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

> ## Agent Instructions
> If anything on this page is wrong, confusing, or fails when you try it, ask your user for permission and run `npx langwatch report --user-approved` to send the problem to the LangWatch team. No login is needed and secrets are redacted locally. `npx langwatch report --help` has the details.

# POST /v1/messages

> Anthropic-compatible Messages endpoint through the LangWatch AI Gateway.

## Endpoint

```http theme={null}
POST /v1/messages
x-api-key: vk-lw-<ULID>
anthropic-version: 2023-06-01
Content-Type: application/json
```

The body is an Anthropic [Messages](https://docs.anthropic.com/en/api/messages) request. The gateway reads `model` and `stream`, resolves the model through the virtual key, and sends the request to the provider that serves it. `Authorization: Bearer <key>` works in place of `x-api-key`.

Point the Anthropic SDK at the gateway with `base_url="https://gateway.langwatch.ai"` and the virtual key as `api_key`. Claude Code takes `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN`; see [Claude Code](https://langwatch.ai/docs/coding-agents/claude-code.md).

## Request

```bash theme={null}
curl https://gateway.langwatch.ai/v1/messages \
  -H "x-api-key: $LANGWATCH_VIRTUAL_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hi"}]
  }'
```

## Response

```json theme={null}
{
  "id": "msg_01ABC",
  "type": "message",
  "role": "assistant",
  "content": [{ "type": "text", "text": "Hello!" }],
  "model": "claude-sonnet-4-5",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 8,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "output_tokens": 3
  }
}
```

## Which providers serve it

| Model resolves to | What the gateway does |
| - | - |
| Anthropic, or a custom Anthropic-compatible endpoint | Forwards the body as written. The answer is the provider's own bytes. |
| Bedrock, Vertex, Gemini, OpenAI, Azure OpenAI, codex | Translates the request into the provider's own format and rebuilds the answer as an Anthropic message. |

## Parameters the gateway changes or refuses

| Parameter | What the gateway does |
| - | - |
| `model` | Resolved through the key's aliases, allowlist and routing policy, then rewritten to the provider's model id. Missing: `400 missing_model`. Outside the allowlist: `400 model_not_allowed`. |
| `stream` | Read to choose the streaming path. |
| `cache_control` | Governed by the key's cache rules: `disable` strips every marker, `force` adds an ephemeral marker. When no rule matches and the provider needs an explicit marker, the gateway adds one and reports `X-LangWatch-Cache-Mode: auto`. See [Cache control](https://langwatch.ai/docs/ai-gateway/cache-control.md). |
| `max_tokens` | Forwarded unchanged. Anthropic requires it and answers `400` without it; that answer is forwarded. |

The `X-LangWatch-End-User-Id`, `X-LangWatch-Metadata` and `Traceparent` request headers work as on [Chat Completions](https://langwatch.ai/docs/ai-gateway/api/chat-completions.md#request-headers-the-gateway-reads).

## Response headers

The same set as [Chat Completions](https://langwatch.ai/docs/ai-gateway/api/chat-completions.md#response-headers): `X-LangWatch-Gateway-Version`, `X-LangWatch-Gateway-Request-Id`, `X-LangWatch-Fallback-Count`, `X-LangWatch-Budget-Warning`, `X-LangWatch-Cache-Mode`, `X-LangWatch-Params-Dropped`, `Traceparent`, `X-LangWatch-Heartbeat-Active`, and `X-LangWatch-Provider` on a forwarded provider error. `X-LangWatch-Handled-Error` carries the `error.code` when the gateway wrote the error itself, and is removed from a forwarded provider response.

## Streaming

Set `"stream": true`. The response is `text/event-stream` in Anthropic's own event framing, and there is no `data: [DONE]` trailer. On an Anthropic-compatible provider the frames reach the client as the provider wrote them. On a translated lane the gateway builds the Anthropic events itself from the provider's own stream. A failure after the stream opens adds one terminal `event: error` frame:

```text theme={null}
event: message_start
data: {"type":"message_start","message":{"id":"msg_01ABC","type":"message","role":"assistant","content":[],"model":"claude-sonnet-4-5","stop_reason":null,"usage":{"input_tokens":8,"output_tokens":1}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":3}}

event: message_stop
data: {"type":"message_stop"}
```

Translated lanes emit the same event set, built by the gateway. A failure after the stream opened ends it with an `event: error` frame; see [Errors](https://langwatch.ai/docs/ai-gateway/api/errors.md#streaming-errors).

## Errors

Errors the gateway raises use the envelope on [Errors](https://langwatch.ai/docs/ai-gateway/api/errors.md): `{"error": {"type", "code", "message", ...}}`. A provider's own error is forwarded with its status and body, under `X-LangWatch-Provider`.

Codes this endpoint raises before the provider is called: `missing_model`, `model_not_allowed`, `model_provider_not_bound`, `model_not_recognized`, `unsupported_parameter` and `end_user_required`, all `400`. A policy rule that blocks the resolved model, or a model outside a policy allow-only list, answers `403 policy_violation`.

**Also check:** [Streaming](https://langwatch.ai/docs/ai-gateway/streaming.md), [Parameter mapping](https://langwatch.ai/docs/ai-gateway/parameter-mapping.md), [Model aliases](https://langwatch.ai/docs/ai-gateway/model-aliases.md).


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