> ## Documentation Index
> Fetch the complete documentation index at: https://docs.recovea.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Any other OpenAI path

ANY `/v1/{path}`

Base URL `https://api.recovea.ai/v1`. Any method is forwarded on this path; it is documented once, under POST.

```http
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"
  }
}
```

Every other path under `/v1` is forwarded to OpenAI as sent, under any method, so an endpoint works the day the provider ships it; there is no allowlist. The exceptions are the paths this document lists separately, `/v1/messages` and everything under it (Anthropic's), and one path the gateway reserves for itself. `{path}` may span several segments and is forwarded with its query string.

## 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 `Authorization: Bearer rcv_live_…`, the form OpenAI clients send. Unknown, revoked and missing keys all receive the same 401 `invalid_api_key`. |
| `x-api-key` string one of the two | The same Recovea key in `x-api-key`, the form Anthropic clients send. Read when no `Authorization: Bearer` is present. |

## Path parameters

| Parameter | Description |
| --- | --- |
| `path` string required | The rest of the path, forwarded as sent. It may span several segments, or be empty; the query string travels with it. |

## 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 `x-recovea-run-*` header is sent. Removed before the request is forwarded, like every `x-recovea-run-*` header. Example: `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 `x-recovea-run-budget-effective`. Example: `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 `run_expired`. Example: `3600` |
| `x-recovea-run-grant` string optional | A signed run-budget grant (an `rbg1` token), needed for a run budget above what a key may declare on its own. A grant that is not accepted refuses with `invalid_run_grant`, whatever the reason. Example: `rbg1.…` |

## Request body

Optional, `*/*`

Forwarded as sent, whatever its type.

## 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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |
| `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; `run` is the life of one run. Rides wherever `x-recovea-budget-scope` does and names the same cap. |
| `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. |

### 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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |
| `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; `run` is the life of one run. Rides wherever `x-recovea-budget-scope` does and names the same cap. |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |
| `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; `run` is the life of one run. Rides wherever `x-recovea-budget-scope` does and names the same cap. |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |

| Field | Description |
| --- | --- |
| `error` object required |  |
| `error.message` string required |  |
| `error.type` string required |  |
| `error.param` string or null required |  |
| `error.code` string required |  |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a 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 `req_` id the gateway fills in; it is not the same value as `x-recovea-request-id`. |
| `retry-after` 1 required | Always `1`: a floor, not a promise. The condition clears when a fresh checkpoint lands. |
| `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; `run` is the life of one run. Rides wherever `x-recovea-budget-scope` does and names the same cap. |

```http
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: `req_` and 32 hex characters. On every response the gateway sends, forwarded or refused. Quote it when you ask about a request. |

Generated from openapi.json, which the gateway renders from `relay/src/proxy.rs` at commit `4b1805b24ff8`.
