Errors & Rate Limits

Every error shape and limit, documented

The error envelope

Every gateway error uses the same shape:

1{"error": {"message": "...", "type": "invalid_request_error", "param": null, "code": "..."}}

type is always the literal invalid_request_error — it does not vary by error. Branch on code, not type.

Upstream provider errors — 4xx or 5xx responses from the model provider itself, rather than from admission — are passed through verbatim and may not match this envelope.

Error codes

HTTPcodeWhen
400invalid_requestUnsupported or invalid parameter, bad JSON, wrong output-limit field for the model, context overflow
401authentication_errorMissing or malformed Authorization header
401invalid_api_keyKey unknown or revoked
402insufficient_creditNot enough credit to reserve the request’s maximum possible cost
404model_not_foundUnknown model or contract slug
404receipt_not_foundUnknown receipt ID on GET /v1/receipts/{receipt_id}
409request_conflictRequest lifecycle conflict; safe to retry
413request_too_largeRequest body over the size limit
429rate_limit_exceededPer-key requests-per-minute limit exceeded
502routing_errorUpstream connect or finalize failure
503service_unavailableTemporary platform condition
504request_timeoutRequest exceeded the ~230-second deadline

Retry guidance

  • Retryable: 409, 429, 502, 503, 504. For 429, wait the number of seconds named in the message before retrying. For the others, use exponential backoff.
  • Not retryable: 400, 401, 402, 404. Retrying without changing the request just reproduces the same error — fix the request (or, for 402, add credit) first.

Rate limits

Rate limiting is per API key, over a fixed 60-second window. During beta the default is 60 requests per minute per key. This value is operator-adjustable at runtime and can change without notice or a deploy.

A rate-limited request returns 429 with a body like this:

1{"error": {"message": "Rate limit exceeded. Retry after 12 seconds.", "type": "invalid_request_error", "param": null, "code": "rate_limit_exceeded"}}

There’s no retry-after header on gateway-generated 429s — the wait time is only in the message string. Parse it from there.

Need more throughput than the default allows? Email support@singularityapi.dev.