---
url: https://docs.dataflair.ai/guide/error-handling.md
description: The JSON error shapes and status codes used by the Toplist API.
---

# Error handling

These error conventions apply to the Toplist API. Stats postbacks and the Ad Server API report errors in their own formats, described on their own pages.

**Always send `Accept: application/json` on every request**, including auth exchanges. Requests run
on a middleware stack that needs this header to return the JSON error shapes below. Without it, a
validation or throttling error can come back as an HTML redirect instead.

| Status | `error` | When | Body example |
|---|---|---|---|
| `401` | `invalid_credentials` | Token exchange: key not found, or secret is wrong (identical response for both, deliberately, so a caller can't use the response to figure out whether a key exists at all) | `{"error":"invalid_credentials","message":"Invalid API key or secret."}` |
| `403` | `ip_not_allowed` | Token exchange: caller's IP isn't on that credential's allowlist | `{"error":"ip_not_allowed","message":"Your IP address is not in the allowed list for this credential."}` |
| `401` | `unauthenticated` | Any data endpoint: missing/invalid/expired bearer token, **or** an IP-allowlist mismatch on this path (surfaces identically to a bad token, not as a 403) | `{"error":"unauthenticated","message":"Invalid or missing API token."}` |
| `403` | `insufficient_scope` | Any data endpoint: your credential doesn't carry the scope that endpoint requires | `{"error":"insufficient_scope","message":"This credential does not have the required scope: toplist:read"}` |
| `404` | `not_found` | Single-resource lookups: no matching, currently-available resource | `{"error":"not_found","message":"Toplist not found or not available."}` |
| `422` | N/A (standard validation) | Token exchange: a required field is missing from the request body | `{"message":"The key field is required. (and 1 more error)","errors":{"key":["The key field is required."],"secret":["The secret field is required."]}}` |
| `429` | N/A (standard throttle) | Rate limit exceeded | Standard `Retry-After` / `X-RateLimit-*` headers, `{"message":"Too Many Attempts."}` |

Rate limits are set per endpoint and per credential. Check the specific API's reference pages (for
example, the Toplist API's [Auth token endpoint](/dataflair/toplist-api/authentication) for the token-exchange
limit, and the [Toplist API overview](/dataflair/toplist-api/) for the default per-credential data-endpoint
limit) for exact numbers.
