Handle errors clearly
Errors include a stable code, a readable message and a request ID. Keep the request ID when contacting support. Some no-match responses use a top-level code and message.
{"error":{"code":"invalid_ip","message":"Enter valid IPv4 or IPv6 addresses.","request_id":"…","documentation_url":"/docs/errors"}}| Status | What to do |
|---|---|
| 400 | Correct the input; private and reserved IPs cannot be geolocated. |
| 401 | Check that your API key is present and valid. |
| 403 | Check key scopes, restrictions and plan eligibility. |
| 404 | Handle no match, an unknown country or an unknown route. |
| 409 | The requested source is unavailable. Try canonical lookup or retry later. |
| 422 | Correct the request body or batch contents. |
| 429 | Respect Retry-After and check your allowance. |
| 503 | The service or required data is unavailable. Use a fallback and bounded backoff. |
Retry transient failures with a delay and a maximum attempt count. Do not repeatedly retry invalid input or rejected credentials. For personalization, offer a manual choice when location is unknown.
Error codes
| Field or endpoint | Meaning |
|---|---|
| invalid_ip / non_geolocatable | Correct input; do not retry unchanged. |
| invalid_key | Check credentials and workspace verification. |
| origin_required / origin_forbidden / ip_forbidden | Correct key restrictions or deployment origin. |
| scope_required / paid_plan_required | Use an eligible key/plan. |
| no_match | Keep location unset and offer manual selection. |
| source_unavailable | Use a suitable fallback and bounded retry. |
| rate_limited | Slow requests; honor Retry-After when present. |
| quota_exceeded | Wait for reset or change plan. |
Keep X-Request-ID or error.request_id for support. Source no-match can use top-level code/message rather than an error envelope. Some endpoints, including standalone ASN quota errors, may omit Retry-After; use a known reset time or bounded delay. Never log a key or expose stack traces.
Examples of error payloads
Examples below show shapes, not live failures. Match the structured code, and retain the request reference for support.
{
"error": {
"code": "scope_required",
"message": "This key does not have the required scope.",
"request_id": "EXAMPLE_REFERENCE",
"documentation_url": "/docs/errors"
}
}{
"code": "no_match",
"message": "No matching public range.",
"remaining": 999,
"reset_at": "EXAMPLE_RESET_TIME"
}Choose a retry policy
Do not retry 400/401/403 unchanged. A 404 no-match is an application result, not a transient network fault. For rate_limited, wait at least Retry-After when provided. quota_exceeded needs a reset or plan change. Retry transport failures and 502/503/504 only with a delay and a small maximum attempt count; a repeated successful lookup can consume another credit.
