Messages API
POST /api/v1/messages — the Anthropic-compatible Messages endpoint. Point any Anthropic SDK or Claude Code at AnyRouter by swapping the base URL.
The Messages API is an Anthropic-compatible endpoint. Any tool that speaks the Anthropic Messages protocol — including Claude Code and the official @anthropic-ai/sdk — works against AnyRouter by changing the base URL.
Authenticate with an LLM API key (sk-ar-v1-…) from /dashboard/keys, passed via either Authorization: Bearer … or Anthropic's x-api-key header. Management keys (ak_…) are not accepted.
Request
Unlike the OpenAI-compatible endpoints, the Messages API expects Anthropic's auth headers.
| Header | Required | Description |
|---|---|---|
x-api-key | yes | Your AnyRouter API key (prefixed sk-ar-). Authorization: Bearer sk-ar-… is also accepted. |
anthropic-version | recommended | Anthropic API version. Dated values (YYYY-MM-DD, e.g. 2023-06-01) are accepted; a missing header is allowed. |
Content-Type | yes | application/json. |
Request body fields:
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | Any catalog model id (e.g. anthropic/claude-sonnet-4-6, openai/gpt-4o, anyrouter/coding). |
messages | array | yes | [{role, content}] — content can be a string or rich blocks. |
max_tokens | integer | yes | Required by the Messages API. |
system | string | no | System prompt (Anthropic splits this out of messages). |
temperature | number | no | 0–1. |
stream | boolean | no | SSE streaming. |
stop_sequences | string[] | no | Stop sequences. |
tools | array | no | Tool definitions in Anthropic's schema. |
session_id | string | no | Sticky-session id (≤256 chars) that groups related requests in Request Logs. Also settable via the x-session-id header; the body field wins. |
Response
{
"id": "msg_01XY...",
"type": "message",
"role": "assistant",
"model": "anthropic/claude-sonnet-4-6",
"content": [{ "type": "text", "text": "Hello there." }],
"stop_reason": "end_turn",
"usage": { "input_tokens": 10, "output_tokens": 4, "cost": 0.000342 }
}Cost of a request
usage.cost is the USD amount charged to your credits for the request. It is 0 when nothing was charged, for example a free model or a request made with your own provider key (BYOK). It matches your usage history.
- Non-streaming:
usage.costis on the response. - Streaming:
usage.costis on theusageof the finalmessage_deltaevent, sent when the model has finished. No event is added or reordered.
It is an extra key beside input_tokens and output_tokens. Anthropic's SDKs ignore keys they do not know, so existing clients such as Claude Code keep working unchanged. The same field is on chat completions.
Supported models
The Messages endpoint accepts any model in the catalog, not just Anthropic ones. anthropic/* models are sent to Anthropic-native upstreams as a passthrough; every other model — including OpenAI-compatible providers and AnyRouter virtual models such as anyrouter/coding — is transparently translated to and from the Chat Completions dialect, so the request and response you see stay in Anthropic Messages format.
This means Anthropic-native clients (e.g. Claude Code) can target the full catalog through /messages without switching to chat completions.
Examples
curl https://anyrouter.dev/api/v1/messages \
-H "x-api-key: sk-ar-your-key" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-haiku-4-5",
"max_tokens": 1024,
"messages": [
{ "role": "user", "content": "Say hi in 5 words" }
]
}'import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic({
baseURL: "https://anyrouter.dev/api",
apiKey: "sk-ar-your-key",
})
const response = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
})For the Anthropic SDK the base URL is https://anyrouter.dev/api — the SDK appends /v1/messages itself.
Errors
Errors use the standard AnyRouter envelope. An unknown provider or an unrouteable model returns unknown_provider or no_upstream:
{
"error": {
"code": "no_upstream",
"message": "No upstream is available for \"<model>\".",
"metadata": { "type": "upstream_error" }
}
}| Status | Meaning | Fix |
|---|---|---|
| 400 | Malformed body, or max_tokens missing. | max_tokens is required by the Messages API. |
| 401 | Missing or invalid key. | Send a valid sk-ar-… key via x-api-key or Authorization. |
| 404 | Unknown model or no upstream. | Verify the id with List models. |
See Errors for the full status table and retry guidance.