Direct answer

This page explains how Singapore-based teams use NextModel's OpenAI-compatible gateway. Every gateway error code, the JSON envelope, billing semantics, and retry guidance. It adds the practical steps, configuration notes, and common questions.

The error envelope

Every error the gateway generates is JSON the OpenAI-shaped SDKs can parse: an error object with code and message, plus a billing_status field, and an X-NextModel-Billing-Status response header. (The Anthropic-native /v1/messages ingress returns the Anthropic error envelope instead, with the same billing headers.) Use the code field for programmatic handling and the message for logs; treat any code not listed here as a plain failure and retry per the guidance at the end of this page.

Example error response
HTTP/1.1 429 Too Many Requests
X-NextModel-Billing-Status: not_charged

{
  "error": {
    "code": "rate_limited",
    "message": "Account rate limit exceeded."
  },
  "billing_status": "not_charged"
}

Errors never bill — verified per request

A reservation is taken before the upstream call and settled only after the model's response is delivered in full. Every failure path — provider error, mid-stream failure, even your own client disconnect — rolls the reservation back, so a failed request costs nothing. The X-NextModel-Billing-Status header on every response tells you which happened: settled (delivered and charged), rolled_back (failed, nothing charged), or not_charged (rejected before any upstream call). Usage that a stream already delivered before a later failure would have been settled at actual tokens; in practice the gateway rolls back whenever the stream did not complete cleanly.

Authentication and account

Fix the key or the account state before retrying — these never resolve on their own.

401 · missing_api_keyNo Authorization header. Send: Authorization: Bearer $NEXTMODEL_API_KEY
401 · invalid_api_keyKey unknown, disabled, or deleted. Create a new key in the dashboard.
403 · account_not_foundThe key's account no longer exists. Contact support.
402 · insufficient_creditsPrepaid credit check failed. Top up, then retry.
404 · anthropic_ingress_disabledAnthropic-native endpoints are disabled on this deployment.
404 · embeddings_ingress_disabledEmbeddings ingress is disabled on this deployment.
404 · tts_ingress_disabledText-to-speech ingress is disabled on this deployment.
404 · transcription_ingress_disabledAudio transcription is not open yet — the route exists but the deployment has not switched it on.

Request validation

The request never reached a model. Fix the payload; do not retry as-is.

400 · invalid_request_bodyBody is not valid JSON or has the wrong shape.
400 · missing_messagemessages array missing or empty.
400 · missing_inputInput field missing (responses, embeddings, audio).
400 · missing_promptPrompt field missing (image or audio endpoints).
400 · model_not_supportedModel id is not in the live catalog. Fetch GET /v1/models and use an id from it.
400 · prompt_too_longInput exceeds the model's context window.
400 · message_too_longA single message exceeds the per-message limit.
400 · n_too_largeThe n (number of choices) parameter exceeds the allowed maximum.
400 · invalid_image_urlImage URL failed fetch or validation (multimodal input).
400 · unsupported_video_rateRequested frame rate is not supported for the video model.
400 · audio_file_requiredAudio endpoint needs a file upload.
400 · speech_input_too_longTTS input text exceeds the character limit.
413 · request_body_too_largeRequest body exceeds the size cap. Trim attachments or context.
409 · idempotency_replay_conflictSame idempotency key reused with a different request body. Use a fresh key per distinct request.

Rate limits

Back off and retry. Respect the Retry-After header when present.

429 · rate_limitedGeneric rate limit (Anthropic-ingress paths report this code too).
429 · account_rate_limitedPer-account request rate exceeded — slow down across all keys of the account.
429 · api_key_rate_limitedThis key exceeded its own per-minute limit.

Upstream and platform availability

Transient by nature — safe to retry with exponential backoff. If a 503 persists across minutes, check the status page before filing a report.

upstream_error (provider's own status)The provider returned a non-2xx; its status and message are relayed under this code.
502 · egress_translation_failedProvider response could not be translated to the ingress protocol.
503 · channel_retries_exhaustedEvery channel for the model failed; routing gave up. Retry after a delay.
503 · provider_network_errorNetwork failure while calling the provider.
503 · gateway_not_readyGateway storage or upstream is still initializing.
503 · media_busyImage generation is at its concurrency cap. Honor Retry-After and retry.
503 · storage_not_configured / billing_store_unavailableGateway storage hiccup — retry.
500 · internal_errorUnexpected gateway fault. Retry once, then report with the request id.
500 · council_orchestration_failedA council run failed mid-quorum. Retry; partial calls are rolled back.
404 · job_not_foundVideo job id unknown or already expired.
404 · not_foundUnknown API path. Check the path against this docs section.
405 · method_not_allowedWrong HTTP verb; the Allow header lists what the path accepts.
501 · protocol_runtime_not_routedVendor-native protocol paths (gemini/mistral/cohere/dashscope/bedrock) are not open yet — call the same model through the OpenAI-compatible endpoints.

Retry guidance

Retry 429 and 5xx with exponential backoff and jitter, up to a small maximum; honor the Retry-After header when it is present. Never blindly retry 4xx — validation and auth errors fail identically forever. Requests accept an idempotency_key field in the JSON body: replaying the same request under the same key returns the original result instead of charging twice, and reusing a key with a different body is the 409 conflict above. When contacting support, include the request id, timestamp, model, and the error code — never the API key itself.