# Messages (Anthropic-compatible)

> POST /v1/messages: the Anthropic Messages API, served by any model you have connected, with tools, images, extended thinking and streaming.

Product: AI Cost Optimizer Gateway (ACOG). Web version: https://tessarac.com/docs/acog/api/messages. Last updated: 2026-10-16.

```http
POST https://gateway.acog.tessarac.com/v1/messages
```

The Anthropic [Messages API](https://docs.claude.com/en/api/messages). Send exactly what you would send to Anthropic, including the `anthropic-version` header. ACOG routes by `model`: a Claude model goes to whichever of your Anthropic, Bedrock or Vertex connections declares it, and a GPT or Gemini model is translated.

## Example

```python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://gateway.acog.tessarac.com",
    # The gateway key is sent as Authorization: Bearer. Use auth_token, not api_key.
    auth_token=os.environ["ACOG_API_KEY"],
)

message = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=512,
    messages=[{"role": "user", "content": "Explain prompt caching in one paragraph."}],
)
print(message.content[0].text)
```

```typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://gateway.acog.tessarac.com",
  authToken: process.env.ACOG_API_KEY,
});

const message = await client.messages.create({
  model: "claude-sonnet-4-5",
  max_tokens: 512,
  messages: [{ role: "user", content: "Explain prompt caching in one paragraph." }],
});
```

```bash
curl -s https://gateway.acog.tessarac.com/v1/messages \
  -H "Authorization: Bearer $ACOG_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model": "claude-sonnet-4-5", "max_tokens": 512, "messages": [{"role": "user", "content": "Hello"}]}'
```

If your code sets `ANTHROPIC_API_KEY` in the environment, the Anthropic SDK sends it as `x-api-key`. ACOG ignores a provider key there, so the request fails with `401`. Unset it, or pass the gateway key explicitly as shown.

## What is supported

| Feature | Supported |
|---|---|
| System prompts, multi-turn conversations | Yes |
| Tools, tool use and tool results | Yes |
| Images and documents (base64 or URL) | Yes. For Bedrock and Vertex, ACOG fetches URL sources and sends them inline (up to 5 MB, 10-second fetch). |
| Prompt caching (`cache_control`) | Yes. ACOG also adds cache breakpoints you did not set; see [Caching](https://tessarac.com/docs/acog/optimize/caching.md#provider-prompt-caching). |
| Extended thinking | Yes. If the serving model rejects it, ACOG retries without it and sets `x-acog-thinking-stripped: true`. |
| `anthropic-beta` | Forwarded. If the serving platform rejects a beta value, ACOG retries without it and names it in `x-acog-beta-stripped`. |
| Streaming | Yes. See [Streaming](https://tessarac.com/docs/acog/api/streaming.md). |
| `model: "auto"` and `<model>:batch` | Yes. See [Auto mode](https://tessarac.com/docs/acog/optimize/auto-mode.md) and [Batches](https://tessarac.com/docs/acog/api/batches.md). |

Token counting (`/v1/messages/count_tokens`), Message Batches (`/v1/messages/batches`) and the Files API are not part of the compatible route. Call them on the native route, `https://gateway.acog.tessarac.com/anthropic`. See [Native provider routes](https://tessarac.com/docs/acog/api/native-routes.md).

## Translation to other providers

A GPT model (OpenAI, Azure OpenAI or a custom endpoint) or a Gemini model is translated from and to the Messages format, including streamed responses. Translation is strict: a field with no faithful equivalent is refused with `422 translation_unsupported`.

## The response

The response is an Anthropic message object. The header `x-acog-resolved-model` names the model that answered.

When a budget passes 50, 80 or 90% of its limit, ACOG appends a one-time notice after the model's reply and sets `x-acog-budget-notice`. See [Budgets](https://tessarac.com/docs/acog/govern/budgets.md#warnings-in-responses).
