Scrub Single Number
curl --request GET \
--url https://www.dncscrub.com/app/main/rpc/scrub \
--header 'loginId: <loginid>'import requests
url = "https://www.dncscrub.com/app/main/rpc/scrub"
headers = {"loginId": "<loginid>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {loginId: '<loginid>'}};
fetch('https://www.dncscrub.com/app/main/rpc/scrub', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.dncscrub.com/app/main/rpc/scrub",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"loginId: <loginid>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.dncscrub.com/app/main/rpc/scrub"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("loginId", "<loginid>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.dncscrub.com/app/main/rpc/scrub")
.header("loginId", "<loginid>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.dncscrub.com/app/main/rpc/scrub")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["loginId"] = '<loginid>'
response = http.request(request)
puts response.read_body{
"version": 8,
"results": [
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": null,
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": false,
"LineType": "AllOther",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
{
"version": 8,
"results": [
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": null,
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 35,
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": -240,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": "10001",
"TZSource": "postalCode",
"IsCallAllowedNonATDS": true,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
Full Scrub
Scrub Single Number
Scrub a single phone number via the API
GET
/
app
/
main
/
rpc
/
scrub
Scrub Single Number
curl --request GET \
--url https://www.dncscrub.com/app/main/rpc/scrub \
--header 'loginId: <loginid>'import requests
url = "https://www.dncscrub.com/app/main/rpc/scrub"
headers = {"loginId": "<loginid>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {loginId: '<loginid>'}};
fetch('https://www.dncscrub.com/app/main/rpc/scrub', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.dncscrub.com/app/main/rpc/scrub",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"loginId: <loginid>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.dncscrub.com/app/main/rpc/scrub"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("loginId", "<loginid>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.dncscrub.com/app/main/rpc/scrub")
.header("loginId", "<loginid>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.dncscrub.com/app/main/rpc/scrub")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["loginId"] = '<loginid>'
response = http.request(request)
puts response.read_body{
"version": 8,
"results": [
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": null,
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": false,
"LineType": "AllOther",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
{
"version": 8,
"results": [
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": null,
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 35,
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": -240,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": "10001",
"TZSource": "postalCode",
"IsCallAllowedNonATDS": true,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
Scrub a single phone number against all configured DNC lists and compliance databases.
There is deliberately no request-level parameter — one postal code applied to a
whole list would silently mis-time every other number. See Unique
Identifiers for the pipe syntax.
Accepted formats: 5-digit US ZIP (ZIP+4 is accepted, e.g.
See Is the call allowed?
for the rules and Compliance for AI Voice
Agents for the AI workflow end to end.
Request
Headers
string
required
Your API Key
Query Parameters
string
required
The 10-digit phone number to scrub. Optionally append a pipe-delimited
identifier (
5039367181|ACCT-1) and/or postal code (5039367181|ACCT-1|10001;
leave the identifier empty to pass only a postal code: 5039367181||10001) —
see Postal Code Time Zonesstring
default:"8"
required
API version. Use
8 (latest). Version 6 adds EBRExpiresOn; version 7
adds WirelessPortDate and VoIPDate; version 8 adds PostalCode, TZSource,
IsCallAllowedNonATDS, IsCallAllowedATDS and IsCallAllowedAI, and returns
JSON as a typed object ({"version": 8, "results": [...]}) instead of an array
of strings — see JSON response
shape.string
default:"json"
Response format:
json or csvstring
Optional. Project ID
string
Optional. Campaign ID
Postal Code Time Zones
By defaultTZCode, UTCOffset, CallingWindow, CallingTimeRestrictions
and DoNotCallToday are derived from the phone number’s area code and prefix.
Mobile numbers keep their area code when their owner moves, so the area code is
not always where the person is. If you know the contact’s postal code, pass it
and those fields are calculated from the postal code’s time zone and state
instead — state calling hours, state holidays and state-of-emergency blocks all
follow the postal code’s state.
The postal code is always passed per number, as the third pipe-delimited field
of phoneList: PHONE|ID|POSTALCODE. Leave the ID empty if you don’t use one:
phoneList=5039367181||10001
10001-1234; only
the first five digits are used) and Canadian postal codes (M5V3L9, or just
the M5V forward sortation area). Case and hyphens are ignored. Do not put
spaces inside a phoneList entry — whitespace separates phone numbers, so
M5V 3L9 must be sent as M5V3L9 (or M5V-3L9).
If the postal code is not recognized, the number is processed exactly as if no
postal code had been passed. Use version=8 to receive TZSource, which tells
you which method was used.
The postal code only affects the time zone and calling-window fields.
ResultCode, Reason, RegionAbbrev, Country, Locale, DNC list matching
and EBR logic are always based on the phone number.One-Field Answer
Withversion=8 the response also includes three yes/no flags so you don’t
have to interpret ResultCode, EBRType, DoNotCallToday and the calling
window yourself. Pick the one that matches how you place calls:
| Flag | You are placing… |
|---|---|
IsCallAllowedNonATDS | a manually dialed, live-agent call |
IsCallAllowedATDS | an autodialed call (live agent on connect) |
IsCallAllowedAI | a call with an AI, artificial or prerecorded voice |
Example Request
curl --location --request GET \
'https://www.dncscrub.com/app/main/rpc/scrub?phoneList=7075276405&version=8&output=json' \
--header 'loginId: YOUR_API_KEY'
const phoneNumber = "7075276405";
const apiUrl = `https://www.dncscrub.com/app/main/rpc/scrub?phoneList=${phoneNumber}&version=8&output=json`;
fetch(apiUrl, {
method: "GET",
headers: {
loginId: "YOUR_API_KEY",
},
})
.then((response) => response.json())
.then((data) => {
const result = data.results[0];
console.log("Phone:", result.Phone);
console.log("Result Code:", result.ResultCode);
console.log("Reason:", result.Reason);
});
// Ensure TLS 1.2
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var phoneNumber = "7075276405";
var url = $"https://www.dncscrub.com/app/main/rpc/scrub?phoneList={phoneNumber}&version=8&output=json";
var response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
{
"version": 8,
"results": [
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": null,
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": false,
"LineType": "AllOther",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
{
"version": 8,
"results": [
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": null,
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 35,
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": -240,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": null,
"VoIPDate": null,
"PostalCode": "10001",
"TZSource": "postalCode",
"IsCallAllowedNonATDS": true,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
}
]
}
Response Fields
string
The phone number that was scrubbed
string
The scrub result code (see Result
Codes)
string | null
Your unique identifier if you passed one (
PHONE|ID), otherwise nullstring
Explanation of why the number is flagged
string
State/region abbreviation (e.g., “CA”)
string
Two-digit country code (e.g., “US”)
string
City or locality
string
Carrier information in format:
ID;TYPE;"Name"string | null
New area code if the number’s area code has been split or overlaid, otherwise
nullinteger
Time zone code (see Timezone
Codes). Derived from the
postal code when one is supplied, otherwise from the area code
string | null
Permitted calling hours in the destination’s local time,
HH:MM-HH:MM, as
three semicolon-separated windows: weekday;Saturday;Sunday (e.g.
8:00-21:00;8:00-21:00;8:00-21:00). null when no window appliesinteger
UTC offset in minutes for the destination, adjusted for DST (e.g.
-240)boolean
true if the number should not be called today (state holiday or state of emergency)integer
Bit field:
1 = it is currently outside the calling window, 2 = an EBR
exemption to the calling window is available, 4 = the destination state
does not specify its own calling window (or you are exempt from it), so the
federal 8 AM–9 PM window appliesstring | null
Type of EBR applied:
S (Sale), I (Inquiry), or P (Permission). null if no EBRboolean
true if wireless or VoIPstring
Line type:
Wireless, VoIP, or AllOtherstring | null
Date the EBR expires,
YYYY-MM-DD (e.g. 2027-02-09), inclusive — the number may be called through the end of that day in the destination’s local time. The earlier of the federal and state expiration dates. null if no EBR. Requires version=6 or higher (versions 6–7 return YYYY-MM-DD 23:59:00 as a string)string | null
Date the number was ported to wireless,
YYYY-MM-DD. null when there is no port record (versions 7 returns 0 or empty). Requires version=7 or higherstring | null
Date the number was identified as VoIP,
YYYY-MM-DD. null if not VoIP. Requires
version=7 or higherstring | null
Normalized postal code used for the time zone calculation (
10001, M5V).
null if none was supplied. Requires version=8 or higherstring
postalCode when the time zone and calling window were derived from the
supplied postal code, otherwise areaCode. Requires version=8 or higherboolean
true if a manually dialed, live-agent marketing call may be placed to this number right now. Combines ResultCode, DoNotCallToday and
the calling window. See Is the call
allowed? for the rules
and for when this flag applies to you. Requires version=8 or higherboolean
Same checks, for calls placed by an autodialer (federal or state
definition). Wireless and VoIP numbers return
false unless a Permission (P)
EBR — express written consent — is on file. Requires version=8 or higherboolean
Same checks, for calls using an artificial, prerecorded or AI-generated
voice.
true only when a Permission (P) EBR is on file and still valid
(EBRType is P and ResultCode is E, O, G or H) — any line type.
Clean numbers without consent return false. See Compliance for AI Voice
Agents. Requires version=8 or higherHandling the Response. Make sure to handle all response codes. The sample below handles just a few
const { results } = await response.json();
const result = results[0];
switch (result.ResultCode) {
case "C":
// Clean - safe to call
console.log("Phone number is clean");
break;
case "D":
// Do Not Call
console.log("Do not call:", result.Reason);
break;
case "W":
// Wireless number detected
console.log("Wireless number detected");
break;
default:
console.log("Result:", result.ResultCode);
}