> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dnclatam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors and retries

> Handle validation failures, account state, idempotency conflicts, quotas, rate limits, and temporary capacity.

Error responses use JSON and include an `error` code. Many also include a
human-readable `message` and structured fields that should drive recovery.

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "rate limit exceeded",
  "limit": 60,
  "window_seconds": 60,
  "retry_after": 12
}
```

## Error matrix

| HTTP  | `error`                           | Meaning                                                                   | Client action                                                                                               |
| ----- | --------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `400` | `missing_idempotency_key`         | The required header is missing.                                           | Generate a new opaque key for the logical request.                                                          |
| `400` | `invalid_idempotency_key`         | The key does not meet format requirements.                                | Use 1–255 visible ASCII characters without spaces.                                                          |
| `400` | `invalid_body`                    | JSON or the `phones` array is invalid.                                    | Fix the request; do not retry unchanged.                                                                    |
| `400` | `unsupported_country`             | `country` is not `mx` or `ar`.                                            | Split and send a supported country.                                                                         |
| `400` | `too_many_phones`                 | The batch exceeds the current OpenAPI limit.                              | Split the work into smaller logical requests with different idempotency keys.                               |
| `400` | `phone_too_long`                  | At least one input exceeds the per-string limit.                          | Reject or clean that input before retrying.                                                                 |
| `401` | `invalid_key`                     | The API key is missing, invalid, or revoked.                              | Fix or rotate the secret; do not retry automatically.                                                       |
| `402` | `subscription_inactive`           | The Stripe-backed subscription is not active.                             | Resolve billing before retrying.                                                                            |
| `403` | `account_suspended`               | The organization is suspended.                                            | Contact DNC LATAM support.                                                                                  |
| `403` | `country_not_in_plan`             | The selected country is not enabled.                                      | Add the country or use an entitled country.                                                                 |
| `409` | `idempotency_request_in_progress` | The same logical request is still running.                                | Respect `Retry-After`; retry the exact payload with the same key.                                           |
| `409` | `idempotency_key_reused`          | The key was used with a different payload.                                | Generate a new key for the new logical request.                                                             |
| `413` | `payload_too_large`               | The HTTP body exceeds the transport limit.                                | Reduce or split the batch.                                                                                  |
| `429` | `rate_limit_exceeded`             | The organization exceeded 60 requests per 60 seconds across its API keys. | Respect `Retry-After` and rate-limit headers.                                                               |
| `429` | `monthly_quota_exceeded`          | The country-specific monthly number allowance is exhausted.               | Stop retries; inspect `country`, `limit`, `used`, and `requested`, then change volume in billing if needed. |
| `429` | `temporarily_blocked`             | The source IP triggered unknown-route abuse protection.                   | Stop probing unknown routes and respect `Retry-After`.                                                      |
| `503` | `capacity_exceeded`               | The API is at bounded temporary capacity.                                 | Respect `Retry-After` and retry with bounded backoff.                                                       |
| `500` | `internal`                        | An unexpected server failure occurred.                                    | Record the non-sensitive `request_id`; retry cautiously or contact support.                                 |

## Retry policy

Retry only failures that can recover without changing the logical request:

* `409 idempotency_request_in_progress`
* `429 rate_limit_exceeded`
* `503 capacity_exceeded`
* selected network timeouts and `5xx` responses

For those retries:

1. Keep the exact same country, phone array, and idempotency key.
2. Honor `Retry-After` when present.
3. Add exponential backoff with jitter when no delay is provided.
4. Set a bounded attempt count and total deadline.
5. Never log the phone array or authorization header.

Do not automatically retry validation, entitlement, billing, quota, or
idempotency-conflict errors.

## Rate-limit headers

A technical rate-limit response can include:

```http theme={null}
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1780000000
```

`X-RateLimit-Reset` is a Unix timestamp.

## Quotas count phone inputs

Monthly allowances count `summary.total_checked` inputs, not HTTP requests.
API and CSV scrubs share the same country-specific allowance for the
organization.

Invalid inputs and duplicates count because they are submitted inputs.
