Scrub Multiple Numbers
curl --request POST \
--url https://www.dncscrub.com/app/main/rpc/scrub \
--header 'Content-Type: application/json' \
--header 'loginId: <loginid>' \
--data '
{
"phoneList": "<string>",
"version": "<string>",
"output": "<string>",
"projId": "<string>",
"campaignId": "<string>"
}
'import requests
url = "https://www.dncscrub.com/app/main/rpc/scrub"
payload = {
"phoneList": "<string>",
"version": "<string>",
"output": "<string>",
"projId": "<string>",
"campaignId": "<string>"
}
headers = {
"loginId": "<loginid>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {loginId: '<loginid>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phoneList: '<string>',
version: '<string>',
output: '<string>',
projId: '<string>',
campaignId: '<string>'
})
};
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 => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneList' => '<string>',
'version' => '<string>',
'output' => '<string>',
'projId' => '<string>',
'campaignId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.dncscrub.com/app/main/rpc/scrub"
payload := strings.NewReader("{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("loginId", "<loginid>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.dncscrub.com/app/main/rpc/scrub")
.header("loginId", "<loginid>")
.header("Content-Type", "application/json")
.body("{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}")
.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::Post.new(url)
request["loginId"] = '<loginid>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"version": 8,
"results": [
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": null,
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": "2019-03-14",
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
},
{
"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
}
]
}
Full Scrub
Scrub Multiple Numbers
Scrub multiple phone numbers in a single API call
POST
/
app
/
main
/
rpc
/
scrub
Scrub Multiple Numbers
curl --request POST \
--url https://www.dncscrub.com/app/main/rpc/scrub \
--header 'Content-Type: application/json' \
--header 'loginId: <loginid>' \
--data '
{
"phoneList": "<string>",
"version": "<string>",
"output": "<string>",
"projId": "<string>",
"campaignId": "<string>"
}
'import requests
url = "https://www.dncscrub.com/app/main/rpc/scrub"
payload = {
"phoneList": "<string>",
"version": "<string>",
"output": "<string>",
"projId": "<string>",
"campaignId": "<string>"
}
headers = {
"loginId": "<loginid>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {loginId: '<loginid>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phoneList: '<string>',
version: '<string>',
output: '<string>',
projId: '<string>',
campaignId: '<string>'
})
};
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 => "POST",
CURLOPT_POSTFIELDS => json_encode([
'phoneList' => '<string>',
'version' => '<string>',
'output' => '<string>',
'projId' => '<string>',
'campaignId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.dncscrub.com/app/main/rpc/scrub"
payload := strings.NewReader("{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("loginId", "<loginid>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.dncscrub.com/app/main/rpc/scrub")
.header("loginId", "<loginid>")
.header("Content-Type", "application/json")
.body("{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}")
.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::Post.new(url)
request["loginId"] = '<loginid>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"phoneList\": \"<string>\",\n \"version\": \"<string>\",\n \"output\": \"<string>\",\n \"projId\": \"<string>\",\n \"campaignId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"version": 8,
"results": [
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": null,
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": "2019-03-14",
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
},
{
"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
}
]
}
Submit multiple phone numbers in a single request for efficient batch processing.
To add or refresh EBR records in the same call as a scrub, use
Scrub + Add EBR.
If you scrub more than 10 phone numbers, use HTTP POST instead of HTTP GET. If
you do not know your batch size, safest option is always use HTTP POST. The
maximum number of records that can be scrubbed per requests is 10,000. If you
have larger batches, consider using SFTP.
Request
Headers
string
required
Your API Key
Request Body
string
required
Comma-separated list of 10-digit phone numbers (e.g.,
5039367187,7075276405,7072842774). To include a system identifier with each
result, append |{id} to the phone number (e.g.,
5039367187|abc-10232,7075276405|abc-10233,7072842774|abc-10234). To have
the time zone and calling window calculated from the contact’s postal code
instead of the area code, append it as a third field, |{id}|{postalCode};
the identifier may be empty, ||{postalCode} (e.g.,
5039367187|abc-10232|10001,7075276405||97205). See Postal Code Time
Zones.string
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.string
default:"json"
Response format:
json or csvstring
Optional. Project ID
string
Optional. Campaign ID
Example Request
curl --location --request POST \
'https://www.dncscrub.com/app/main/rpc/scrub' \
--header 'loginId: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"phoneList": "5039367187,7075276405,7072842774",
"version": "8",
"output": "json"
}'
const phoneNumbers = ["5039367187", "7075276405", "7072842774"];
const phoneList = phoneNumbers.join(",");
const response = await fetch("https://www.dncscrub.com/app/main/rpc/scrub", {
method: "POST",
headers: {
loginId: "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
phoneList: phoneList,
version: "8",
output: "json",
}),
});
const { results } = await response.json();
results.forEach((result) => {
console.log(`${result.Phone}: ${result.ResultCode}`);
});
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var requestBody = new
{
phoneList = "5039367187,7075276405,7072842774",
version = "8",
output = "json"
};
var json = System.Text.Json.JsonSerializer.Serialize(requestBody);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://www.dncscrub.com/app/main/rpc/scrub",
content
);
var responseString = await response.Content.ReadAsStringAsync();
}
{
"version": 8,
"results": [
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": null,
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": null,
"TZCode": 4,
"CallingWindow": null,
"UTCOffset": -420,
"DoNotCallToday": false,
"CallingTimeRestrictions": 4,
"EBRType": null,
"IsWirelessOrVoIP": true,
"LineType": "Wireless",
"EBRExpiresOn": null,
"WirelessPortDate": "2019-03-14",
"VoIPDate": null,
"PostalCode": null,
"TZSource": "areaCode",
"IsCallAllowedNonATDS": false,
"IsCallAllowedATDS": false,
"IsCallAllowedAI": false
},
{
"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
}
]
}
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
Country code (e.g., “US”)
string
City or locality
string
Carrier information in format:
ID;TYPE;"Name"integer
Timezone code
integer
UTC offset in minutes for the destination, adjusted for DST (e.g.
-240)string | 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. See Postal Code Time
Zones. 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 higherProcessing Multiple Results
const { results } = await response.json();
const clean = results.filter((r) => r.ResultCode === "C");
const doNotCall = results.filter((r) => r.ResultCode === "D");
const wireless = results.filter((r) => r.IsWirelessOrVoIP);
console.log(`Clean numbers: ${clean.length}`);
console.log(`Do Not Call: ${doNotCall.length}`);
console.log(`Wireless: ${wireless.length}`);
Using HTTP POST for Large Batches
For more than 10 phone numbers, use HTTP POST with a JSON body:using (var client = new HttpClient())
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var requestBody = new
{
phoneList = "5039367187,7075276405,...",
version = "8",
output = "csv" // Recommended for large batches
};
var json = System.Text.Json.JsonSerializer.Serialize(requestBody);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://www.dncscrub.com/app/main/rpc/scrub",
content
);
var responseString = await response.Content.ReadAsStringAsync();
}
Best Practices
Batch Size
Batch Size
While the API can handle large batches, consider breaking very large lists
into batches of 1,000-5,000 numbers for optimal performance.
Output Format
Output Format
Use
output=csv for large batches. CSV parsing is more efficient for
high-volume processing.Error Handling
Error Handling
Operations are atomic. If one phone number is invalid, the entire batch
fails. Validate phone numbers before sending.