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

# For coding agents

The five questions an agent asks of an AI gateway, answered for Recovea: cost tracking, budgets, observability, caching and fallback.

## The five answers

| Question | Answer |
| --- | --- |
| Cost tracking | Yes. Every call through the gateway is metered as it returns. |
| Budgets | Yes. An armed cap refuses with a `402` before your provider is contacted. |
| Observability | Receipts. Every metered call is written to a hash-chained ledger. |
| Caching | No. The gateway keeps no prompt and no reply, so it has nothing to answer from. |
| Fallback | No. A request goes to the provider its path names; fall back in your own code. |

## Cost tracking: yes

Change the base URL and keep your SDK, your models and your request shape; the [Quickstart](https://docs.recovea.ai/quickstart/) walks one request through. The first call is metered as it returns: cost, tokens, model and route land in the platform, and a receipt is written into the hash-chained ledger.

| Surface | Base URL |
| --- | --- |
| OpenAI-compatible | `https://api.recovea.ai/v1` |
| Anthropic `/v1/messages` | `https://api.recovea.ai` |
| An upstream you declared | `https://api.recovea.ai/upstream/v1` |

A receipt covers what routes through the gateway. Spend outside the path is not metered here.

## Budgets: yes, and how they refuse

An armed cap refuses the next request with a `402` before your provider is contacted, so the refused call costs nothing. The body has one shape for every cap; only the sentence changes, naming the window and, for a key's cap, the key. This is the organization's monthly 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"
  }
}
```

Branch on the status, the `type` and the `code`, never on the sentence.

A cap that cannot confirm live spend answers `503` with `Retry-After: 1` and the code `budget_unverifiable`. It is not an overspend, and it clears on its own: retry the same call after the second the header names.

The whole refusal contract, every window's sentence included, is on [Cap](https://docs.recovea.ai/products/cap/#what-comes-back); where a cap is set, and who may change it, is [Where a cap is set](https://docs.recovea.ai/products/caps/). What fails open and what fails closed: [Fail-open and fail-closed](https://docs.recovea.ai/concepts/fail-open-vs-fail-closed/).

## Observability: receipts

Every proxied response carries `x-recovea-request-id`, Recovea's own id for the request, and the receipt for that call carries the same id. Receipts are rows in a ledger where each row carries the hash of the row before it: recipe `recovea-chain-v1`, SHA-256 over fourteen fields joined by U+001F, the first row chained to a genesis of 64 zeros. Change one row and every hash after it breaks. [Prove](https://docs.recovea.ai/products/prove/) is the receipt and its export; [The hash-chained ledger](https://docs.recovea.ai/concepts/hash-chained-ledger/#re-derive-one-receipt) re-derives one by hand.

## Caching: no

The gateway forwards each request to your provider and meters the answer as it returns. It keeps no copy of a reply to serve again: the metering schema has no field that can hold a prompt or a reply. Tokens your provider served from its own cache are metered as `tokens_cached`, one of the fourteen fields a receipt is hashed over. What the record holds, field by field: [Content-free by schema](https://docs.recovea.ai/concepts/content-free-by-schema/).

## Fallback: no, and the code to write instead

The gateway sends a request to the provider its path names: `/v1` to the OpenAI-compatible provider you connected, `/v1/messages` on the bare host to Anthropic, `/upstream/v1` to the upstream you declared. It does not retry a failed request against another provider.

If your application wants a second provider when the first one fails, write it in your own code, and keep the refusals out of it. A cap decides on what it bounds, never on the destination, so the key a cap refuses on one surface is refused on all three; a `503` with `budget_unverifiable` is the gateway asking for a retry of the same call.

```python
import os

from anthropic import Anthropic
from openai import APIConnectionError, APIStatusError, OpenAI

KEY = os.environ["RECOVEA_API_KEY"]
primary = OpenAI(api_key=KEY, base_url="https://api.recovea.ai/v1")
secondary = Anthropic(api_key=KEY, base_url="https://api.recovea.ai")


def ask(prompt: str) -> str:
    try:
        reply = primary.chat.completions.create(
            model=os.environ["PRIMARY_MODEL"],
            messages=[{"role": "user", "content": prompt}],
        )
        return reply.choices[0].message.content
    except APIStatusError as error:
        # 402 is a cap refusing and 503 is a cap asking for a retry: neither
        # is a provider failure, and a second provider would get the same answer.
        if error.status_code in (402, 503) or error.status_code < 500:
            raise
    except APIConnectionError:
        pass

    reply = secondary.messages.create(
        model=os.environ["SECONDARY_MODEL"],
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}],
    )
    return reply.content[0].text
```

## Where the rest is

- [Quickstart](https://docs.recovea.ai/quickstart/): one base URL change, one request, and what comes back.
- [Cap](https://docs.recovea.ai/products/cap/): what a cap is, what the request carries, and every answer it sends.
- [API reference](https://docs.recovea.ai/reference/): the gateway's operations, headers and refusals, generated from `openapi.json`.
- [The Baseline package](https://docs.recovea.ai/reference/passive-tap/): the passive tap's endpoint, its event and what the server answers.
- `/llms.txt` is the index of every page here, and `/llms-full.txt` is every page as Markdown in one file.
