Documentation Index
Fetch the complete documentation index at: https://docs.dncscrub.com/llms.txt
Use this file to discover all available pages before exploring further.
C# Code Examples
Production-ready C# examples for integrating with DNCScrub APIs.
Prerequisites
- .NET 6 or later
- No third-party packages required — all examples use built-in
System.Text.Json and System.Net.Http.Json
These examples use top-level statements, available in C# 9+ / .NET 6+.
Wrap the code in a Main method if you’re targeting an older project style.
Scrub API — GET
Best for quick lookups of up to 50 phone numbers.
using System.Net.Http.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var phoneNumbers = "5039367187,7075276405";
var url = $"https://www.dncscrub.com/app/main/rpc/scrub?phoneList={phoneNumbers}&version=5&output=json";
var results = await client.GetFromJsonAsync<ScrubResult[]>(url);
foreach (var result in results!)
{
var callable = result.ResultCode switch
{
"C" or "E" or "O" or "X" => true, // Clean, EBR, or exemption
"W" or "G" or "H" or "Y" => true, // Wireless/VoIP — OK but may need TCPA consent
"D" or "P" or "B" or "I" or "M" => false, // DNC, blocked, or invalid
"L" or "F" or "V" => false, // Wireless-prohibited state
_ => false
};
Console.WriteLine($"{result.Phone}: {result.ResultCode} — {(callable ? "Callable" : "Do Not Call")} ({result.Locale}, {result.RegionAbbrev})");
}
record ScrubResult(
string Phone,
string ResultCode,
string Reason,
string RegionAbbrev,
string Country,
string Locale,
string LineType,
string IsWirelessOrVoIP,
string CallingWindow,
string UTCOffset
);
See the Output Guide for a full reference of result codes and response fields.
Scrub API — POST
Use POST for batches larger than 50 phone numbers.
using System.Net.Http.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var formData = new Dictionary<string, string>
{
["phoneList"] = "5039367187,7075276405,7072842774",
["version"] = "5",
["output"] = "json"
};
var response = await client.PostAsync(
"https://www.dncscrub.com/app/main/rpc/scrub",
new FormUrlEncodedContent(formData)
);
response.EnsureSuccessStatusCode();
var results = await response.Content.ReadFromJsonAsync<ScrubResult[]>();
foreach (var result in results!)
{
Console.WriteLine($"{result.Phone}: {result.ResultCode} — {result.LineType} — {result.Locale}, {result.RegionAbbrev}");
}
record ScrubResult(
string Phone,
string ResultCode,
string Reason,
string RegionAbbrev,
string Country,
string Locale,
string LineType,
string IsWirelessOrVoIP,
string CallingWindow,
string UTCOffset
);
TCPA Authority — Reassigned Number Check
Check whether a phone number has been reassigned to a new owner since consent was given. This uses carrier-level data for high accuracy.
using System.Net.Http.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var phoneNumber = "7075276405";
var consentDate = "20210209"; // YYYYMMDD format
var url = $"https://dataapi.dncscrub.com/v1.5/Data/TCPAAuthority?phoneNumber={phoneNumber}&date={consentDate}";
var result = await client.GetFromJsonAsync<TcpaAuthorityResult>(url);
var status = result!.IsReassigned switch
{
true => "REASSIGNED — Do not call (consent no longer valid)",
false => "Not reassigned — Safe to call",
null => "Unable to determine — Insufficient data"
};
Console.WriteLine($"{result.PhoneNumber}: {status}");
Console.WriteLine($" Carrier: {result.Carrier}");
Console.WriteLine($" Line type: {result.LineType}");
Console.WriteLine($" Location: {result.Locale}, {result.Region}");
record TcpaAuthorityResult(
string PhoneNumber,
bool? IsReassigned,
bool IsValid,
string LineType,
string Carrier,
string Locale,
string Region,
string Country,
string TZ,
string UTCOffset
);
Litigator Check
Check whether phone numbers belong to known TCPA litigators.
using System.Net.Http.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
var url = "https://dataapi.dncscrub.com/v1.5/Scrub/litigator?phoneList=5039367187,7075276405";
var results = await client.GetFromJsonAsync<LitigatorResult[]>(url);
foreach (var result in results!)
{
if (result.IsLitigator)
Console.WriteLine($"{result.Phone}: LITIGATOR — Do not call");
else
Console.WriteLine($"{result.Phone}: Not a known litigator");
}
record LitigatorResult(long Phone, bool IsLitigator);
Internal DNC — Add / Remove
Add phone numbers to your organization’s private Internal Do Not Call list (also called Project DNC). Numbers on this list are automatically blocked during scrubs.
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");
// Add a number to your Internal DNC list
var response = await client.GetAsync(
"https://www.dncscrub.com/app/main/rpc/pdnc?phoneList=5039367187&actionType=add"
);
if (response.IsSuccessStatusCode)
Console.WriteLine("Number added to Internal DNC");
else
Console.WriteLine($"Failed: {response.StatusCode}");
// Remove a number from your Internal DNC list
await client.GetAsync(
"https://www.dncscrub.com/app/main/rpc/pdnc?phoneList=5039367187&actionType=remove"
);
Production Client with Error Handling
A reusable client class suitable for production use. Handles authentication errors, rate limiting, timeouts, and proper resource cleanup.
using System.Net;
using System.Net.Http.Json;
class DncScrubClient : IDisposable
{
private readonly HttpClient _http;
public DncScrubClient(string apiKey)
{
_http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
_http.DefaultRequestHeaders.Add("loginId", apiKey);
}
public async Task<ScrubResult[]> ScrubAsync(params string[] phoneNumbers)
{
var phoneList = string.Join(",", phoneNumbers);
var url = $"https://www.dncscrub.com/app/main/rpc/scrub?phoneList={phoneList}&version=5&output=json";
var response = await _http.GetAsync(url);
if (response.StatusCode == HttpStatusCode.Unauthorized)
throw new InvalidOperationException("Invalid API key.");
if ((int)response.StatusCode == 429)
throw new InvalidOperationException("Rate limit exceeded. Slow down requests.");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ScrubResult[]>() ?? [];
}
public async Task<TcpaAuthorityResult?> CheckReassignedAsync(string phoneNumber, string consentDate)
{
var url = $"https://dataapi.dncscrub.com/v1.5/Data/TCPAAuthority?phoneNumber={phoneNumber}&date={consentDate}";
return await _http.GetFromJsonAsync<TcpaAuthorityResult>(url);
}
public async Task<LitigatorResult[]> CheckLitigatorsAsync(params string[] phoneNumbers)
{
var phoneList = string.Join(",", phoneNumbers);
var url = $"https://dataapi.dncscrub.com/v1.5/Scrub/litigator?phoneList={phoneList}";
return await _http.GetFromJsonAsync<LitigatorResult[]>(url) ?? [];
}
public void Dispose() => _http.Dispose();
}
record ScrubResult(
string Phone, string ResultCode, string Reason,
string RegionAbbrev, string Country, string Locale,
string LineType, string IsWirelessOrVoIP,
string CallingWindow, string UTCOffset
);
record TcpaAuthorityResult(
string PhoneNumber, bool? IsReassigned, bool IsValid,
string LineType, string Carrier, string Locale,
string Region, string Country, string TZ, string UTCOffset
);
record LitigatorResult(long Phone, bool IsLitigator);
Usage:
using var client = new DncScrubClient("YOUR_API_KEY");
// Scrub
var scrubResults = await client.ScrubAsync("5039367187", "7075276405");
foreach (var r in scrubResults)
Console.WriteLine($"{r.Phone}: {r.ResultCode}");
// Check reassigned
var tcpa = await client.CheckReassignedAsync("7075276405", "20210209");
Console.WriteLine($"Reassigned: {tcpa?.IsReassigned}");
// Check litigators
var litigators = await client.CheckLitigatorsAsync("5039367187");
Console.WriteLine($"Litigator: {litigators[0].IsLitigator}");