Scrub with Unique Identifiers
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[
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": "ACCT-12345",
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": "-420",
"DoNotCallToday": "0",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "1",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
Full Scrub
Scrub with Unique Identifiers
Pass a unique identifier with each phone number
GET
/
app
/
main
/
rpc
/
scrub
Scrub with Unique Identifiers
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[
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": "ACCT-12345",
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": "-420",
"DoNotCallToday": "0",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "1",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
Pass a unique identifier (such as Account ID, Record ID, or Member ID) with each phone number and have it returned in the response. This allows you to easily match scrub results back to your records.
The unique identifier will be returned in the
For the full field list see the Output Guide.
How It Works
Append a pipe character (|) followed by your unique identifier to each phone number:
phoneList=5039367181|UniqueID
Reserved field of the response.
An optional third field carries the contact’s postal code, which switches the
time zone and calling-window calculation from the number’s area code to the
postal code (see Postal Code Time
Zones):
phoneList=5039367181|UniqueID|10001
phoneList=5039367181||10001 (no identifier)
Request
Headers
string
required
Your API Key
Query Parameters
string
required
Phone number with identifier in format:
PHONE|ID (e.g.,
5039367181|ACCT-12345), optionally followed by a postal code:
PHONE|ID|POSTALCODE (e.g., 5039367181|ACCT-12345|10001). For multiple
numbers, comma-separate them: 5039367181|ACCT-001,7075276405|ACCT-002string
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:"csv"
Response format:
json or csvstring
Project ID
string
Campaign ID
Example Request
curl --location --request GET \
'https://www.dncscrub.com/app/main/rpc/scrub?phoneList=5039367181|ACCT-12345&version=8&output=json' \
--header 'loginId: YOUR_API_KEY'
const phoneNumber = "5039367181";
const accountId = "ACCT-12345";
const response = await fetch(
`https://www.dncscrub.com/app/main/rpc/scrub?phoneList=${phoneNumber}|${accountId}&version=8&output=json`,
{
method: "GET",
headers: { loginId: "YOUR_API_KEY" },
}
);
const data = await response.json();
console.log("Account ID:", data[0].Reserved); // "ACCT-12345"
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var phoneNumber = "5039367181";
var accountId = "ACCT-12345";
var url = $"https://www.dncscrub.com/app/main/rpc/scrub?phoneList={phoneNumber}|{accountId}&version=8&output=json";
var response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
[
{
"Phone": "5039367181",
"ResultCode": "W",
"Reserved": "ACCT-12345",
"Reason": ";;;W",
"RegionAbbrev": "OR",
"Country": "US",
"Locale": "Portland",
"CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
"NewReassignedAreaCode": "",
"TZCode": "4",
"CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
"UTCOffset": "-420",
"DoNotCallToday": "0",
"CallingTimeRestrictions": "4",
"EBRType": "",
"IsWirelessOrVoIP": "1",
"LineType": "Wireless",
"EBRExpiresOn": "",
"WirelessPortDate": "0",
"VoIPDate": "",
"PostalCode": "",
"TZSource": "areaCode",
"IsCallAllowedNonATDS": "1",
"IsCallAllowedATDS": "0",
"IsCallAllowedAI": "0"
}
]
The
Reserved field contains your unique identifier "ACCT-12345".Response Fields
string
The phone number that was scrubbed
string
The scrub result code (see Result
Codes)
string
Your unique identifier passed with the phone number
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
1 if wireless/VoIP, 0 otherwisestring
Line type:
Wireless, VoIP, or AllOtherstring
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 higherMultiple Numbers with Identifiers
Comma-separate multiple phone numbers with their identifiers:phoneList=5039367181|ACCT-001,7075276405|ACCT-002,7072842774|ACCT-003
Example
const records = [
{ phone: "5039367181", accountId: "ACCT-001" },
{ phone: "7075276405", accountId: "ACCT-002" },
{ phone: "7072842774", accountId: "ACCT-003" },
];
const phoneList = records.map((r) => `${r.phone}|${r.accountId}`).join(",");
// phoneList = "5039367181|ACCT-001,7075276405|ACCT-002,7072842774|ACCT-003"
const response = await fetch(
`https://www.dncscrub.com/app/main/rpc/scrub?phoneList=${encodeURIComponent(
phoneList
)}&version=8&output=json`,
{
method: "GET",
headers: { loginId: "YOUR_API_KEY" },
}
);
const results = await response.json();
// Match results back to original records
results.forEach((result) => {
console.log(`Account ${result.Reserved}: ${result.ResultCode}`);
});
Use Cases
CRM Integration
Pass your CRM Record ID to update records directly after scrubbing
Batch Processing
Track which phone number belongs to which customer in large batches
Audit Trail
Include transaction IDs for compliance logging
Database Updates
Pass primary keys to enable efficient database updates
Best Practices
The unique identifier should not contain commas (
,) or pipe characters (|)
as these are used as delimiters. The pipe fields are positional: the second
is always the identifier and the third is always the postal code, so use
PHONE||POSTALCODE to pass a postal code without an identifier.- Keep identifiers reasonably short
- Use URL-safe characters
- Consider encoding special characters if needed