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

# Anthropic Messages API

> Use the Anthropic SDK unmodified against the Toqan Router AI Gateway with prompt caching on Claude and access to 500+ models via one base URL change.

**Use Cases**

> [accordion] Adopt the gateway without rewriting Anthropic code
>
> Keep an existing Anthropic SDK codebase and point it at **Toqan Router** with a single `base_url` change; streaming, tool use, and multimodal input keep working unchanged.

> [accordion] Cut input costs on long, stable prompts
>
> Mark the system prompt or reference documents with `cache_control` so repeat calls and follow-up turns read them from cache instead of paying full price.

> [accordion] Drive any catalog model from one client
>
> Change the `model` value to any `provider/model_id` in the **AI Gateway** catalog, from Claude to OpenAI and other providers, without swapping SDKs.

> [accordion] Apply gateway governance to Claude traffic
>
> Fallbacks, budgets, guardrails, and traces apply to every Anthropic SDK call routed through the gateway.

***

## Overview

The **AI Gateway** is a routing layer that proxies one API to 500+ models across providers, adding fallbacks, budgets, guardrails, and traces; see the [quick start](/docs/ai-gateway/get-started/introduction.md). It exposes an Anthropic-compatible endpoint at `https://router.toqan.ai/eu/v3/anthropic`. The Anthropic SDK appends `/v1/messages` to the base URL automatically, so existing Anthropic code runs against **Toqan Router** with no other changes.

Requests authenticate with a **Toqan Router** API key and run through the same pipeline as the [OpenAI-compatible API](/docs/ai-gateway/features/openai-compatible-api.md), so fallbacks, budgets, guardrails, and traces all apply. Prompt caching on Claude models is opt-in via `cache_control` breakpoints, exactly as in the native Anthropic API.

Configure fallbacks for this endpoint through [Routing Rules](/docs/ai-gateway/configuration/routing-rules.md) or Policies. The request body's `fallbacks` field is ignored. Configured fallback models disable direct Anthropic passthrough so the gateway can route between providers.

## Quick Start

**Before you start**: complete the [AI Gateway quick start](/docs/ai-gateway/get-started/introduction.md) once. It walks through creating an account at [router.toqan.ai/eu](https://router.toqan.ai/eu), connecting a provider (BYOK) with an Anthropic API key, and creating a **Toqan Router** API key. Then set the key in the environment:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export TOQAN_API_KEY="your-api-key"
```

Set the base URL to `https://router.toqan.ai/eu/v3/anthropic` and send a messages request with a **Toqan Router** API key. cURL requests use the full path shown below; SDKs set `baseURL` to `https://router.toqan.ai/eu/v3/anthropic` and the client appends `/v1/messages` automatically.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://router.toqan.ai/eu/v3/anthropic/v1/messages \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "max_tokens": 1024,
    "messages": [
      { "role": "user", "content": "Explain the AI Gateway in one paragraph." }
    ]
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: process.env.TOQAN_API_KEY,
  baseURL: "https://router.toqan.ai/eu/v3/anthropic",
});

const message = await client.messages.create({
  model: "anthropic/claude-sonnet-5",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Explain the AI Gateway in one paragraph." },
  ],
});

console.log(message.content[0].text);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import anthropic
import os

client = anthropic.Anthropic(
    api_key=os.environ.get("TOQAN_API_KEY"),
    base_url="https://router.toqan.ai/eu/v3/anthropic",
)

message = client.messages.create(
    model="anthropic/claude-sonnet-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain the AI Gateway in one paragraph."}],
)

print(message.content[0].text)
```

## Supported Endpoints

All routes are relative to the base URL `https://router.toqan.ai/eu/v3/anthropic` and mirror the Anthropic Messages API request and response formats.

| Endpoint | Description |
| - | - |
| `POST /v1/messages` | Create a message. Supports [streaming](/docs/ai-gateway/features/streaming.md), [tool use](/docs/ai-gateway/features/tool-calling.md), and [multimodal input](/docs/ai-gateway/features/multimodal.md). |
| `POST /v1/messages/count_tokens` | Count input tokens for a request without calling the model. Returns `{"input_tokens": <count>}`. Returns HTTP `400` with `invalid_request_error` when token counting is not supported for the resolved model. |
| `GET /v1/models` | List models available through the **AI Gateway**. |
| `GET /v1/models/{model_id}` | Get details for a single model. |

> [!NOTE]
>
> An unsupported token count is unavailable, not zero. Handle the `invalid_request_error` response with a client-side estimate or choose a model that supports token counting.

## Authentication

Choose whether to use the workspace's provider configuration or send an Anthropic credential with each request.

### Use a Toqan Router API key

Authenticate with the **Toqan Router** API key in either header:

* `Authorization: Bearer $TOQAN_API_KEY`
* `x-api-key: $TOQAN_API_KEY` (the header the Anthropic SDK sends by default)

The **Anthropic SDK** works unmodified: set `ANTHROPIC_API_KEY` to a **Toqan Router** key and `ANTHROPIC_BASE_URL` to `https://router.toqan.ai/eu/v3/anthropic`. Alternatively, pass the constructor parameters shown in the Quick Start (`apiKey`/`baseURL` in TypeScript, `api_key`/`base_url` in Python).

> [!NOTE]
>
> To learn more about **Toqan Router** API keys, see [API Keys](/docs/ai-gateway/configuration/api-keys.md).

### Use an Anthropic credential

Send an Anthropic API key or OAuth token through the **AI Gateway** without adding it to a workspace integration. Keep the **Toqan Router** API key in `x-toqan-api-key` and send the Anthropic credential in its own header:

| Header | Value |
| - | - |
| `x-toqan-api-key` | **Toqan Router** API key. Required to access the workspace. |
| `x-api-key` | Anthropic API key, when using API billing. |
| `Authorization` | `Bearer <ANTHROPIC_OAUTH_TOKEN>`, when using a Claude subscription token. |
| `anthropic-version` | Anthropic API version, for example `2023-06-01`. |
| `anthropic-beta` | Include the OAuth beta required by the token when using subscription authentication. **Claude Code** sends this automatically. |

Send one Anthropic credential: either `x-api-key` or `Authorization`. Use a public model served directly by Anthropic, such as `anthropic/claude-sonnet-5`. Bedrock, Vertex AI, private endpoints, and models from other providers cannot use an Anthropic credential.

> [tab] Anthropic API key
>
> Set `TOQAN_API_KEY` and `ANTHROPIC_API_KEY`, then send a request:
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
> curl https://router.toqan.ai/eu/v3/anthropic/v1/messages \
>   -H "x-toqan-api-key: $TOQAN_API_KEY" \
>   -H "x-api-key: $ANTHROPIC_API_KEY" \
>   -H "anthropic-version: 2023-06-01" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "model": "anthropic/claude-sonnet-5",
>     "max_tokens": 1024,
>     "messages": [{"role": "user", "content": "Explain prompt caching."}]
>   }'
> ```
>
> In the **Anthropic SDK**, keep the Anthropic key as `apiKey` or `api_key`, set the base URL to `https://router.toqan.ai/eu/v3/anthropic`, and add `x-toqan-api-key` through `defaultHeaders` in TypeScript or `default_headers` in Python.

> [tab] Claude subscription token
>
> Set `TOQAN_API_KEY` and `ANTHROPIC_OAUTH_TOKEN`, then send the token as a bearer credential. Include its OAuth beta header:
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
> curl https://router.toqan.ai/eu/v3/anthropic/v1/messages \
>   -H "x-toqan-api-key: $TOQAN_API_KEY" \
>   -H "Authorization: Bearer $ANTHROPIC_OAUTH_TOKEN" \
>   -H "anthropic-version: 2023-06-01" \
>   -H "anthropic-beta: oauth-2025-04-20" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "model": "anthropic/claude-sonnet-5",
>     "max_tokens": 1024,
>     "messages": [{"role": "user", "content": "Explain prompt caching."}]
>   }'
> ```
>
> For interactive use, follow the **Claude Code** setup to keep the existing Claude login. For an explicit token, run `claude setup-token` and complete the browser sign-in. See [Anthropic's token instructions](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token).

The same headers work for streaming messages and `POST /v1/messages/count_tokens`. Anthropic applies the supplied account's billing or subscription limits to the model request. **Toqan Router** records usage in [Traces](/docs/ai-studio/observability/traces.md) without charging that request as **Toqan Router**-managed model usage.

For client setup, see **Claude Code** or **Claude Desktop**.

## Model Naming

Use the `provider/model_id` format from the **AI Gateway** catalog:

* `anthropic/claude-sonnet-5` for Claude models.
* Any other provider prefix, for example `openai/gpt-5.6-sol`, routed through the same Anthropic-compatible endpoint.

`GET /v1/models` returns some models as native IDs without the provider prefix (for example `claude-sonnet-4-6`). Those IDs also resolve on this endpoint; the catalog `provider/model_id` form is unambiguous. The same catalog applies to every **AI Gateway** API, including `/v3/router` and the Responses API.

Browse every available model in [Supported Models](/docs/ai-gateway/supported-models.md).

## Gateway Features

Because requests run through the same pipeline as the router, the following **AI Gateway** features apply to Anthropic SDK calls:

* [Smart Router](/docs/ai-gateway/smart-router.md)
* [Load Balancing and Fallbacks](/docs/ai-gateway/features/load-balancing.md)
* [Retries](/docs/ai-gateway/features/retries.md)
* [Budgets](/docs/ai-gateway/budgets.md)
* [Guardrails](/docs/ai-gateway/configuration/guardrails.md)
* Traces
* [Prompt caching](/docs/ai-gateway/features/prompt-caching.md)
* [Response caching](/docs/ai-gateway/features/cache.md)

### Prompt Caching

Prompt caching is opt-in: add a `cache_control` object to a content block to mark a cache breakpoint, the end of a cacheable prefix. Breakpoints pass through unchanged on this endpoint, including multi-turn and streaming requests.

> [card] [Prompt caching](/docs/ai-gateway/features/prompt-caching.md)
>
> Supported `cache_control` values, TTLs, block types, minimum token thresholds, and usage reporting.

Cache writes and reads appear in the response `usage` as `cache_creation_input_tokens` (write) and `cache_read_input_tokens` (read), the native Anthropic shape. `cache_control` on a non-Anthropic model is ignored, not rejected.

#### Multi-turn example

Mark the system prompt with a breakpoint, then send a follow-up turn with the same prefix to read from cache. The system text below is abbreviated; use a prefix above the [provider minimum token threshold](/docs/ai-gateway/features/prompt-caching.md#minimum-token-thresholds) for the cache read to appear. The TypeScript and Python tabs reuse the client from the Quick Start.

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
# First call: writes the prefix to cache
curl -X POST https://router.toqan.ai/eu/v3/anthropic/v1/messages \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "You are a senior legal assistant. The following is our complete contract template library...",
        "cache_control": { "type": "ephemeral", "ttl": "1h" }
      }
    ],
    "messages": [
      { "role": "user", "content": "Summarize clause 7 of the NDA template." }
    ]
  }'

# Second call with the same prefix: reads from cache
curl -X POST https://router.toqan.ai/eu/v3/anthropic/v1/messages \
  -H "Authorization: Bearer $TOQAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "max_tokens": 1024,
    "system": [
      {
        "type": "text",
        "text": "You are a senior legal assistant. The following is our complete contract template library...",
        "cache_control": { "type": "ephemeral", "ttl": "1h" }
      }
    ],
    "messages": [
      { "role": "user", "content": "Summarize clause 8 of the NDA template." }
    ]
  }'
```

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Uses the client from the Quick Start above
const system = [
  {
    type: "text",
    text: "You are a senior legal assistant. The following is our complete contract template library...",
    cache_control: { type: "ephemeral", ttl: "1h" },
  },
];

// First call: writes the prefix to cache
await client.messages.create({
  model: "anthropic/claude-sonnet-5",
  max_tokens: 1024,
  system,
  messages: [
    { role: "user", content: "Summarize clause 7 of the NDA template." },
  ],
});

// Second call with the same prefix: reads from cache
const message = await client.messages.create({
  model: "anthropic/claude-sonnet-5",
  max_tokens: 1024,
  system,
  messages: [
    { role: "user", content: "Summarize clause 8 of the NDA template." },
  ],
});

console.log(message.usage.cache_read_input_tokens);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Uses the client from the Quick Start above
system = [
    {
        "type": "text",
        "text": "You are a senior legal assistant. The following is our complete contract template library...",
        "cache_control": {"type": "ephemeral", "ttl": "1h"},
    }
]

# First call: writes the prefix to cache
client.messages.create(
    model="anthropic/claude-sonnet-5",
    max_tokens=1024,
    system=system,
    messages=[{"role": "user", "content": "Summarize clause 7 of the NDA template."}],
)

# Second call with the same prefix: reads from cache
message = client.messages.create(
    model="anthropic/claude-sonnet-5",
    max_tokens=1024,
    system=system,
    messages=[{"role": "user", "content": "Summarize clause 8 of the NDA template."}],
)

print(message.usage.cache_read_input_tokens)
```

The second call sends the identical system prefix with a new user turn. When the marked prefix is above the provider minimum token threshold, the response reports `cache_read_input_tokens` greater than zero instead of paying full price for the system prompt.

#### Manual vs Automatic Prompt Caching

How prompt caching is enabled depends on the endpoint and the provider:

| Endpoint | Provider | How caching is enabled |
| - | - | - |
| Anthropic-compatible (`/v3/anthropic`) | Claude | Manual `cache_control` breakpoints on content blocks, or automatic caching with a top-level `cache_control`. Both pass through to the provider. |
| Responses API (`/v3/router/responses`) | Claude | Manual `cache_control` on the system prompt by default. Use the top-level `cache_control` parameter only when continuing with `previous_response_id`. |
| Responses API (`/v3/router/responses`) | OpenAI | Fully automatic. No request changes needed. |
| Responses API (`/v3/router/responses`) | Google Gemini 2.5+ | Automatic. Explicit caching with `cache_control` markers works on Vertex AI deployments with service-account auth; the gateway skips it on Google AI (Gemini API) when the request has a system prompt or tools, and entirely on Vertex AI Express (API-key) deployments. |

Use manual breakpoints when the request has a long stable prefix and the cache boundary matters. The Responses API's top-level `cache_control` marks the last cacheable block automatically; it does not allow multiple breakpoints, and it is the form to use with `previous_response_id`. See [Multi-turn conversations](/docs/ai-gateway/features/prompt-caching.md#multi-turn-conversations). OpenAI and Gemini 2.5+ cache automatically, so no request changes are needed; Gemini 2.5+ also supports explicit caching through `cache_control` markers on Vertex AI deployments with service-account auth, while the gateway skips it on Google AI when the request has a system prompt or tools, and entirely on Vertex AI Express (API-key) deployments. For the full comparison, see [Prompt caching](/docs/ai-gateway/features/prompt-caching.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.