Errors
Every error code, what causes it, and whether it costs you anything.
Every error returns the same envelope:
{
"error": {
"code": "insufficient_balance",
"message": "This request costs $0.064000 but your balance is $0.0100.",
"docs": "https://enricho.io/docs/errors#insufficient_balance"
}
}
Match on code, never on message — messages are written for humans and will change.
| Status | Code | Cause | Charged? |
|---|---|---|---|
| 401 | invalid_api_key |
Missing, malformed or revoked key | No |
| 402 | insufficient_balance |
Balance below the price of the call | No |
| 404 | not_found |
Unknown endpoint | No |
| 422 | invalid_params |
Required parameters missing | No |
| 429 | concurrency_limit_exceeded |
Too many requests in flight | No |
| 502 | upstream_unavailable |
The source could not be reached | No |
| 503 | service_unavailable |
Planned maintenance | No |
Nothing in that table is charged. You are only ever billed for a call that returned data.
invalid_api_key {#invalid_api_key}
Unknown, malformed and revoked keys all return the same response deliberately, so the error cannot be used to tell a real-but-revoked key from a guess.
insufficient_balance {#insufficient_balance}
The response includes required, balance and a topup_url. Switch on automatic top-ups if you would rather a long job never stops.
concurrency_limit_exceeded {#concurrency_limit_exceeded}
Respect Retry-After. Retrying immediately in a tight loop will keep failing — back off, or reduce your worker count to your tier's limit.
upstream_unavailable {#upstream_unavailable}
Transient. Retry with exponential backoff. If it persists, check status before opening a ticket.
service_unavailable {#service_unavailable}
Planned maintenance. The message says what is happening and Retry-After suggests when to come back.