> ## 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.

# Scrub Single Number

> Scrub a single phone number via the API

Scrub a single phone number against all configured DNC lists and compliance databases.

## Request

### Headers

<ParamField header="loginId" type="string" required>
  Your API Key
</ParamField>

### Query Parameters

<ParamField query="phoneList" type="string" required>
  The 10-digit phone number to scrub. Optionally append a pipe-delimited
  identifier (`5039367181|ACCT-1`) and/or postal code (`5039367181|ACCT-1|10001`;
  leave the identifier empty to pass only a postal code: `5039367181||10001`) —
  see [Postal Code Time Zones](#postal-code-time-zones)
</ParamField>

<ParamField query="version" type="string" required default="8">
  API version. Use `8` (latest). Version `6` adds `EBRExpiresOn`; version `7`
  adds `WirelessPortDate` and `VoIPDate`; version `8` adds `PostalCode`, `TZSource`,
  `IsCallAllowedNonATDS`, `IsCallAllowedATDS` and `IsCallAllowedAI`, and returns
  JSON as a typed object (`{"version": 8, "results": [...]}`) instead of an array
  of strings — see [JSON response
  shape](/api-reference/scrub/output-guide#json-response-shape).
</ParamField>

<ParamField query="output" type="string" default="json">
  Response format: `json` or `csv`
</ParamField>

<ParamField query="projId" type="string">
  Optional. Project ID
</ParamField>

<ParamField query="campaignId" type="string">
  Optional. Campaign ID
</ParamField>

## Postal Code Time Zones

By default `TZCode`, `UTCOffset`, `CallingWindow`, `CallingTimeRestrictions`
and `DoNotCallToday` are derived from the phone number's area code and prefix.
Mobile numbers keep their area code when their owner moves, so the area code is
not always where the person is. If you know the contact's postal code, pass it
and those fields are calculated from the postal code's time zone and state
instead — state calling hours, state holidays and state-of-emergency blocks all
follow the postal code's state.

The postal code is always passed per number, as the third pipe-delimited field
of `phoneList`: `PHONE|ID|POSTALCODE`. Leave the ID empty if you don't use one:

```
phoneList=5039367181||10001
```

There is deliberately no request-level parameter — one postal code applied to a
whole list would silently mis-time every other number. See [Unique
Identifiers](/api-reference/scrub/unique-identifier) for the pipe syntax.

Accepted formats: 5-digit US ZIP (ZIP+4 is accepted, e.g. `10001-1234`; only
the first five digits are used) and Canadian postal codes (`M5V3L9`, or just
the `M5V` forward sortation area). Case and hyphens are ignored. **Do not put
spaces inside a `phoneList` entry** — whitespace separates phone numbers, so
`M5V 3L9` must be sent as `M5V3L9` (or `M5V-3L9`).

If the postal code is not recognized, the number is processed exactly as if no
postal code had been passed. Use `version=8` to receive `TZSource`, which tells
you which method was used.

<Note>
  The postal code only affects the time zone and calling-window fields.
  `ResultCode`, `Reason`, `RegionAbbrev`, `Country`, `Locale`, DNC list matching
  and EBR logic are always based on the phone number.
</Note>

## One-Field Answer

With `version=8` the response also includes three yes/no flags so you don't
have to interpret `ResultCode`, `EBRType`, `DoNotCallToday` and the calling
window yourself. Pick the one that matches how you place calls:

| Flag | You are placing… |
| - | - |
| `IsCallAllowedNonATDS` | a manually dialed, live-agent call |
| `IsCallAllowedATDS` | an autodialed call (live agent on connect) |
| `IsCallAllowedAI` | a call with an AI, artificial or prerecorded voice |

See [Is the call allowed?](/api-reference/scrub/output-guide#is-the-call-allowed)
for the rules and [Compliance for AI Voice
Agents](/api-reference/scrub/ai-voice-agents) for the AI workflow end to end.

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request GET \
    'https://www.dncscrub.com/app/main/rpc/scrub?phoneList=7075276405&version=8&output=json' \
    --header 'loginId: YOUR_API_KEY'
  ```

  ```javascript JavaScript theme={null}
  const phoneNumber = "7075276405";
  const apiUrl = `https://www.dncscrub.com/app/main/rpc/scrub?phoneList=${phoneNumber}&version=8&output=json`;

  fetch(apiUrl, {
    method: "GET",
    headers: {
      loginId: "YOUR_API_KEY",
    },
  })
    .then((response) => response.json())
    .then((data) => {
      const result = data.results[0];
      console.log("Phone:", result.Phone);
      console.log("Result Code:", result.ResultCode);
      console.log("Reason:", result.Reason);
    });
  ```

  ```csharp C# theme={null}
  // Ensure TLS 1.2
  System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

  using (var client = new HttpClient())
  {
      client.DefaultRequestHeaders.Add("loginId", "YOUR_API_KEY");

      var phoneNumber = "7075276405";
      var url = $"https://www.dncscrub.com/app/main/rpc/scrub?phoneList={phoneNumber}&version=8&output=json";

      var response = await client.GetStringAsync(url);
      Console.WriteLine(response);
  }
  ```
</CodeGroup>

<ResponseExample>
  ```json Response theme={null}
  {
    "version": 8,
    "results": [
      {
        "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
      }
    ]
  }
  ```

  ```json phoneList=5039367181||10001 theme={null}
  {
    "version": 8,
    "results": [
      {
        "Phone": "5039367181",
        "ResultCode": "W",
        "Reserved": null,
        "Reason": ";;;W",
        "RegionAbbrev": "OR",
        "Country": "US",
        "Locale": "Portland",
        "CarrierInfo": "5820;WIRELESS;\"Verizon Wireless:Verizon Wireless\"",
        "NewReassignedAreaCode": null,
        "TZCode": 35,
        "CallingWindow": "8:00-21:00;8:00-21:00;8:00-21:00",
        "UTCOffset": -240,
        "DoNotCallToday": false,
        "CallingTimeRestrictions": 4,
        "EBRType": null,
        "IsWirelessOrVoIP": true,
        "LineType": "Wireless",
        "EBRExpiresOn": null,
        "WirelessPortDate": null,
        "VoIPDate": null,
        "PostalCode": "10001",
        "TZSource": "postalCode",
        "IsCallAllowedNonATDS": true,
        "IsCallAllowedATDS": false,
        "IsCallAllowedAI": false
      }
    ]
  }
  ```
</ResponseExample>

## Response Fields

<ResponseField name="Phone" type="string">
  The phone number that was scrubbed
</ResponseField>

<ResponseField name="ResultCode" type="string">
  The scrub result code (see [Result
  Codes](/api-reference/scrub/overview#result-codes))
</ResponseField>

<ResponseField name="Reserved" type="string | null">
  Your unique identifier if you passed one (`PHONE|ID`), otherwise `null`
</ResponseField>

<ResponseField name="Reason" type="string">
  Explanation of why the number is flagged
</ResponseField>

<ResponseField name="RegionAbbrev" type="string">
  State/region abbreviation (e.g., "CA")
</ResponseField>

<ResponseField name="Country" type="string">
  Two-digit country code (e.g., "US")
</ResponseField>

<ResponseField name="Locale" type="string">
  City or locality
</ResponseField>

<ResponseField name="CarrierInfo" type="string">
  Carrier information in format: `ID;TYPE;"Name"`
</ResponseField>

<ResponseField name="NewReassignedAreaCode" type="string | null">
  New area code if the number's area code has been split or overlaid, otherwise `null`
</ResponseField>

<ResponseField name="TZCode" type="integer">
  Time zone code (see [Timezone
  Codes](/api-reference/scrub/output-guide#timezone-codes)). Derived from the
  postal code when one is supplied, otherwise from the area code
</ResponseField>

<ResponseField name="CallingWindow" type="string | null">
  Permitted calling hours in the destination's local time, `HH:MM-HH:MM`, as
  three semicolon-separated windows: weekday;Saturday;Sunday (e.g.
  `8:00-21:00;8:00-21:00;8:00-21:00`). `null` when no window applies
</ResponseField>

<ResponseField name="UTCOffset" type="integer">
  UTC offset in minutes for the destination, adjusted for DST (e.g. `-240`)
</ResponseField>

<ResponseField name="DoNotCallToday" type="boolean">
  `true` if the number should not be called today (state holiday or state of emergency)
</ResponseField>

<ResponseField name="CallingTimeRestrictions" type="integer">
  Bit field: `1` = it is currently outside the calling window, `2` = an EBR
  exemption to the calling window is available, `4` = the destination state
  does not specify its own calling window (or you are exempt from it), so the
  federal 8 AM–9 PM window applies
</ResponseField>

<ResponseField name="EBRType" type="string | null">
  Type of EBR applied: `S` (Sale), `I` (Inquiry), or `P` (Permission). `null` if no EBR
</ResponseField>

<ResponseField name="IsWirelessOrVoIP" type="boolean">
  `true` if wireless or VoIP
</ResponseField>

<ResponseField name="LineType" type="string">
  Line type: `Wireless`, `VoIP`, or `AllOther`
</ResponseField>

<ResponseField name="EBRExpiresOn" type="string | 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)
</ResponseField>

<ResponseField name="WirelessPortDate" type="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 higher
</ResponseField>

<ResponseField name="VoIPDate" type="string | null">
  Date the number was identified as VoIP, `YYYY-MM-DD`. `null` if not VoIP. Requires
  `version=7` or higher
</ResponseField>

<ResponseField name="PostalCode" type="string | null">
  Normalized postal code used for the time zone calculation (`10001`, `M5V`).
  `null` if none was supplied. Requires `version=8` or higher
</ResponseField>

<ResponseField name="TZSource" type="string">
  `postalCode` when the time zone and calling window were derived from the
  supplied postal code, otherwise `areaCode`. Requires `version=8` or higher
</ResponseField>

<ResponseField name="IsCallAllowedNonATDS" type="boolean">
  `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?](/api-reference/scrub/output-guide#is-the-call-allowed) for the rules
  and for when this flag applies to you. Requires `version=8` or higher
</ResponseField>

<ResponseField name="IsCallAllowedATDS" type="boolean">
  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 higher
</ResponseField>

<ResponseField name="IsCallAllowedAI" type="boolean">
  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](/api-reference/scrub/ai-voice-agents). Requires `version=8` or higher
</ResponseField>

## Handling the Response. Make sure to handle all response codes. The sample below handles just a few

```javascript theme={null}
const { results } = await response.json();
const result = results[0];

switch (result.ResultCode) {
  case "C":
    // Clean - safe to call
    console.log("Phone number is clean");
    break;
  case "D":
    // Do Not Call
    console.log("Do not call:", result.Reason);
    break;
  case "W":
    // Wireless number detected
    console.log("Wireless number detected");
    break;
  default:
    console.log("Result:", result.ResultCode);
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.