Docs Menu & Search
Documentation
Errors
Error response format and every status code the API can return.
Error Format
Errors return a non-2xx HTTP status and a JSON body with an error object containing a
machine-readable code and a human-readable message. Some errors include
extra fields (for example, recharge_url or retry_after_seconds).
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Credit balance is too low for this request. Please add credits.",
"recharge_url": "https://app.nabh.cloud/billing"
}
}Status Codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST |
Malformed JSON, or a required field such as model or input is missing. |
| 401 | AUTHENTICATION_ERROR |
API key is missing, invalid, or expired. |
| 402 | INSUFFICIENT_BALANCE |
Your credits (or the institution pool) are exhausted. Includes a recharge_url when the credits are your own. |
| 402 | SPEND_LIMIT_REACHED |
This API key has reached the monthly spend limit you set on it. Raise or remove the limit on the API Keys page, or wait for the 1st (IST). |
| 402 | PROJECT_BUDGET_REACHED |
The key’s project has reached its monthly budget. Raise the budget on the Projects page, or wait for the 1st (IST). |
| 403 | PERMISSION_DENIED |
The requested model isn’t available on your plan, or the key isn’t scoped correctly for an institution course. |
| 403 | IP_NOT_ALLOWED |
Request IP is not in the key’s whitelist. |
| 403 | ACCOUNT_SUSPENDED |
The account has been suspended. |
| 404 | INVALID_REQUEST |
Unknown model ID, or the model was called on the wrong endpoint — check that model’s docs page for its exact base URL. |
| 404 | NOT_FOUND |
The URL isn’t an API endpoint (for example /v1/responses or /v1/completions — use /v1/chat/completions). |
| 405 | METHOD_NOT_ALLOWED |
The endpoint exists but not for this HTTP method; the Allow header lists the right one. |
| 411 | MISSING_CONTENT_LENGTH |
Audio upload is missing a Content-Length header. |
| 413 | REQUEST_TOO_LARGE |
The JSON request body is larger than 10 MB. |
| 413 | INPUT_TOO_LARGE |
Text-to-speech input exceeds the 8,000-character limit. |
| 413 | FILE_TOO_LARGE |
Audio upload exceeds the 25 MB limit. |
| 429 | RATE_LIMIT_EXCEEDED |
Too many requests. Includes Retry-After header and retry_after_seconds in the body. |
| 503 | SERVICE_UNAVAILABLE |
A dependency (auth, rate limiter, model catalog, course policy) is temporarily down. Safe to retry. |
| 504 | GATEWAY_TIMEOUT |
The model sent nothing for 100 seconds. Without streaming nothing is sent until the answer is complete, so for long outputs set stream: true or lower max_tokens. Safe to retry. |
| 5xx | API_ERROR |
The model provider returned an unexpected error or the upstream connection failed. Safe to retry. |
| 502 | EMPTY_RESPONSE |
The model finished without producing anything; the request was not charged. Almost always the request is longer than the model’s context window (input plus max_tokens): shorten the conversation or lower max_tokens. |
Handling Errors
- Check the HTTP status first, then branch on
error.codefor specific handling. - On
402 INSUFFICIENT_BALANCE, prompt the user to recharge using the providedrecharge_url. - On
429 RATE_LIMIT_EXCEEDED, wait forRetry-Afterthen retry with backoff — see Rate Limits. - On
503 SERVICE_UNAVAILABLE, retry with backoff — it means a dependency is temporarily down, not that your request was invalid. - On
504 GATEWAY_TIMEOUTorAPI_ERROR, retry with backoff — these mean the model provider timed out or errored, not that your request was invalid.