Sign in

API reference · Anthropic

Create a message (earlier spelling)

POST /anthropic/v1/messages

Base URL https://api.recovea.ai

The earlier spelling of /v1/messages. The gateway strips /anthropic and forwards the rest to Anthropic, and the call is metered as the same endpoint. It keeps working; new integrations point an Anthropic client at the bare host instead.

Authentication

A Recovea key, in either header. The gateway removes it before the request is forwarded.

HeaderDescription
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.

Request headers

HeaderDescription
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

Required, application/json

Anthropic's Messages request, forwarded as sent and never modified.

FieldDescription
model string optional passthrough

Forwarded as sent. The model that served the call is read from the response, not from here.

messages array of any optional passthrough

Forwarded as sent and never read.

max_tokens integer optional passthrough

Forwarded as sent.

stream boolean optional passthrough

Forwarded as sent. A streamed message reports usage in message_start and message_delta, which are 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.

HeaderDescription
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.

FieldDescription
model string optional read

Read from a bounded copy of the response to record the call.

stop_reason string optional read

Read from a bounded copy of the response to record the call.

usage object optional read

Provider-reported token counts, read to record the call. Never estimated.

usage.input_tokens integer optional read

Read from a bounded copy of the response to record the call.

usage.output_tokens integer optional read

Read from a bounded copy of the response to record the call.

usage.cache_read_input_tokens integer optional read

Read from a bounded copy of the response to record the call.

usage.cache_creation_input_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.

HeaderDescription
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.

A malformed or missing x-recovea-run-id
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 byerror.code and error.message
A malformed or missing x-recovea-run-idinvalid_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-budgetinvalid_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-ttlinvalid_run_ttl x-recovea-run-ttl must be a positive whole number of seconds.
A run-budget grant that is refusedinvalid_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.

HeaderDescription
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.

An unknown, revoked or missing key
HTTP/1.1 401 Unauthorized

{
  "error": {
    "message": "Invalid API key.",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_api_key"
  }
}
Refused byerror.code and error.message
An unknown, revoked or missing keyinvalid_api_key Invalid API key.
No provider key connectedprovider_key_missing No Anthropic key is connected for this workspace.
The provider key cannot be read right nowprovider_key_unavailable The Anthropic 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.

HeaderDescription
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.

The organization's cap on the month window
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 byerror.code and error.message
The organization's cap on the month windowbudget_exceeded Monthly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the day windowbudget_exceeded Daily budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the week windowbudget_exceeded Weekly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the year windowbudget_exceeded Yearly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the lifetime windowbudget_exceeded Lifetime budget reached. This budget does not reset; raise the cap to continue.
A key's cap on the day windowbudget_exceeded Daily budget reached for this API key. Traffic resumes at reset, or raise the cap.
A key's cap on the week windowbudget_exceeded Weekly budget reached for this API key. Traffic resumes at reset, or raise the cap.
A key's cap on the month windowbudget_exceeded Monthly budget reached for this API key. Traffic resumes at reset, or raise the cap.
A key's cap on the year windowbudget_exceeded Yearly budget reached for this API key. Traffic resumes at reset, or raise the cap.
A key's cap on the lifetime windowbudget_exceeded Lifetime budget reached for this API key. This budget does not reset; raise the cap to continue.
A run over its own budgetbudget_exceeded Run budget reached. This run is stopped for good; start a new run to continue.
A run past its time limitrun_expired This run's time limit has passed. Start a new run to continue.
A run that was closedrun_closed This run was closed. Start a new run to continue.
No concurrent run budget leftrun_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 zerorun_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 canrun_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.

HeaderDescription
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.

The rate limit
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 byerror.code and error.message
The rate limitrate_limit_exceeded Rate limit reached for this workspace.
The organization's cap on the day window, pause modebudget_exceeded Daily budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the week window, pause modebudget_exceeded Weekly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the month window, pause modebudget_exceeded Monthly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the year window, pause modebudget_exceeded Yearly budget reached. Traffic resumes at reset, or raise the cap.
The organization's cap on the lifetime window, pause modebudget_exceeded Lifetime budget reached. This budget does not reset; raise the cap to continue.
A key's cap on the day window, pause modebudget_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 modebudget_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 modebudget_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 modebudget_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 modebudget_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.

HeaderDescription
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.

FieldDescription
error object required
error.message string required
error.type string required
error.param string or null required
error.code string required
The destination could not be reached
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.

HeaderDescription
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.

The organization's cap on the month window
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 byerror.code and error.message
The organization's cap on the month windowbudget_unverifiable Monthly spend cannot be confirmed right now. Retry in a moment.
The organization's cap on the day windowbudget_unverifiable Daily spend cannot be confirmed right now. Retry in a moment.
The organization's cap on the week windowbudget_unverifiable Weekly spend cannot be confirmed right now. Retry in a moment.
The organization's cap on the year windowbudget_unverifiable Yearly spend cannot be confirmed right now. Retry in a moment.
The organization's cap on the lifetime windowbudget_unverifiable Lifetime spend cannot be confirmed right now. Retry in a moment.
A key's cap on the day windowbudget_unverifiable Daily spend for this API key cannot be confirmed right now. Retry in a moment.
A key's cap on the week windowbudget_unverifiable Weekly spend for this API key cannot be confirmed right now. Retry in a moment.
A key's cap on the month windowbudget_unverifiable Monthly spend for this API key cannot be confirmed right now. Retry in a moment.
A key's cap on the year windowbudget_unverifiable Yearly spend for this API key cannot be confirmed right now. Retry in a moment.
A key's cap on the lifetime windowbudget_unverifiable Lifetime spend for this API key cannot be confirmed right now. Retry in a moment.
A run over its own budgetbudget_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.

HeaderDescription
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.