Every error response follows the same structure and includes a clear error code you can match on programmatically.
Response format
Every error follows the same JSON structure. Match on the code field to handle specific cases in your code:
{
"success": false,
"data": null,
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits: 0 available, 1 required"
},
"metadata": {
"requestId": "00bc3fa0-348f-4955-a1c1-3c7c91234568",
"executionTimeMs": 3
}
}
Note
Always include metadata.requestId when contacting support. It lets us trace your request instantly.
Error reference
| Status | What to do |
|---|---|
422 |
Check your request body: a required field is missing or malformed. For async endpoints, make sure a webhook URL is configured. |
401 |
Check your API key: it may be missing, invalid, or expired. See Authentication. |
402 |
No credits left. Paid lookups (INSUFFICIENT_CREDITS) and the free /check endpoints (NO_CREDITS) are both blocked until you top up. Purchase more or upgrade your plan. |
403 |
Your key lacks a required permission, or the endpoint requires a paid plan. Upgrade to unlock live enrichment, email discovery, and more. |
404 |
No result found for your query. Some endpoints still charge credits; see Not found pricing. |
429 |
Rate limit reached. Wait and retry with backoff (see below). |
451 |
This person has been removed per GDPR/CCPA. Enrichment is permanently blocked. |
503 |
Our service is temporarily unavailable. Retry with backoff (see below). |
504 |
The lookup took too long and timed out. Retry with backoff (see below). |
When to retry
These statuses are safe to retry with exponential backoff:
429you’ve hit a rate limit. Wait for the reset window and retry.503temporary service issue. Retry after a short delay.504the lookup timed out before completing. Retry after a short delay.
All other errors require a change to your request or configuration before retrying.
Wait a little longer between each retry to give the server time to recover:
const delay = Math.min(1000 * 2 ** attempt, 15000)
const jitter = Math.floor(Math.random() * 250)
await new Promise((r) => setTimeout(r, delay + jitter))
delay = min(1 * 2 ** attempt, 15)
jitter = random.uniform(0, 0.25)
time.sleep(delay + jitter)
Credits and errors
All error responses (401, 402, 403, 422, 429, 451, 503, 504) cost 0 credits.
The 404 status is the only exception: some endpoints charge credits when the lookup was performed but no result was found. See Not found pricing for the full breakdown.