npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vicistack/vicidial-dnc-management

v1.0.0

Published

VICIdial DNC Compliance: The Gaps That Generate Six-Figure Fines — ViciStack call center engineering guide

Readme

VICIdial DNC Compliance: The Gaps That Generate Six-Figure Fines

Everything you need to know about DNC list management in VICIdial — federal DNC scrubbing, state-level lists, internal DNC tables, real-time hopper filtering, audit trails, and the SQL queries that prove you're compliant when the lawyers come knocking. --- Do Not Call compliance is not optional. It is not a "best practice." It is the single most expensive thing you can get wrong in an outbound VICIdial operation. A single DNC violation under the TCPA carries $500 in damages. Willful violations jump to $1,500 per call. And plaintiff attorneys don't file lawsuits over one call — they file class actions covering thousands. We've seen operations hit with seven-figure settlements because their DNC scrubbing process had a gap they didn't know about. A list that wasn't re-scrubbed within the 31-day window. A state DNC list they didn't know existed. An internal DNC table that wasn't being checked during hopper loading because someone toggled the wrong setting during a campaign clone. The DNC landscape in 2026 involves three overlapping layers of compliance: the federal National Do Not Call Registry managed by the FTC, state-level DNC registries maintained by individual states, and your own internal DNC lists built from consumer opt-out requests. VICIdial handles the internal layer natively. The federal and state layers require external scrubbing processes that feed into VICIdial's filtering system. This guide covers all three layers — the import processes, the VICIdial configuration, the SQL queries for verification, and the audit trail documentation that constitutes your legal defense if you're ever challenged. For the DNC glossary definition, see /glossary/dnc/. For broader TCPA compliance configuration, see our VICIdial TCPA Compliance Checklist. --- ## Federal DNC: The National Do Not Call Registry The FTC's National Do Not Call Registry is the baseline. Every outbound operation calling U.S. consumers must scrub against it. No exceptions (with narrow carve-outs for existing business relationships and certain nonprofit calls that almost certainly don't apply to your VICIdial campaigns). ### Registering for Access Before you can download the registry data, you must register your organization with the FTC: 1. Go to telemarketing.donotcall.gov 2. Create an organization account. You'll need your company's legal name, physical address, EIN, and the name of a responsible individual. 3. Pay the access fee. As of 2026, fees are based on the number of area codes you download. A single area code costs $75/year. All area codes (the full national file) costs approximately $21,525/year. Most operations download only the area codes they actively dial, which brings the cost down significantly. 4. Select your area codes. Choose the area codes that correspond to the states and regions you're calling into. If you're unsure, pull your active area codes from VICIdial: sql SELECT DISTINCT SUBSTRING(phone_number, 1, 3) as area_code, COUNT(*) as lead_count FROM vicidial_list WHERE list_id IN (SELECT list_id FROM vicidial_lists WHERE active = 'Y') GROUP BY area_code ORDER BY lead_count DESC; 5. Download the data. The FTC provides the DNC data as flat text files — one phone number per line, organized by area code. Files are updated daily, but you're required to download and scrub at minimum every 31 days. ### Import Process VICIdial does not have a native "import federal DNC" button. The standard workflow is: Option A: Pre-scrub before loading leads into VICIdial This is the most common approach. Before importing any new lead list into VICIdial, you scrub it against the federal DNC file externally. The scrubbed list (with DNC numbers removed) is then loaded into VICIdial as usual. bash #!/bin/bash # Federal DNC scrub script # Removes numbers found in federal DNC files before VICIdial import DNC_DIR="/opt/dnc/federal" LEAD_FILE="$1" OUTPUT_FILE="${LEAD_FILE%.csv}_scrubbed.csv" REJECT_FILE="${LEAD_FILE%.csv}_dnc_rejected.csv" # Combine all area code DNC files into one sorted lookup file cat ${DNC_DIR}/*.txt | sort -u > /tmp/federal_dnc_combined.txt # Extract phone numbers from lead file (assumes phone is column 1) # Compare against DNC list, output clean leads and rejected leads awk -F',' 'NR==FNR{dnc[$1]; next} { phone=$1; gsub(/[^0-9]/, "", phone); if (phone in dnc) { print $0 >> "'${REJECT_FILE}'" } else { print $0 } }' /tmp/federal_dnc_combined.txt "$LEAD_FILE" > "$OUTPUT_FILE" TOTAL=$(wc -l < "$LEAD_FILE") CLEAN=$(wc -l < "$OUTPUT_FILE") REJECTED=$((TOTAL - CLEAN)) echo "Scrub complete: $TOTAL total, $CLEAN clean, $REJECTED DNC matches" echo "$(date) | $LEAD_FILE | Total: $TOTAL | Clean: $CLEAN | DNC: $REJECTED" \ >> /var/log/vicidial/dnc_scrub_audit.log Option B: Load the federal DNC data into VICIdial's internal DNC table This approach imports the entire federal DNC registry into VICIdial's vicidial_dnc table, allowing VICIdial's native DNC checking to handle federal DNC filtering at hopper-loading time. sql -- Load federal DNC numbers into VICIdial's internal DNC table -- WARNING: The federal DNC registry contains 240+ million numbers. -- This will significantly increase the size of the vicidial_dnc table. -- Test on a staging environment first and monitor MySQL performance. LOAD DATA LOCAL INFILE '/opt/dnc/federal/combined_dnc.txt' INTO TABLE vicidial_dnc FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' (phone_number); Before taking this approach, check your current DNC table size and MySQL memory allocation: sql SELECT COUNT(*) as current_dnc_count, ROUND(data_length / 1024 / 1024, 2) as data_mb, ROUND(index_length / 1024 / 1024, 2) as index_mb FROM information_schema.tables WHERE table_name = 'vicidial_dnc'; If you're loading 240+ million numbers into this table, your innodb_buffer_pool_size needs to accommodate the additional index size. For MySQL performance tuning specific to VICIdial, check our MySQL optimization guide. Option C: Use a third-party DNC scrubbing service Services like DNC.com, Gryphon Networks, Contact Center Compliance (DCC), and Tele-Data Solutions offer API-based DNC scrubbing. You upload your list (or send numbers via API), they scrub against federal, state, and litigator lists, and return the clean file. This is the easiest approach but adds per-number cost. Most charge $0.002-$0.005 per number per scrub. ### Scrub Frequency: The 31-Day Rule The TSR (Telemarketing Sales Rule, enforced by the FTC) requires that you scrub your calling lists against the National DNC Registry no less frequently than every 31 days. Not 32 days. Not "monthly." Every 31 days, counted from the date of your last scrub. This means every active list in your VICIdial system needs a scrub date tracked somewhere. Here's a practical approach: sql -- Create a DNC scrub tracking table CREATE TABLE IF NOT EXISTS vicistack_dnc_scrub_log ( scrub_id INT AUTO_INCREMENT PRIMARY KEY, list_id BIGINT NOT NULL, scrub_type ENUM('federal', 'state', 'litigator') NOT NULL, scrub_date DATETIME NOT NULL, total_numbers INT NOT NULL, numbers_removed INT NOT NULL, scrub_source VARCHAR(100), performed_by VARCHAR(50), notes TEXT, INDEX idx_list_date (list_id, scrub_date) ); -- Check which lists are overdue for federal DNC scrub SELECT vl.list_id, vl.list_name, vl.list_lastcalldate, ds.last_scrub, DATEDIFF(NOW(), ds.last_scrub) as days_since_scrub, CASE WHEN DATEDIFF(NOW(), ds.last_scrub) > 31 THEN 'OVERDUE' WHEN DATEDIFF(NOW(), ds.last_scrub) > 25 THEN 'SCRUB SOON' ELSE 'CURRENT' END as scrub_status FROM vicidial_lists vl LEFT JOIN ( SELECT list_id, MAX(scrub_date) as last_scrub FROM vicistack_dnc_scrub_log WHERE scrub_type = 'federal' GROUP BY list_id ) ds ON vl.list_id = ds.list_id WHERE vl.active = 'Y' ORDER BY days_since_scrub DESC; Run this query weekly. Any list showing "OVERDUE" must be either re-scrubbed or deactivated immediately. Dialing from a list whose federal DNC scrub is older than 31 days is a per-call violation. --- ## State DNC Lists: The Layer Most Operations Miss The federal DNC registry gets all the attention. State DNC lists are what actually trip people up. Over a dozen states maintain their own Do Not Call registries — separate from and in addition to the federal list. A number can be on a state DNC list but not on the federal list. If you're calling into that state and you haven't scrubbed against the state list, you're in violation of state law. ### States With Their Own DNC Registries Here's the current landscape as of 2026. Each state's list must be obtained separately, and each has its own registration process, fee structure, and update schedule: | State | Registry | Annual Fee (approx.) | Update Frequency | Notes | |---|---|---|---|---| | Colorado | Colorado No Call List | $200-$400 | Quarterly | Managed by Attorney General | | Florida | Florida Do Not Call List | $100 | Quarterly | Must scrub for FTSA compliance | | Indiana | Indiana Do Not Call List | $75-$300 | Quarterly | Managed by Attorney General | | Louisiana | Louisiana No Call List | Free-$200 | Quarterly | Managed by PSC | | Massachusetts | Massachusetts Do Not Call Registry | $100-$300 | Quarterly | Managed by Attorney General | | Mississippi | Mississippi No Call List | Free | Quarterly | Managed by PSC | | Missouri | Missouri No Call List | $200 | Quarterly | Managed by Attorney General | | New York | New York Do Not Call Registry | $200-$500 | Monthly | Managed by DPS | | Pennsylvania | Pennsylvania Do Not Call List | $100-$400 | Quarterly | Managed by Attorney General | | Tennessee | Tennessee Do Not Call List | Free-$100 | Quarterly | Managed by TRA | | Texas | Texas No Call List | $100-$300 | Quarterly | Managed by PUC | | Wyoming | Wyoming No Call List | Free | Quarterly | Managed by PSC | Important: This list changes. States add and remove DNC registry programs. Check each state's Attorney General or Public Service Commission website annually to verify current requirements. Some states that previously maintained lists have sunset them in favor of relying solely on the federal registry. ### State DNC Import Process The process for each state follows the same general pattern: 1. Register with the state agency. Each state has its own portal. Some allow online registration; others require paper forms. 2. Pay the annual fee (if applicable). 3. Download the data. Format varies by state — some provide CSV, some provide fixed-width text files, some provide pipe-delimited files. 4. Normalize the data. Strip formatting, ensure 10-digit phone numbers, remove duplicates. 5. Scrub your lists against the state data before loading into VICIdial (or load the state DNC numbers into a VICIdial DNC list). Here's a script that handles normalization and import for state DNC files: bash #!/bin/bash # State DNC import into VICIdial campaign-level DNC list # Usage: ./import_state_dnc.sh <state_file> <dnc_campaign_id> STATE_FILE="$1" DNC_CAMPAIGN="$2" MYSQL_USER="cron" MYSQL_PASS="your_password" MYSQL_DB="asterisk" # Normalize phone numbers: strip everything except digits, take last 10 awk '{ gsub(/[^0-9]/, ""); if (length($0) == 11 && substr($0,1,1) == "1") $0 = substr($0, 2); if (length($0) == 10) print $0; }' "$STATE_FILE" | sort -u > /tmp/state_dnc_normalized.txt COUNT=$(wc -l < /tmp/state_dnc_normalized.txt) echo "Normalized $COUNT unique phone numbers from $STATE_FILE" # Import into VICIdial campaign DNC table while IFS= read -r phone; do mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" "$MYSQL_DB" -e \ "INSERT IGNORE INTO vicidial_campaign_dnc (phone_number, campaign_id) VALUES ('$phone', '$DNC_CAMPAIGN');" done < /tmp/state_dnc_normalized.txt echo "State DNC import complete: $COUNT numbers into campaign DNC $DNC_CAMPAIGN" echo "$(date) | State DNC | File: $STATE_FILE | Campaign: $DNC_CAMPAIGN | Count: $COUNT" \ >> /var/log/vicidial/dnc_scrub_audit.log For large state files (Florida and Texas can have millions of entries), batch the MySQL inserts instead of one-at-a-time: sql -- Bulk load state DNC into campaign DNC table LOAD DATA LOCAL INFILE '/tmp/state_dnc_normalized.txt' IGNORE INTO TABLE vicidial_campaign_dnc FIELDS TERMINATED BY '\n' (phone_number) SET campaign_id = 'STATEDNCFL'; Then assign that DNC campaign ID to any campaigns calling into that state. ### Managing Multiple State DNC Lists If you're calling into multiple states with their own DNC registries, you need a system. Here's the approach that works: Option 1: Merge all state DNC numbers into the system-wide internal DNC table. Simple, effective, but it blocks those numbers across all campaigns — even campaigns where the state restriction doesn't apply (e.g., a number on Indiana's DNC list being blocked from a campaign that only calls Florida). Option 2: Create state-specific campaign DNC lists. More granular. Create DNC list entries tagged by state, and assign the relevant state DNC lists to campaigns based on their target geography. This is more work to maintain but prevents over-blocking. Option 3: Pre-scrub externally by state. Before loading leads into VICIdial, scrub against all applicable state DNC lists for the states represented in the lead file. Only clean


Read the full article

About

Built by ViciStack — enterprise VoIP and call center infrastructure.

License

MIT