Get Started
Back to Blog
Two people with tablets walking past server racks

Integrating DNC Scrubbing Into Your Dialer via API

By Carrier Fence · October 29, 2026 (updated) · 5 min read

Uploading a CSV before every campaign works until it doesn't: until you're loading leads all day, pulling them from web forms in real time, or dialing at a volume where a manual step becomes a bottleneck and a source of mistakes. At that point you want Do Not Call scrubbing built into your systems through an API, so no number reaches the dialer without being checked.

This guide shows the integration patterns that work for dialers and CRMs, with working examples against the Carrier Fence API.

1,000Numbers you can check in a single API request
2.5 coinsCost per number for a combined DNC and honeypot check
$0Charge for invalid numbers and failed requests

Where API scrubbing fits

There are two common patterns, and most teams end up using both:

PatternWhen to use itHow it works
Real-time checkLeads arrive one by one from forms, ads or partnersYour CRM checks each number the moment the lead is created, and flags or suppresses it before an agent sees it
Batch pre-dial scrubYou load lists into the dialer for a campaignA scheduled job sends the list in chunks of up to 1,000, then loads only the clean numbers

Either way, the rule is the same: the dialer should never hold a number that hasn't been scrubbed in the last 31 days. See how often the DNC registry updates.

Step 1: Get an API key

Create a key under Account → API Keys after you sign up. The key is shown once and stored only as a hash, so save it in your secrets manager or environment variables, never in front-end code. Send it as a bearer token:

Authorization: Bearer cf_live_xxxxxxxxxxxxxxxxxxxxxxxx

Step 2: Check numbers

Send POST /api/v1/scrub with up to 1,000 numbers and the checks you want (dnc, honeypot or both). Numbers can be in any common format, with dashes, spaces, brackets or a leading 1.

curl -X POST https://carrierfence.com/api/v1/scrub \
  -H "Authorization: Bearer $CF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"numbers": ["2125551234", "(415) 555-9876"], "checks": ["dnc", "honeypot"]}'

Each result tells you whether the number is valid and whether it's on DNC data, a honeypot or a known litigator. It also includes free extras: the number's original carrier and line type (mobile, landline, VoIP or pager), and a callTime object that says whether a sales call is allowed right now in that number's local time.

{ "number": "4155559876", "valid": true, "dnc": false, "honeypot": false, "litigator": false,
  "callTime": { "status": "early", "state": "CA", "nextAllowedLocal": "Tue, Oct 6, 8:00 AM PDT" },
  "carrier": "T-Mobile USA", "lineType": "Mobile" }

Step 3: Act on the results

A simple suppression rule covers most teams:

A batch example in Node.js

This script splits a list into chunks of 1,000, removes duplicates first (duplicates within a request are charged), and keeps only the numbers that are safe to dial.

const KEY = process.env.CF_API_KEY;

async function scrub(numbers) {
  const unique = [...new Set(numbers)];
  const clean = [];
  for (let i = 0; i < unique.length; i += 1000) {
    const res = await fetch("https://carrierfence.com/api/v1/scrub", {
      method: "POST",
      headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify({ numbers: unique.slice(i, i + 1000), checks: ["dnc", "honeypot"] }),
    });
    if (res.status === 402) throw new Error("Out of coins: top up before dialing");
    if (!res.ok) throw new Error(`Scrub failed: ${res.status}`);
    const data = await res.json();
    for (const r of data.results) {
      if (r.valid && !r.dnc && !r.honeypot && !r.litigator) clean.push(r.number);
    }
  }
  return clean;
}

A real-time example in Python

For a CRM webhook that fires when a new lead is created:

import os, requests

def is_safe_to_call(phone):
    r = requests.post(
        "https://carrierfence.com/api/v1/scrub",
        headers={"Authorization": f"Bearer {os.environ['CF_API_KEY']}"},
        json={"numbers": [phone], "checks": ["dnc", "honeypot"]},
        timeout=30,
    )
    r.raise_for_status()
    res = r.json()["results"][0]
    return res["valid"] and not (res["dnc"] or res["honeypot"] or res["litigator"])

Handling errors

StatusErrorWhat to do
400invalid_requestThe numbers array is missing or empty, or no valid check was requested
400too_many_numbersSplit the request into chunks of 1,000 or fewer
401unauthorizedThe key is missing, mistyped or revoked; create a new one
402insufficient_balanceTop up coins; the response says how many more you need

Nothing is charged when a request fails, because the charge and the lookup happen in one transaction. If a request times out, retry it; don't skip the check. If the scrub can't run, the number shouldn't be dialed.

You can check your balance for free with GET /api/v1/balance, which is useful for an alert before a nightly batch runs.

Integration mistakes to avoid

What it costs

The API uses the same coin balance as the web uploader. A DNC check is 1 coin, a honeypot check is 1.5 coins, and invalid numbers are free. On the $25 Basic pack, that's $0.00025 per DNC check, about $25 for 100,000 numbers. There's no monthly fee, so a nightly batch and a trickle of real-time checks cost exactly what they use. See what DNC scrubbing should cost.

Frequently asked questions

How many numbers can I check per API request?

Up to 1,000. For larger lists, split them into chunks of 1,000 and send them one after another.

Can I check a single number in real time?

Yes. Send one number in the numbers array. This works well in a CRM webhook that checks each new lead as it arrives.

Am I charged for invalid numbers or failed requests?

No. Numbers that aren't valid 10-digit US numbers come back with valid: false and aren't charged, and a failed request charges nothing.

Does the API tell me if it's a legal time to call?

Yes. Every result includes a free callTime check covering the federal 8 AM to 9 PM window, stricter state hours, and Sunday and holiday bans, along with the next allowed time if it's too early or too late.

Where is the full API reference?

On the API documentation page, which lists every field, error and example.

Get an API key free: new accounts start with 500 coins to test the integration.

This article is general information, not legal advice.