> ## Documentation Index
> Fetch the complete documentation index at: https://gomodel-feat-cache-economic-optimization.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Anthropic Messages API

> Accept Anthropic-style /v1/messages requests in GoModel and route them to any configured provider, with budgets, failover, and usage tracking applied.

## Overview

GoModel accepts the **Anthropic Messages API** request dialect at `POST /v1/messages`,
in addition to its OpenAI-compatible API. Clients and SDKs that speak the Anthropic
format can point at GoModel unchanged.

The request is translated to GoModel's canonical chat type at ingress and runs through
the same pipeline as `/v1/chat/completions` — so virtual models, workflow policy,
budgets, failover, the response cache, usage/cost tracking, and audit logging all
apply. Because every provider implements chat completion, an Anthropic-format request
can be routed to **any** configured provider (OpenAI, Gemini, Bedrock, and others),
not only Anthropic.

This differs from the [passthrough API](/features/passthrough-api): `/p/anthropic/v1/messages`
forwards bytes verbatim to the Anthropic upstream only, while the managed `/v1/messages`
endpoint routes anywhere and is fully managed.

## Supported endpoints

| Endpoint                                | Behavior                                                                                                                                                                                                        |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /v1/messages`                     | Creates a message through translated model routing. Supports streaming (`stream: true`) with Anthropic-format SSE events.                                                                                       |
| `POST /v1/messages/count_tokens`        | Returns a heuristic input token estimate.                                                                                                                                                                       |
| `GET /v1/models`                        | Returns the catalog in the Anthropic list shape (`type: "model"`, `display_name`, `created_at`) when the request carries the `anthropic-version` header the Anthropic SDKs always send; OpenAI shape otherwise. |
| `POST /v1/messages/batches`             | Creates a Message Batch. Inline `requests[].params` are translated per item, so a batch can target any provider with native batch support (Anthropic, OpenAI, …), not only Anthropic.                           |
| `GET /v1/messages/batches`              | Lists batches (`limit`, `after_id`).                                                                                                                                                                            |
| `GET /v1/messages/batches/{id}`         | Retrieves a batch (`processing_status`, `request_counts`, `results_url` once ended).                                                                                                                            |
| `POST /v1/messages/batches/{id}/cancel` | Cancels a running batch.                                                                                                                                                                                        |
| `DELETE /v1/messages/batches/{id}`      | Deletes an ended batch. Deleted upstream too when the provider's batch API supports it (Anthropic); otherwise removed from the gateway only.                                                                    |
| `GET /v1/messages/batches/{id}/results` | Streams results as JSONL. Successful items are returned in the Anthropic Messages shape regardless of the provider that served them.                                                                            |

## Message Batches

`/v1/messages/batches` shares the gateway's native-batch pipeline with the
OpenAI-compatible `/v1/batches` route — the two are dialect views of the same
resource. Batch IDs are interchangeable across the two dialects (`msgbatch_<uuid>`
here, `batch_<uuid>` there). All requests in one batch must resolve to a single
provider; per-item `custom_id` values are required and must be unique.

Providers whose batch API is file-based (OpenAI-compatible) receive inline
requests as an automatically uploaded JSONL input file. `request_counts` maps the
provider's aggregate counts: while a batch runs, unfinished requests are reported
as `processing`; once it ends, any remainder is attributed by the batch outcome
(`canceled`, `expired`, or `errored`).

```python theme={null}
batch = client.messages.batches.create(requests=[
    {"custom_id": "q1", "params": {"model": "openai/gpt-4o-mini", "max_tokens": 64,
        "messages": [{"role": "user", "content": "What is 2+3?"}]}},
])
# poll client.messages.batches.retrieve(batch.id) until "ended", then:
for entry in client.messages.batches.results(batch.id):
    print(entry.custom_id, entry.result.type)
```

## Authentication

Both credential styles work, so the official Anthropic SDKs are drop-in:

* `Authorization: Bearer <key>` — GoModel's primary scheme.
* `x-api-key: <key>` — the Anthropic-native header, accepted as a fallback when no
  `Authorization` header is present.

```python theme={null}
import anthropic

client = anthropic.Anthropic(
    api_key="<your GoModel key>",       # sent as x-api-key — works as-is
    base_url="https://your-gateway",
)
client.messages.create(
    model="openai/gpt-4o-mini",          # any configured provider's model
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello"}],
)
```

## Example

```bash theme={null}
curl https://your-gateway/v1/messages \
  -H "Authorization: Bearer $GOMODEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 256,
    "system": "Be concise.",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
```

The response uses the Anthropic Messages shape (`type: "message"`, `content` blocks,
`stop_reason`, `usage`). Errors use the Anthropic error envelope
(`{"type": "error", "error": {...}}`). `max_tokens` is required, as in the Anthropic API.

Streaming responses emit the Anthropic SSE event sequence (`message_start`,
`content_block_start`/`content_block_delta`/`content_block_stop`, `message_delta`,
`message_stop`).

## Cost tracking and audit logs

`/v1/messages` requests are tracked and audited exactly like the OpenAI-compatible
routes. Cost is computed from the actual provider that served the request, and usage
is recorded under the `/v1/messages` endpoint so it can be filtered in the dashboard.

## Limitations

`/v1/messages` translates through GoModel's canonical chat type. Anthropic-specific
features that have no canonical equivalent are not preserved end to end:

* **`cache_control`** is preserved on the request, system/content blocks,
  custom tools, and tool-use/tool-result history when routed to Anthropic.
* **Extended-thinking signatures** and `thinking` blocks on input messages are dropped.
* **Server/built-in tools** (web search, code execution, …) are rejected with a clear
  `400`; only custom tools (`type` absent or `"custom"`) translate.
* **`top_k`** is dropped — it has no portable OpenAI-compatible equivalent, and
  OpenAI-family providers reject unknown request fields. `temperature` and `top_p`
  are forwarded.
* **`document` and other non-text/image content blocks** are rejected with a clear
  `400` error rather than silently dropped.
* **`stop_sequences`** are honored on every provider. Providers that report the
  matched sequence natively (Anthropic) get the full contract back:
  `stop_reason: "stop_sequence"` plus the `stop_sequence` value. OpenAI-family
  providers conflate stop-parameter hits with natural stops in `finish_reason`,
  so completions there report `stop_reason: "end_turn"` (output is still truncated
  correctly).
* **`count_tokens`** returns a provider-agnostic heuristic estimate (≈ characters / 4),
  not a tokenizer-exact count. Use it for budgeting and UX sizing, not hard
  context-limit decisions. The same estimate seeds `usage.input_tokens` in the
  streaming `message_start` event; the authoritative counts arrive in the final
  `message_delta` event, which SDK accumulators prefer.

For byte-exact Anthropic fidelity beyond the supported cache controls, use the
`/p/anthropic/v1/messages` passthrough route instead.

See [ADR-0007](https://github.com/ENTERPILOT/GoModel/blob/main/docs/adr/0007-anthropic-messages-ingress.md)
for the design rationale and tradeoffs.
