# Errors Synthient returns conventional HTTP status codes and machine-readable JSON bodies for every failure. ## HTTP error shape Most error responses follow a small, consistent JSON envelope. Validation errors use a slightly richer body so you can show field-level messages. ```json title="Generic error" { "detail": "Invalid API Key" } ``` ```json title="Validation error" { "title": "Validation error", "errors": { "ip_address": ["must be a valid IP address"] } } ``` The HTTP `Content-Type` is always `application/json`. Empty bodies should be treated as transient infrastructure errors and retried. ## Status code reference | Status | Meaning | What to do | | ------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 Bad Request | Invalid input: malformed IP, bad cursor, oversized batch. | Fix the request before retrying. The body usually identifies the offending field. | | 401 Unauthorized | Missing or invalid `x-api-key` header. | Verify the key is loaded from the environment and not truncated. See [Authentication](https://docs.synthient.com/authentication). | | 402 Payment Required | Lookup credit balance is exhausted. | Add credits, upgrade your plan, or wait for `lookup_quota.resets_in` to elapse. See [Rate Limits](https://docs.synthient.com/rate-limits). | | 403 Forbidden | API key lacks the scope required for this endpoint. | Check granted scopes via [`/account/me`](https://docs.synthient.com/account); reach out to support to add the missing one. | | 404 Not Found | Snapshot, domain, or other resource doesn't exist. | Don't retry; the resource is genuinely missing. | | 429 Too Many Requests | Per-key rate limit or concurrent-stream limit hit. | Back off using the `Retry-After` header if present; otherwise exponential backoff with jitter. See [Rate Limits](https://docs.synthient.com/rate-limits). | | 500 Internal Server Error | Unexpected server error. | Retry with backoff. If the issue persists, [contact support](https://docs.synthient.com/misc/support). | | 503 Service Unavailable | Streaming or downstream backend temporarily down. | Retry with exponential backoff and jitter. | ## Per-status examples ### 400 Bad Request Returned when the request fails validation before any work is done. The body identifies the offending fields. ```json title="Malformed IP address" { "title": "Validation error", "errors": { "ip_address": ["must be a valid IP address"] } } ``` ```json title="Oversized batch" { "title": "Validation error", "errors": { "ips": ["must contain at most 1000 entries"] } } ``` ### 401 Unauthorized The API key was missing or rejected. Check that the value is non-empty and that you're using the `x-api-key` header. ```json { "detail": "Invalid API Key" } ``` ### 402 Payment Required You've spent your remaining lookup credits. Inspect `lookup_quota.credits` and `lookup_quota.resets_in` on [`/account/me`](https://docs.synthient.com/account) to see when your balance resets. ```json { "detail": "Quota exhausted" } ``` ### 403 Forbidden The key is valid but isn't scoped for the requested endpoint or feed. For example, calling `/feeds/anonymizers/stream` with a key that only has `PROXY_FIREHOSE`. ```json { "detail": "Insufficient scope for this resource" } ``` ### 404 Not Found There is no parquet snapshot for the requested date, or the domain has never been observed. ```json { "detail": "Snapshot not found" } ``` ### 429 Too Many Requests Returned when you exceed the per-key request rate or attempt to open more concurrent streams than your plan allows. Honour the `Retry-After` response header (seconds) when present. ```json { "detail": "Too many concurrent streams" } ``` ### 500 / 503 Server errors A `500` indicates an unexpected fault on our side; a `503` indicates the streaming or downstream backend is briefly unavailable. Both are safe to retry. Use exponential backoff with jitter and cap the delay at 60 seconds. ```json { "detail": "Internal Server Error" } ``` ## Recovery checklist 1. **Read the status code first.** `4xx` means your request needs to change; `5xx` means ours does, so retry safely. 2. **Honour `Retry-After` on `429`.** When present, wait at least that many seconds. 3. **Use exponential backoff with jitter.** Start at 1s, double up to a 60s cap, randomize ±25% so a flock of clients don't synchronize. 4. **Don't retry `400`, `403`, `404`.** They will not become success without a code change. 5. **Surface the `detail` body.** Forward it to your logs; it's the fastest way to diagnose unexpected failures. ## Next steps - [Authentication](https://docs.synthient.com/authentication): fixing `401` and `403` errors. - [Rate Limits](https://docs.synthient.com/rate-limits): handling `402` and `429` correctly. - [Support](https://docs.synthient.com/misc/support): when retries don't help.