Error codes and next steps
Look up a status code the Gateway returned to see what it means, what to check first, and what to do next.
Every error response carries a request_id. Include it when you contact support so we can find the request.
See where a request stops#
Choose a scenario to see where the request stops and what the response looks like.
x-ratelimit-limit-requests: … x-ratelimit-remaining-requests: … x-ratelimit-reset-requests: …
The body is the provider's response in your SDK's format. Rate-limit headers tell you how much room is left.
Log & billing — Input and output tokens are metered and charged in credits against the project's balance; the call shows up in the console's request logs.
curl https://api.atptoken.ai/v1/chat/completions \
-H "Authorization: Bearer atp-..." \
-H "Content-Type: application/json" \
-d '{
"model": "<model from GET /v1/models>",
"messages": [{"role": "user", "content": "hi"}]
}'
Text version
| Step | Check | Stops with | Response |
|---|---|---|---|
| 1. Client | Sends a project key | — | — |
| 2. Key check | Valid, active key | 401 Unauthorized | {"message":"API key has been revoked or does not exist.","error":"token_revoked"} |
| 3. Model allowlist | Model enabled for the project | 403 Forbidden | {"error":{"message":"model not available for this project","type":"permission_denied","request_id":"..."}} |
| 4. Credits | Project balance left | 402 Payment Required | An error body in your SDK's error format: the wallet or credit pool is exhausted. Top up to resume; retrying won't help. |
| 5. Rate limit | Within limits | 429 Too Many Requests | An error body in your SDK's error format: a rate limit, quota or provider cooldown. Back off and retry; honor Retry-After if present. |
| 6. Provider | Routed with failover | — | — |
| 7. Log & billing | Metered in credits | 200 OK | x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests — The body is the provider's response in your SDK's format. Rate-limit headers tell you how much room is left. |
200 with empty content#
A request can return 200 OK with an empty message — no error, just no text. This is almost always driven by request parameters, not a failure. The most common cause is a max_tokens that is too low for a reasoning (extended-thinking) model: the entire budget is consumed by internal reasoning before any visible output is produced, so the content comes back empty.
On this platform that request typically reports zero token usage and deducts no credits — an empty 200 with an empty usage object is the signature of this case, not a billing bug. Fix it by raising max_tokens so it covers the model's thinking budget plus your expected output, or turn extended thinking off. Always check finish_reason / stop_reason and usage before assuming text exists.