Reference
Errors
Stable codes, and what each one means.
Every failure carries a machine-readable code and an explicit HTTP status. Client-facing codes are append-only, one never changes meaning. The body is shaped for the protocol you called. an OpenAI client reads error.message and error.type as it always has. and the code is ours.
{ "error": { "message": "Wallet balance is below the minimum required for this request.",
"type": "insufficient_quota", "code": "insufficient_credit", "param": null } }Gateway
What a call to <application>.gw.ourseams.com can return.
| Code | Status | Meaning |
|---|---|---|
unknown_model | 400 | No model by that name is available on this key. |
unsupported_parameter | 400 | The request used a parameter this endpoint does not support. |
protocol_translation_failed | 400 | The request could not be translated for the model provider. |
no_capable_model | 400 | No model behind this router can serve this request. |
invalid_api_key | 401 | The API key is not valid. |
revoked_api_key | 401 | This API key has been revoked. Mint a new one. |
expired_api_key | 401 | This API key has expired. Mint a new one. |
insufficient_credit | 402 | Wallet balance is below the minimum required for this request. |
quota_exhausted | 402 | The included quota for this period is used up. |
on_demand_limit_reached | 402 | The on-demand spend limit for this period has been reached. |
subscription_past_due | 402 | The subscription is past due. Update the payment method to continue. |
spend_limit_exceeded | 402 | The spend limit for this request was reached. |
key_spend_limit_exceeded | 402 | The spend limit for this key was reached. |
bundle_spend_limit_exceeded | 402 | The spend limit for this bundle was reached. |
outcome_limit_exceeded | 402 | The budget for this unit of work was reached. |
balance_frozen | 402 | This wallet is frozen. Ask whoever issued this key to reopen it. |
model_not_in_bundle | 403 | That model is not included in this key's bundle. |
outcome_owner_mismatch | 403 | This outcome belongs to another end user. |
bundle_archived | 403 | The bundle behind this key has been archived. |
model_disabled | 403 | That model is turned off. Ask whoever issued this key to enable it. |
customer_suspended | 403 | This account is suspended. |
unknown_customer | 404 | No customer is served at this host. |
unknown_application | 404 | No application is served at this host. |
usage_unmeasurable | 500 | Usage could not be measured, so nothing was billed. |
gateway_error | 500 | The gateway could not complete the request. |
provider_error | 502 | The model provider returned an error. |
provider_unavailable | 503 | The model provider is unavailable. |
no_healthy_provider | 503 | No healthy provider is available for this model. |
request_timeout | 503 | The request exceeded its time budget. |
ttfb_timeout | 503 | The provider did not send a first token in time. |
stream_idle_timeout | 503 | The stream stalled and was closed. |
The three key codes are distinct on purpose: revoked and expired tell the developer to mint a new key, invalid tells them the key was never ours.
usage_unmeasurable is a 500 on purpose. We treat it as an outage rather than bill a guess.
Control plane
What a call to api.ourseams.com can return. These are the codes to branch on when you are provisioning: creating applications, bundles, end users and keys.
| Code | Status | Meaning |
|---|---|---|
unsupported_parameter | 400 | The request used a parameter this endpoint does not support. |
key_code_unavailable | 400 | That key code is not available. Choose another. |
authorization_pending | 400 | This sign-in is waiting for approval. |
invalid_device_code | 400 | This sign-in request is not valid. |
expired_device_code | 400 | This sign-in request has expired. |
invalid_api_key | 401 | The API key is not valid. |
revoked_api_key | 401 | This API key has been revoked. Mint a new one. |
expired_api_key | 401 | This API key has expired. Mint a new one. |
subscription_past_due | 402 | The subscription is past due. Update the payment method to continue. |
bundle_archived | 403 | The bundle behind this key has been archived. |
customer_suspended | 403 | This account is suspended. |
insufficient_scope | 403 | This API key does not carry the scope this request needs. |
unknown_customer | 404 | No customer is served at this host. |
unknown_application | 404 | No application is served at this host. |
unknown_resource | 404 | This account has no such bundle, end user, key or provider account. |
not_subscribed | 404 | This end user is not on a plan, so there is no spending to show. |
gateway_error | 500 | The gateway could not complete the request. |
not_implemented | 501 | This endpoint is not available yet. |
Creating something that already exists
There is no conflict code and no bundle_exists code, and no route answers 409. A create that collides returns 400 with the code below, so branch on the code rather than the status.
| Call | Already there | Code |
|---|---|---|
PUT /v1/apps/{slug} | the slug is taken, reserved, or malformed | key_code_unavailable |
PUT /v1/bundles/{slug} | refuses | unsupported_parameter |
PUT /v1/models/{name} | replaces the sources; no error | — |
POST /v1/keys | mints another key for that end user; no error | — |
PUT /v1/team/{email} | resends to that address; no error | — |
POST /v1/keys is not idempotent. Calling it twice for one end user leaves them holding two keys, and keys show <endUserId> then refuses as ambiguous. Keep the id or the keyPrefix mint returns.