Skip to main content

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}");