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[
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": "",
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "2019-03-14",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
},
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": "",
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "0",
"LineType": "AllOther",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
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[
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": "",
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "2019-03-14",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
},
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": "",
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "0",
"LineType": "AllOther",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
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}
(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();
}
[
{
"Phone": "5039367187",
"ResultCode": "D",
"Reserved": "",
"Reason": "Litigator",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "2019-03-14",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
},
{
"Phone": "7075276405",
"ResultCode": "D",
"Reserved": "",
"Reason": "National (USA) 2003-06-01;;;",
"RegionAbbrev": "CA",
"Country": "US",
"Locale": "Santa Rosa",
"CarrierInfo": "9740;RBOC;\"AT&T California:AT&T California\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "",
"UTCOffset": "-420",
"DoNotCallToday": "",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "0",
"LineType": "AllOther",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "0",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
Response Fields
string
The phone number that was scrubbed
string
The scrub result code (see Result
Codes)
string
Reserved field (used for unique identifiers)
string
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"string
Timezone code
string
UTC offset in minutes
string
Type of EBR applied:
S (Sale), I (Inquiry), or P (Permission). Empty if
no EBRstring
1 if wireless/VoIP, 0 otherwisestring
Line type:
Wireless, VoIP, or AllOtherstring
When the EBR expires, format
YYYY-MM-DD HH:MM:SS (e.g. 2027-02-09 23:59:00). The earlier of the federal and state expiration dates. Empty if no
EBR. Requires version=6 or higher. The time portion is always 23:59:00
(end of day) and no timezone is included — treat the value as a date and
compare against your local calendar date rather than parsing it as a UTC
timestampstring
Date the number was ported to wireless.
0 or empty when there is no port
record. Requires version=7 or higherstring
Date the number was identified as VoIP. Empty if not VoIP. Requires
version=7 or higherstring
Normalized postal code used for the time zone calculation (
10001, M5V).
Empty 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 higherstring
1 if a manually dialed, live-agent marketing call may be placed to this
number right now; 0 otherwise. 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 higherstring
Same checks, for calls placed by an autodialer (federal or state
definition). Wireless and VoIP numbers return
0 unless a Permission (P)
EBR — express written consent — is on file. Requires version=8 or higherstring
Same checks, for calls using an artificial, prerecorded or AI-generated
voice.
1 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 0. 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 === "1");
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.