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

# Rate Limits

> API rate limits and best practices

All APIs have rate limits to ensure fair usage and system stability.

## Standard Rate Limits

| API | Rate Limit | Max Batch Size |
| - | - | - |
| Scrub API (GET) | 200 requests/minute | 10 numbers |
| Scrub API (POST) | 200 requests/minute | 10,000 numbers |
| Litigator-Only API (GET) | 1,000 requests/minute | 10 numbers |
| Litigator-Only API (POST) | 1,000 requests/minute | 10,000 numbers |
| Reassigned APIs | 1,000 requests/minute | 1,000 numbers |
| TrustCall | 100 requests/minute | 50 numbers (add) |

## Exceeding the Rate Limit

Limits are enforced per client IP address over a one-minute window. Requests over the limit are
rejected with HTTP `429 Too Many Requests` and this body:

```json theme={null}
{"error":"rate_limit_exceeded","message":"Rate limit exceeded. Slow down and retry after 60 seconds."}
```

Key on the status code rather than parsing the body: the `429` is returned by our edge gateway,
which labels the body `Content-Type: text/html`. Wait 60 seconds before retrying; a tight retry loop
keeps the window full and extends the block.

## Average API Response Times

Average response time per request. Unless otherwise noted (for example, the 1,000-number batch row), times are measured for a single phone number. These are averages measured by third-party monitoring services. Outliers will exist that are both faster and slower.

| API | Average Response Time |
| - | - |
| Full Scrub API (1 number) | 600ms |
| Full Scrub API (1,000 numbers) | 1200ms |
| Litigator-Only API (1 number) | 400ms |
| Reassigned Authority Plus (1 number) | 700ms |
| Reassigned Authority (1 number) | 500ms |
| RND Basic (1 number) | 700ms |
| Right Party ID (1 number) | 1600ms |

## HTTP Method Requirements

| Numbers | Required Method |
| - | - |
| 1-10 | GET or POST |
| 11+ | POST required |

<Warning>
  Requests with more than 10 phone numbers **must** use HTTP POST. GET requests
  will fail. If you don't know your payload size, use HTTP POST to prevent
  future issue.
</Warning>

## Retry Example

**You must plan what your system will do in the event of a network or service outage.** Our recommendation is to implement retries with exponential backoff.

```javascript theme={null}
async function scrubWithRetry(phoneNumbers, apiKey, maxRetries = 5) {
  const baseUrl = "https://www.dncscrub.com/scrub";
  const url = `${baseUrl}?phone=${phoneNumbers.join(",")}`;
  const baseDelay = 1000; // Start with 1 second

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    let response;
    try {
      response = await fetch(url, { headers: { loginId: apiKey } });
    } catch (networkError) {
      // fetch throws on DNS/connection failures; treat like a 5xx and retry
      response = { ok: false, status: 0 };
    }

    if (response.ok) {
      return await response.json();
    }

    const retryable = response.status === 429 || response.status >= 500 || response.status === 0;
    if (retryable && attempt < maxRetries) {
      // 429 = rate limited: wait out the one-minute window before retrying
      // 5xx / network error = transient failure: exponential backoff 1s, 2s, 4s, 8s, 16s
      const delay =
        response.status === 429 ? 60000 : baseDelay * Math.pow(2, attempt - 1);
      console.log(
        `Request failed with ${response.status || "network error"}. Retrying in ${
          delay / 1000
        }s (attempt ${attempt}/${maxRetries})...`
      );
      await new Promise((resolve) => setTimeout(resolve, delay));
      continue;
    }

    throw new Error(`Request failed with status ${response.status}`);
  }
  throw new Error("Max retries exceeded");
}

// Usage
const results = await scrubWithRetry(
  ["5551234567", "5559876543"],
  "your-api-key"
);
```

## Best Practices

<AccordionGroup>
  <Accordion title="Batch Your Requests">
    Instead of making 100 requests with 1 number each, make 1 request with 100
    numbers.
  </Accordion>

  <Accordion title="Implement Retry Logic">
    If you receive a 5xx response, wait and retry with exponential backoff. If
    you receive a 429, you have exceeded your rate limit: wait 60 seconds, then
    retry.
  </Accordion>

  <Accordion title="Cache Results">
    Cache scrub results to avoid re-checking the same numbers unnecessarily.
  </Accordion>

  <Accordion title="Plan for Outages">
    Consider what your system will do in the event of a network or service
    outage. Implement retry logic with exponential backoff and have a fallback
    plan for when the API is unavailable.
  </Accordion>

  <Accordion title="Use SFTP for Very Large Batches">
    For very large batches of phone numbers where real-time checking is not
    needed, consider using SFTP file upload instead of the API. This is more
    efficient for processing millions of records.
  </Accordion>
</AccordionGroup>

## File Upload Limits for SFTP or Web Portal

| Product | Max Rows Per File | Max File Size |
| - | - | - |
| Reassigned Authority Plus | 1,000,000 | 500MB |
| Reassigned Authority | 10,000,000 | 650MB |
| DNC Scrub | 15,000,000 | 800MB |


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