Overview
NanoGPT APIs return standard HTTP status codes. Many endpoints also follow OpenAI- or Anthropic-compatible error shapes so you can reuse existing SDK error handling. If you contact support about an API error, include theX-Request-ID response header (when present).
For private feedback submission and status retrieval, see the
Feedback API for the
exact HTTP status and error.code mapping. Feedback uses feedback_unavailable
for both permanent 410 responses and temporary 503 responses, so clients
must check the HTTP status before retrying.
Error Response Formats
NanoGPT has a few common error envelopes depending on the API surface.OpenAI-compatible (most /api/v1/* endpoints)
Used by endpoints like:
POST /api/v1/chat/completionsPOST /api/v1/responsesPOST /api/v1/embeddingsGET /api/v1/models
error.message: human-readableerror.type: high-level category (see Error Types)error.code: optional machine-readable code (see Error Codes)error.param: optional name of the request field that caused the error
Anthropic-compatible (POST /api/v1/messages)
The Messages API uses the Anthropic-style wrapper:
Legacy / simple format (some /api/* endpoints)
Some older endpoints return a simpler body:
requiredBalance on 402).
Status Codes
This table covers the most common HTTP error statuses you may encounter.
Notes:
- Some endpoints include convenience fields like
statusin the JSON body mirroring the HTTP status code. - Some error responses include
Retry-After(seconds) for429.
Error Types
Depending on the endpoint, you may see different type strings. Common values include:invalid_request_error(400)authentication_error(401)permission_denied_errororpermission_error(403)not_found_error(404)rate_limit_error(429)server_error,service_unavailable, orapi_error(500/503)
Error Codes
Not every error includes acode. When present, codes are useful for programmatic handling.
Common codes include:
Request validation
missing_required_parameterinvalid_parameter_valueinvalid_jsoninvalid_json_schematool_choice_unsupportedimage_input_not_supportedconflicting_moderation_modelinline_moderation_requires_api_keyempty_moderation_inputunsupported_moderation_inputunsupported_input_modalityunsupported_batch_input
Content and context
content_policy_violationcontext_length_exceededempty_response
Model and routing
model_not_foundmodel_not_allowedmodel_not_availableall_fallbacks_failedno_fallback_availablefallback_blocked_for_cache_consistencynative_web_search_unavailable(native web search was requested, but the allowed providers cannot run it)
Balance and payment
memory_balance_requiredwebSearch_balance_requiredboth_balance_required
Rate limiting
rate_limit_exceededapi_key_rpd_limit,api_key_usd_limitand the other per-key limits (see Rate Limits)api_account_monthly_usd_limitauthentication_rate_limited(see Authentication rate limiting)
Authentication Rate Limiting
A credential that keeps being rejected (an unknown, expired or revoked key, or a key whose account is blocked) is temporarily refused before it is checked again. The response is429 with code: "authentication_rate_limited", type: "authentication_error" and a Retry-After header in seconds. No model provider is contacted and nothing is charged.
POST /api/v1/messages returns the same code inside the Anthropic-style wrapper.
How the throttle works:
- It is applied per credential, not per IP address. Other keys sent from the same address, network or cloud egress keep working, and a key that authenticates successfully is never affected by other clients’ failures.
- An address is only restricted as a whole when it presents many different invalid credentials within a few minutes. Even then, keys that recently authenticated successfully keep working; only credentials that have not been seen succeeding are refused from that address until the restriction lapses.
- Requests that carry no credential at all are limited per address, separately.
- A key that keeps tripping the throttle is refused for longer each time, up to 15 minutes.
x-nanogpt-auth-rate-limit-reason on these responses: credential_blocked (this key), ip_restricted (this address presented many invalid keys) or missing_credential_throttled (too many requests without a credential). POST /api/v1/responses returns the same code and headers in its own error format.
Client action: stop retrying with that key until Retry-After has elapsed, and check the key itself. Retrying with the same key does not shorten the wait; rotating IP addresses does not help and is unnecessary. A 429 with this code is not a throughput or daily limit, so it does not mean your traffic volume is too high.
Streaming Errors
When using Server-Sent Events ("stream": true), errors can happen:
- Before streaming begins (you get a normal JSON error response with an HTTP status code)
- Mid-stream (you may receive an error frame/chunk, or the connection may terminate)
- Surface/log the error message
- Log the
X-Request-IDheader if available - Retry only when the status/category indicates it is safe to retry (for example 408/429/500/503)
X-Request-ID before reading the stream and use Request Billing
with the same API key to check the original primary charge. Repeating inference
can create a separate charge; a reused request ID does not deduplicate it.
Retry Guidance
General retry recommendations:- Retry:
408,429,500,503(use exponential backoff and respectRetry-After) - Do not blindly retry:
400,401,402,403,404,409,413
404 from Request Billing
can mean accounting is still pending. Wait at least its Retry-After: 30 delay
plus jitter before looking up the same ID again. Honor larger retry delays on
429 and 503; stop on 200, permanent errors, or no later than 24 hours after
the original request. A 404 can also mean expired, absent, or inaccessible
records, so it never proves zero cost.
If you need current guidance on global rate limits, see Rate Limits.
Daily Per-Key Limit Notes
NanoGPT can enforce optional per-key daily limits (Requests/Day and USD/Day). When a daily limit is exceeded, the API returns429 and typically includes a Retry-After header indicating the number of seconds until the next reset at 00:00 UTC.
Balance Errors (402)
Some endpoints return402 Payment Required when payment is needed before the request can run. There are two common cases.
Authenticated Balance Error
Accountless x402 Payment Challenge
Supported endpoints can also be called withoutAuthorization or x-api-key when the client explicitly opts in to accountless x402 quote generation. To request an accountless x402 quote, send the API request without Authorization or x-api-key, and include x-x402: true. NanoGPT will return 402 Payment Required with available payment options and a stable top-level payment object plus legacy OpenAI-compatible error fields.
If you receive 401 missing_api_key immediately, check that the initial quote request includes x-x402: true. Without that header, NanoGPT does not enter the x402 quote flow.
Detect accountless x402 by checking for the top-level payment object, not a single error.code value.
accepts array may still appear for backwards-compatible and lower-level protocol clients, but new clients should use payment.accepted[]. Exact rails such as nano-exact, x402-exact, and x402-solana-usdc replay the original request with X-PAYMENT; polling-style rails such as nano and base-usdc use statusUrl and completeUrl; Lightning L402 replays the exact original request with Authorization: L402 <token>:<preimage> and does not use X-PAYMENT or completeUrl. See Accountless x402 API Payments for the complete flow and supported endpoint matrix.
Feature-specific variants may include a structured error code such as memory_balance_required or webSearch_balance_required.
Content Policy and Empty Responses
- If a request is blocked by safety checks (
content_policy_violation), the API will return a400error and is intended to avoid charging for the blocked generation request. If Inline Moderation blocked the request, the separate moderation preflight is still charged. - If the API returns
empty_response, the request is intended to avoid charging (common causes: stop sequences, very lowmax_tokens, or filtering).