Errors
Every failure returns a code you can act on.
Recoverable API failures return a stable code, a human-readable message, and a request id instead of an anonymous Bad Gateway. This page is the single public catalog for those codes.
One error shape everywhere.
Errors carry type, code, message, request_id, and docs_url. Field-level problems add param; quota and rate-limit errors add safe numeric details.
{
"error": {
"type": "billing_error",
"code": "quota_insufficient_for_request",
"message": "Weekly quota does not have enough room to reserve this request.",
"request_id": "req_...",
"docs_url": "https://lumaos.cloud/docs/errors"
}
}Keep the request id.
Every error response includes the same id in the body (request_id) and in the x-request-id and x-lumacloud-request-id headers.
Support and debugging work from that id, so log it alongside your own request logs and include it in any report.
Rate-limit responses also carry a Retry-After header. Clients that honor it recover faster than clients that retry blind.
Catalog
Error codes by category.
Each code lists when it happens and the first recovery action. Codes are stable; messages may be refined over time.
Authentication
The request never reached routing because the key or token could not be verified.
missing_api_key
401
No credentials were sent. The gateway accepts Authorization: Bearer <key> or the x-api-key header.
What to do: Add Authorization: Bearer with your key from the dashboard (App -> API) and retry.
invalid_api_key
401
The key was sent but does not match an active key record.
What to do: Copy a fresh key from the dashboard. Check for truncation or extra whitespace when pasting into tools.
supercodex_required
401
A key bound to the SuperCodex app was used from a different client.
What to do: Use that key inside SuperCodex only. For your own CLI agents and tools, create an external API key on a Builder workspace.
invalid_device_token
401
A SuperCodex device token was sent without a key, but it is invalid or does not match a registered device.
What to do: Sign in again inside SuperCodex so the device re-registers, then retry.
Access and policy
The key is real, but the account, key state, or model policy blocks the request.
key_inactive
403
The API key exists but has been disabled.
What to do: Create a new key or re-enable this one in the dashboard, then update the client configuration.
model_not_allowed
403
The key is not permitted to use the requested model.
What to do: Call GET /v1/models with the same key to see what it can access, or adjust the key's allowed models in the dashboard.
access_expired
402
The account's paid access period has ended. Details include accessExpiresAt.
What to do: Renew the subscription or top up the account from the dashboard, then retry.
account_held
423
The account has been placed on hold by an operator.
What to do: Contact support and include the request id from the error response.
keys_frozen
423
API key activity for the account has been frozen by an operator.
What to do: Contact support and include the request id from the error response.
Request validation
The request body or path is malformed. These are client-side fixes; retrying unchanged will fail again.
invalid_json
400
The request body could not be parsed as JSON.
What to do: Validate the body before sending; check quoting and escaping in shell scripts.
invalid_request
400
A required field is missing or has the wrong shape. The error's param field points at the offending input.
What to do: Fix the field named in param and resend.
unsupported_parameter
400
The request includes a sampling parameter the chat lane cannot honor faithfully. It is rejected instead of silently ignored.
What to do: Remove the parameter named in param from the request.
payload_too_large
413
The request body exceeds the upload limit.
What to do: Reduce the request size, for example by trimming conversation history or splitting uploads.
model_not_found
404
The requested model alias does not resolve. Details include valid model examples. Ids are case-insensitive and tolerate spacing, for example GPT-5.5X High resolves to gpt-5.5-xhigh.
What to do: Use a canonical id from /docs/models or GET /v1/models.
route_not_found
404
The path is not part of the public API.
What to do: Check that the client's base URL is the /v1 endpoint from your dashboard and ends at /v1, not at a specific completion route.
Quota and balance
Subscription quota or metered balance cannot cover the request. Details carry the exact numbers: used, remaining, and reset times.
quota_exhausted
402
The weekly subscription quota is fully used. Details include resetAt.
What to do: Wait for the weekly reset shown in details, or upgrade the plan.
quota_insufficient_for_input
402
The estimated input alone does not fit in the remaining weekly quota.
What to do: Send a smaller input, or wait for the weekly reset.
quota_insufficient_for_request
402
The combined input and output reservation does not fit in the remaining weekly quota.
What to do: Reduce the request size or max output, or wait for the weekly reset.
balance_required
402
A metered API request costs more than the remaining account balance. Details include the billable amount and available balance.
What to do: Top up the API balance from the dashboard.
key_spend_cap_reached
402
This key's configured spend cap would be exceeded by the request.
What to do: Raise the cap in the dashboard or use a key with more headroom.
quota_not_configured
500
The subscription plan has no weekly quota configured. This is a service-side configuration problem, not a client mistake.
What to do: Contact support with the request id.
Rate limits
Every rate-limit response carries a Retry-After header. Honor it and back off instead of retrying immediately.
rpm_limit_reached
429
Too many requests per minute for this key.
What to do: Wait for the Retry-After interval, then resume. Spread bursts across the minute window.
distributed_rpm_limit_reached
429
The same per-key requests-per-minute limit, enforced across all serving instances. Details include the reset time.
What to do: Same recovery: honor Retry-After and pace requests.
tpm_limit_reached
429
Too many tokens per minute for this key, counting both committed usage and in-flight reservations.
What to do: Wait for the minute window to roll, or reduce request and output sizes.
active_stream_key_limit_reached
429
Too many live streaming responses are open for this API key.
What to do: Let running streams finish before opening new ones, or split traffic across keys.
active_stream_account_limit_reached
429
Too many live streaming responses are open across the whole account.
What to do: Let running streams finish, or reduce parallel agent sessions.
concurrency_limit_reached
429
Too many concurrent in-flight requests for this account.
What to do: Honor Retry-After and queue requests client-side instead of firing them in parallel.
upstream_at_capacity
429
Overall serving capacity is temporarily full. This is not your account's concurrency; the response carries a longer Retry-After.
What to do: Back off for the Retry-After interval and retry. If it persists, contact support with the request id.
Service and streaming
The request was valid but the service could not complete it. These are generally safe to retry with backoff.
upstream_timeout
504
Routing timed out before the model produced a response.
What to do: Retry. If it repeats, contact support with the request id.
upstream_unavailable
503
Serving capacity is temporarily unavailable for this request.
What to do: Retry with exponential backoff.
upstream_empty_response
502
The model route returned an empty response.
What to do: Retry the request once; escalate with the request id if it repeats.
upstream_error
502
An unclassified upstream failure. Unlike capacity errors, this is not a retry hint in disguise.
What to do: Retry once; if it persists, contact support with the request id.
bridge_unreachable
502
The gateway could not reach its internal routing service.
What to do: Retry with backoff; include the request id when reporting.
bridge_invalid_response
502
The internal routing service answered with an unusable payload.
What to do: Retry; include the request id when reporting.
stream_interrupted
SSE event
A streaming response opened successfully and then failed mid-flight. Because the HTTP status was already sent, the error arrives as an in-stream event and usage is settled as partial.
What to do: Treat the received tokens as partial output and retry the request.
internal_error
500
An unexpected gateway failure that did not map to any code above.
What to do: Retry once; if it persists, contact support with the request id.
Diagnose
Check a key without spending quota.
The diagnostics echo route validates auth, key state, account state, and model access without reserving quota or billing usage.
Diagnostic echo
Run this first when a client reports authentication or model-access errors.
curl https://api.lumaos.cloud/v1/diagnostics/echo \
-H "Authorization: Bearer $LUMA_CLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "gpt-5.5-medium" }'Reading the result
The echo route fails with the same codes as real traffic.
A successful echo means authentication, key state, account state, and model access are all healthy; remaining failures on real requests are quota, rate-limit, or service conditions from the catalog above.
A failing echo returns the exact catalog code, so you can fix the key or model configuration before sending billable traffic.
