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

# Anthropic Messages API

> Point the Anthropic SDK or Claude Code at PlungeAI. Any model through the Messages API, on the same routing, guardrails and billing as chat completions.


<Note>
Partly available: the route is built, and this page is read from the gateway code; it has not yet been re-run against the deployed API. Tracked as TI-78.
</Note>

`POST /v1/messages` speaks the Anthropic Messages API. Change the base URL and the key of an Anthropic client and keep your request and response code. Behind it is the same path as [chat completions](/api-reference/models/create-chat-completion): `models` and `sort` failover, presets, guardrails, and billing to your wallet.

## Drop-in for the Anthropic SDK

The SDK adds `/v1/messages` to the base URL and sends your key as `x-api-key`. `Authorization: Bearer` works too. `anthropic-version` is accepted with any value.

<CodeGroup>

```python Python
import os
import anthropic

client = anthropic.Anthropic(base_url='https://api.plungeai.com', api_key=os.environ['PLUNGE_API_KEY'])
message = client.messages.create(
    model='anthropic/claude-haiku-4-5',
    max_tokens=64,
    messages=[{'role': 'user', 'content': 'hi'}],
)
print(message.content[0].text)
```

```typescript TypeScript
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic({ baseURL: 'https://api.plungeai.com', apiKey: process.env.PLUNGE_API_KEY })
const message = await client.messages.create({
  model: 'anthropic/claude-haiku-4-5',
  max_tokens: 64,
  messages: [{ role: 'user', content: 'hi' }],
})
console.log(message.content)
```

```bash cURL
curl -s https://api.plungeai.com/v1/messages \
  -H "x-api-key: $PLUNGE_API_KEY" \
  -H 'anthropic-version: 2023-06-01' \
  -H 'Content-Type: application/json' \
  -d '{"model":"anthropic/claude-haiku-4-5","max_tokens":64,"messages":[{"role":"user","content":"hi"}]}'
```

</CodeGroup>

The same route is served at `https://api.plungeai.com/api/v1/messages`, the OpenRouter-compatible base. There `fallbacks` takes up to 3 models to try after `model`.

## Anthropic models: your body, unchanged

On an `anthropic/*` model the gateway forwards your request body as you sent it and sets only two fields: `model` (the upstream id) and `max_tokens` (the capped value). `cache_control`, `thinking`, documents, `system` blocks and server tools reach Anthropic unchanged. Ocean's own fields (`models`, `fallbacks`, `sort`, `max_cost`) are removed first.

## Every other model: translated

Any other slug, such as `openai/gpt-4o-mini`, gets the chat-completions shape:

| Messages API | Sent as |
|---|---|
| `system` | a system message |
| `tool_use` blocks | `tool_calls` on the assistant message |
| `tool_result` blocks | `tool` messages |
| `tools[].input_schema` | `function.parameters` |
| `tool_choice` `auto` / `any` / `none` / `tool` | `auto` / `required` / `none` / that function |
| `disable_parallel_tool_use` | `parallel_tool_calls: false` |
| `stop_sequences` | `stop` |
| `metadata.user_id` | `user` |
| `thinking.budget_tokens` | `reasoning_effort`: up to 35% of `max_tokens` is `low`, up to 65% `medium`, above that `high` |

Blocks with no chat-completions form (thinking, server tools) are not sent to these models.

## Responses

You get an Anthropic `message` for every model, built from the completion that served the request. `content` holds `text` and `tool_use` blocks. `model` is the slug that actually answered, which can differ from the one you asked for after a failover. `usage.input_tokens` excludes cache reads and cache writes; those are in `cache_read_input_tokens` and `cache_creation_input_tokens`. The `x-request-id` and `x-ocean-*` response headers are kept.

## Streaming

With `stream: true` the events come in Anthropic's order:

1. `message_start`
2. For each content block: `content_block_start`, one or more `content_block_delta` (`text_delta` for text, `input_json_delta` for tool input), `content_block_stop`
3. `message_delta` with `stop_reason` and the final `usage`
4. `message_stop`

`ping` events are keepalives. A failure after the response has started ends the stream with an `error` event. The SDK helpers (`client.messages.stream`) read this stream as they read Anthropic's.

## Errors

Errors use Anthropic's envelope on both `/v1/messages` and `/api/v1/messages`:

```json
{"type":"error","error":{"type":"authentication_error","message":"Invalid API key"},"request_id":"00000000-0000-4000-8000-000000000004"}
```

`error.type` follows the status: `400` `invalid_request_error`, `401` `authentication_error`, `402` `billing_error`, `403` `permission_error`, `404` `not_found_error`, `429` `rate_limit_error`, `504` `timeout_error`, any other `api_error`.

## Not supported

- The `anthropic-beta` header is not forwarded, so features behind a beta flag do not switch on.
- Responses carry `text` and `tool_use` blocks only; `stop_sequence` is always `null`.
- `/v1/messages/count_tokens` and Message Batches are not served.

## Reference

<Card title="Create message (Anthropic)" icon="code" href="/api-reference/models/create-message">
Every request field, the response schema, error codes and code samples.
</Card>
