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

# Anthropic Messages API

> Use the Anthropic SDK unmodified against the Orq.ai AI Gateway, and place cache_control breakpoints on content blocks to control prompt caching on Claude models.

**Use Cases**

<AccordionGroup>
  <Accordion title="Adopt the gateway without rewriting Anthropic code">
    Keep an existing Anthropic SDK codebase and point it at **Orq.ai** with a single `base_url` change; streaming, tool use, and multimodal input keep working unchanged.
  </Accordion>

  <Accordion title="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>

  <Accordion title="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>

  <Accordion title="Apply gateway governance to Claude traffic">
    Fallbacks, budgets, guardrails, and traces apply to every Anthropic SDK call routed through the gateway.
  </Accordion>
</AccordionGroup>

***

## Overview

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

Requests authenticate with an **Orq.ai** API key and run through the same pipeline as the [OpenAI-compatible API](/docs/ai-gateway/features/openai-compatible-api), 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.

## Quick Start

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

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

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

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.orq.ai/v3/anthropic/v1/messages \
    -H "Authorization: Bearer $ORQ_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.ORQ_API_KEY,
    baseURL: "https://api.orq.ai/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("ORQ_API_KEY"),
      base_url="https://api.orq.ai/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)
  ```
</CodeGroup>

## Supported Endpoints

All routes are relative to the base URL `https://api.orq.ai/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), [tool use](/docs/ai-gateway/features/tool-calling), and [multimodal input](/docs/ai-gateway/features/multimodal). |
| `POST /v1/messages/count_tokens` | Count input tokens for a request without calling the model. Returns `{"input_tokens": <count>}`. Returns `{"input_tokens": 0}` 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.                                                                                                                                                                |

<Warning>
  `count_tokens` returns `{"input_tokens": 0}` when the resolved model does not support token counting, which is indistinguishable from a real zero-token result. If the count is required, verify the model supports counting before relying on it.
</Warning>

## Authentication

Authenticate with the **Orq.ai** API key in either header:

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

The **Anthropic SDK** works unmodified: set `ANTHROPIC_API_KEY` to an **Orq.ai** key and `ANTHROPIC_BASE_URL` to `https://api.orq.ai/v3/anthropic`. Alternatively, pass the constructor parameters shown in the Quick Start (`apiKey`/`baseURL` in TypeScript, `api_key`/`base_url` in Python).

<Info>
  To learn more about **Orq.ai** API keys, see [API Keys](/docs/ai-gateway/configuration/api-keys).
</Info>

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

## 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/auto-router)
* [Load Balancing and Fallbacks](/docs/ai-gateway/features/load-balancing)
* [Retries](/docs/ai-gateway/features/retries)
* [Budgets](/docs/ai-gateway/budgets)
* [Guardrails](/docs/ai-gateway/configuration/guardrails)
* [Traces](/docs/ai-gateway/traces)
* [Prompt caching](/docs/ai-gateway/features/prompt-caching)
* [Response caching](/docs/ai-gateway/features/cache)

### 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 title="Prompt caching" icon="coins" href="/docs/ai-gateway/features/prompt-caching" horizontal>
  Supported `cache_control` values, TTLs, block types, minimum token thresholds, and usage reporting.
</Card>

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#minimum-token-thresholds) for the cache read to appear. The TypeScript and Python tabs reuse the client from the Quick Start.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # First call: writes the prefix to cache
  curl -X POST https://api.orq.ai/v3/anthropic/v1/messages \
    -H "Authorization: Bearer $ORQ_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://api.orq.ai/v3/anthropic/v1/messages \
    -H "Authorization: Bearer $ORQ_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)
  ```
</CodeGroup>

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. No automatic mode.                                                                  |
| Responses API (`/v3/router/responses`) | Claude                     | Manual `cache_control` on content blocks, or the top-level `cache_control` parameter, which marks the last cacheable block automatically. |
| Responses API (`/v3/router/responses`) | OpenAI, Google Gemini 2.0+ | Fully automatic. No request changes needed.                                                                                               |

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. OpenAI and Gemini 2.0+ cache automatically, and providers that cache automatically ignore `cache_control`, so the two approaches do not conflict. For the full comparison, see [Prompt caching](/docs/ai-gateway/features/prompt-caching).
