OpenAI's legacy completions endpoint, forwarded to OpenAI as sent.
Authentication
A Recovea key, in either header. The gateway removes it before the request is forwarded.
| Header | Description |
|---|---|
Authorization Bearer rcv_live_… one of the two | A Recovea key in |
x-api-key string one of the two | The same Recovea key in |
Request headers
| Header | Description |
|---|---|
x-recovea-tags string optional | Attribution labels for this call's reading, comma-separated. Opaque to the gateway: split on commas and trimmed, never interpreted. Several header lines are read as one list. Up to 32 labels of up to 128 characters are kept; the rest are dropped from the reading and counted. Removed before the request is forwarded. Example:checkout,team:payments |
x-recovea-project string optional | One opaque project label for this call's reading. Removed before the request is forwarded. Example:checkout |
x-recovea-run-id string optional | The run this request belongs to (Breaker), chosen by you: 1 to 128 visible ASCII characters. Required whenever any other nightly-report-7 |
x-recovea-run-budget string optional | The run's budget in US dollars: a positive decimal with at most 6 decimal places. It binds for the life of the run. Sent again on a live run, a smaller figure tightens the budget and a larger one is ignored. The budget that binds comes back in 5.00 |
x-recovea-run-ttl string optional | The run's time limit in whole seconds, fixed by the run's first request; sending it again does not extend it. Past it, the run refuses with 3600 |
x-recovea-run-grant string optional | A signed run-budget grant (an rbg1.… |
Request body
OpenAI's legacy completion request, forwarded as sent.
| Field | Description |
|---|---|
model string optional passthrough | Forwarded as sent. The model that served the call is read from the response, not from here. |
prompt any optional passthrough | Forwarded as sent and never read. |
Responses
200 OK
The provider's response, returned byte for byte, with x-recovea-request-id added and, under an armed cap or a run budget, the headers below.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
x-recovea-budget-scope "organization" | "key" | "run" optional | Which kind of cap bound this request, or refused it. On a response served under an armed cap it names the tightest one; on a refusal it names the cap that refused. Absent when no armed cap bound the request, and on refusals that read no cap. |
x-recovea-budget-window "run" | "day" | "week" | "month" | "year" | "lifetime" optional | The clock that cap runs on. Calendar windows are UTC; |
x-recovea-run-budget-effective string optional | The run budget that binds, in US dollars at 6 decimals. On a response served under a run that has a budget. Example:0.005000 |
x-recovea-run-clamp-reason "policy_max" | "grant_max" | "workspace_ceiling" | "exposure_headroom" optional | Present only when the declared run budget was lowered, naming the bound that lowered it. |
| Field | Description |
|---|---|
model string optional read | Read from a bounded copy of the response to record the call. |
choices array of object optional read | |
choices[].finish_reason string optional read | The first choice's finish reason is read to record the call. |
usage object optional read | Provider-reported token counts, read to record the call. Never estimated. |
usage.prompt_tokens integer optional read | Read from a bounded copy of the response to record the call. |
usage.completion_tokens integer optional read | Read from a bounded copy of the response to record the call. |
usage.prompt_tokens_details object optional | |
usage.prompt_tokens_details.cached_tokens integer optional read | Read from a bounded copy of the response to record the call. |
usage.completion_tokens_details object optional | |
usage.completion_tokens_details.reasoning_tokens integer optional read | Read from a bounded copy of the response to record the call. |
400 Bad Request
A malformed x-recovea-run-* header, named in the message. Nothing was forwarded.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
HTTP/1.1 400 Bad Request
{
"error": {
"message": "x-recovea-run-id must be 1 to 128 visible ASCII characters, and is required whenever any x-recovea-run-* header is sent.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_run_id"
}
}| Refused by | error.code and error.message |
|---|---|
| A malformed or missing x-recovea-run-id | invalid_run_id x-recovea-run-id must be 1 to 128 visible ASCII characters, and is required whenever any x-recovea-run-* header is sent. |
| An unparseable x-recovea-run-budget | invalid_run_budget x-recovea-run-budget must be a positive decimal amount of US dollars with at most six decimal places, for example 5.00. |
| An unparseable x-recovea-run-ttl | invalid_run_ttl x-recovea-run-ttl must be a positive whole number of seconds. |
| A run-budget grant that is refused | invalid_run_grant x-recovea-run-grant did not verify. Mint a new run-budget grant for this workspace and run. |
401 Unauthorized
invalid_api_key: the Recovea key is unknown, revoked or missing, and all three receive this one body. provider_key_missing: no key for this destination is connected to your organization. provider_key_unavailable: one is connected but cannot be read right now; retry shortly.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
HTTP/1.1 401 Unauthorized
{
"error": {
"message": "Invalid API key.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}| Refused by | error.code and error.message |
|---|---|
| An unknown, revoked or missing key | invalid_api_key Invalid API key. |
| No provider key connected | provider_key_missing No OpenAI key is connected for this workspace. |
| The provider key cannot be read right now | provider_key_unavailable The OpenAI key for this workspace is temporarily unavailable. Retry shortly. |
402 Payment Required
Refused before the provider was contacted: nothing was forwarded and nothing was spent. An armed cap answers budget_exceeded with type insufficient_quota, one shape for every limit; only the sentence moves, naming the window and, for a key's cap, the scope. The organization's monthly sentence is the original constant: "Monthly budget reached. Traffic resumes at reset, or raise the cap." A cap refusal carries x-recovea-budget-scope and x-recovea-budget-window and no Retry-After. A run's own refusals (run_expired, run_closed and the rest) share the status and the type, carry their own codes, and state no budget headers.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
x-recovea-budget-scope "organization" | "key" | "run" optional | Which kind of cap bound this request, or refused it. On a response served under an armed cap it names the tightest one; on a refusal it names the cap that refused. Absent when no armed cap bound the request, and on refusals that read no cap. |
x-recovea-budget-window "run" | "day" | "week" | "month" | "year" | "lifetime" optional | The clock that cap runs on. Calendar windows are UTC; |
HTTP/1.1 402 Payment Required
{
"error": {
"message": "Monthly budget reached. Traffic resumes at reset, or raise the cap.",
"type": "insufficient_quota",
"param": null,
"code": "budget_exceeded"
}
}| Refused by | error.code and error.message |
|---|---|
| The organization's cap on the month window | budget_exceeded Monthly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the day window | budget_exceeded Daily budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the week window | budget_exceeded Weekly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the year window | budget_exceeded Yearly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the lifetime window | budget_exceeded Lifetime budget reached. This budget does not reset; raise the cap to continue. |
| A key's cap on the day window | budget_exceeded Daily budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the week window | budget_exceeded Weekly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the month window | budget_exceeded Monthly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the year window | budget_exceeded Yearly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the lifetime window | budget_exceeded Lifetime budget reached for this API key. This budget does not reset; raise the cap to continue. |
| A run over its own budget | budget_exceeded Run budget reached. This run is stopped for good; start a new run to continue. |
| A run past its time limit | run_expired This run's time limit has passed. Start a new run to continue. |
| A run that was closed | run_closed This run was closed. Start a new run to continue. |
| No concurrent run budget left | run_exposure_exhausted This workspace has no concurrent run budget left. Close a finished run, or wait for one to end. |
| A run budget that resolves to zero | run_envelope_zero The run budget resolved to zero. Raise the run budget policy for this key or workspace. |
| A gateway node holding as many runs as it can | run_registry_full This gateway node is holding as many runs as it can. Retry shortly. |
429 Too Many Requests
Two refusals share this status, and error.code tells them apart. rate_limit_exceeded is the rate limit for your plan. budget_exceeded with type rate_limit_error is an armed cap in pause mode: the same sentences as the 402, and it carries x-recovea-budget-scope and x-recovea-budget-window. Both carry Retry-After. Nothing queues and nothing is forwarded.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
retry-after integer required | Whole seconds before a retry can succeed. For the rate limit, until a request fits again; for a cap in pause mode, until its window resets (a lifetime cap never resets and sends 86400, a back-off rather than a reset). |
x-recovea-budget-scope "organization" | "key" | "run" optional | Which kind of cap bound this request, or refused it. On a response served under an armed cap it names the tightest one; on a refusal it names the cap that refused. Absent when no armed cap bound the request, and on refusals that read no cap. |
x-recovea-budget-window "run" | "day" | "week" | "month" | "year" | "lifetime" optional | The clock that cap runs on. Calendar windows are UTC; |
HTTP/1.1 429 Too Many Requests
Retry-After: 1
{
"error": {
"message": "Rate limit reached for this workspace.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
}
}| Refused by | error.code and error.message |
|---|---|
| The rate limit | rate_limit_exceeded Rate limit reached for this workspace. |
| The organization's cap on the day window, pause mode | budget_exceeded Daily budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the week window, pause mode | budget_exceeded Weekly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the month window, pause mode | budget_exceeded Monthly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the year window, pause mode | budget_exceeded Yearly budget reached. Traffic resumes at reset, or raise the cap. |
| The organization's cap on the lifetime window, pause mode | budget_exceeded Lifetime budget reached. This budget does not reset; raise the cap to continue. |
| A key's cap on the day window, pause mode | budget_exceeded Daily budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the week window, pause mode | budget_exceeded Weekly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the month window, pause mode | budget_exceeded Monthly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the year window, pause mode | budget_exceeded Yearly budget reached for this API key. Traffic resumes at reset, or raise the cap. |
| A key's cap on the lifetime window, pause mode | budget_exceeded Lifetime budget reached for this API key. This budget does not reset; raise the cap to continue. |
502 Bad Gateway
The gateway could not reach the destination at all: the connection or the first byte failed. The only 5xx the gateway originates on a forwarded call. A stream that fails after its first byte ends instead; bytes already sent are not replaced.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
| Field | Description |
|---|---|
error object required | |
error.message string required | |
error.type string required | |
error.param string or null required | |
error.code string required |
HTTP/1.1 502 Bad Gateway
{
"error": {
"message": "Upstream provider unreachable.",
"type": "api_error",
"param": null,
"code": "upstream_unreachable"
}
}503 Service Unavailable
An armed cap's live spend cannot be confirmed on this node right now, so the request is refused rather than let through unprotected, and nothing is forwarded. error.code is budget_unverifiable and Retry-After is 1: the condition clears when a fresh checkpoint lands, so retry. It is not an out-of-credit answer; a spent budget answers 402.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
x-request-id string required | On a forwarded response, the provider's own request id, passed through untouched. On a response the gateway originates, a |
retry-after 1 required | Always |
x-recovea-budget-scope "organization" | "key" | "run" required | Which kind of cap bound this request, or refused it. On a response served under an armed cap it names the tightest one; on a refusal it names the cap that refused. Absent when no armed cap bound the request, and on refusals that read no cap. |
x-recovea-budget-window "run" | "day" | "week" | "month" | "year" | "lifetime" required | The clock that cap runs on. Calendar windows are UTC; |
HTTP/1.1 503 Service Unavailable
Retry-After: 1
{
"error": {
"message": "Monthly spend cannot be confirmed right now. Retry in a moment.",
"type": "insufficient_quota",
"param": null,
"code": "budget_unverifiable"
}
}| Refused by | error.code and error.message |
|---|---|
| The organization's cap on the month window | budget_unverifiable Monthly spend cannot be confirmed right now. Retry in a moment. |
| The organization's cap on the day window | budget_unverifiable Daily spend cannot be confirmed right now. Retry in a moment. |
| The organization's cap on the week window | budget_unverifiable Weekly spend cannot be confirmed right now. Retry in a moment. |
| The organization's cap on the year window | budget_unverifiable Yearly spend cannot be confirmed right now. Retry in a moment. |
| The organization's cap on the lifetime window | budget_unverifiable Lifetime spend cannot be confirmed right now. Retry in a moment. |
| A key's cap on the day window | budget_unverifiable Daily spend for this API key cannot be confirmed right now. Retry in a moment. |
| A key's cap on the week window | budget_unverifiable Weekly spend for this API key cannot be confirmed right now. Retry in a moment. |
| A key's cap on the month window | budget_unverifiable Monthly spend for this API key cannot be confirmed right now. Retry in a moment. |
| A key's cap on the year window | budget_unverifiable Yearly spend for this API key cannot be confirmed right now. Retry in a moment. |
| A key's cap on the lifetime window | budget_unverifiable Lifetime spend for this API key cannot be confirmed right now. Retry in a moment. |
| A run over its own budget | budget_unverifiable Run spend cannot be confirmed right now. Retry in a moment. |
Any other status
Any other status is the provider's own response, passed through byte for byte, error bodies included. The gateway adds x-recovea-request-id.
| Header | Description |
|---|---|
x-recovea-request-id string required | The gateway's id for this request: |
Generated from openapi.json, which the gateway renders from relay/src/proxy.rs at commit 4b1805b24ff8.