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

# Errors and rate limits

> Handle errors, request IDs, and retry timing.

Errors use this format:

```json theme={null}
{
  "error": {
    "code": "unknown_proxy_ip",
    "message": "One or more IPs are not active in this subscription.",
    "details": { "ips": ["198.51.100.10"] },
    "request_id": "ad2f824c-46bc-47c6-b276-2bb51a3083b1"
  }
}
```

`details` appears only when the API can identify specific input IPs. `X-Request-ID` matches `error.request_id`; include it when contacting support.

## Error codes

| HTTP | Code | Next step |
| - | - | - |
| `400` | `invalid_request` | Correct the ID, JSON, IP format, or selection size. |
| `400` | `invalid_ip_address` | Use one public IPv4 address for IP authorization. |
| `400` | `invalid_proxy_ip` | Replace the IPs in `error.details.ips` with valid public IPv4 addresses. |
| `400` | `duplicate_proxy_ip` | Remove duplicate IPs. |
| `400` | `unknown_proxy_ip` | Refresh the proxy list; submit active IPs from it. |
| `400` | `invalid_package` | Refresh the ISP catalog; correct the package options. |
| `401` | `unauthorized` | Use your current API key as a bearer token. |
| `403` | `forbidden` | The member who created the API key is disabled. Create a new API key. |
| `402` | `insufficient_balance` | Add funds or buy a GB package on the website; confirm a current quote. |
| `403` | `kyc_required` | Complete organization verification before ordering. |
| `404` | `not_found` | Check the ID and workspace. |
| `409` | `not_available` | The invoice PDF is not ready yet. Retry later or open `hosted_invoice_url`. |
| `409` | `quote_expired` | Create a new quote. |
| `409` | `request_conflict` | Refresh the quote or order; do not change the existing request. |
| `409` | `rotation_in_progress` | Poll the active rotation before changing the subscription. |
| `429` | `rotation_allowance_exhausted` | Select fewer IPs or wait until `rotations_reset_at`. |
| `429` | `rate_limit_exceeded` | Wait for `Retry-After` before retrying. |
| `500` | `internal_error` | Retry later; contact support with `request_id` if needed. |
| `503` | `temporarily_unavailable` | Retry later with backoff. |

Individual rotation failures can use `rotation_temporarily_unavailable`. Check the item's `retryable` flag before submitting that IP again.

## Rate limits

Limits apply per API key in 60-second windows:

| Request class | Default limit | Operations |
| - | -: | - |
| Read | 120 per minute | All `GET` requests |
| Rotation | 10 per minute | Rotation `POST` |
| Authorization | 20 per minute | Authorization `PUT` and `DELETE` |
| Purchase | 10 per minute | Quote, order, and credential `POST`; subscription and credential `DELETE`; traffic limit `PUT` |

Rate-limit responses include `Retry-After` in seconds. Wait at least that long. Rotation acceptance also returns `Retry-After: 2` before the first poll.

> [!NOTE]
>
> `429 rotation_allowance_exhausted` may omit `Retry-After`. Check the subscription's `rotations_reset_at` instead.


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