# Messages

`POST https://api.llm.buzz/api/v1/messages`

Anthropic's Messages API, for the Anthropic SDK and the tools built on it. The key may also come in `x-api-key`. Errors keep Anthropic's error body.

Authentication: an inference key, as `Authorization: Bearer KEY` or in `x-api-key`.

## Parameters

- `x-session-id` (header string): Names the conversation, as `session_id` does, so its turns stay on the provider that holds its cache.

## Body

- `model` (string, required): A model's name from `GET /api/v1/models`, such as `deepseek/deepseek-v4.1-flash`. A suffix changes one request: `:floor` tries the cheapest provider first and `:nitro` the fastest. On Chat Completions and Responses `:online` asks for a web search, which llm.buzz does not run today: the request is served without one and `x-sgr-ignored-parameters` names `web_search->dropped(search_unavailable)`, or for an organization whose requests llm.buzz keeps in the EU it answers 400 `web_search_unavailable_in_region`. On Messages `:online` does nothing and is named as `model:online`.
- `max_tokens` (integer, required): The most tokens the answer may use.
- `messages` (object[], required): The conversation, as Anthropic's message objects.
- `system` (string or object[]): The system prompt: a string, or a list of text blocks, which may carry `cache_control`.
- `stream` (boolean): Stream Anthropic's server-sent events.
- `tools` (object[]): Tools in Anthropic's shape. `{"type": "tool_search_tool_bm25"}` or `{"type": "tool_search_tool_regex"}` declares a tool search over tools marked `defer_loading: true`.
- `reasoning` (object): Reasoning controls, translated for each provider.
  - `effort` (string): How hard the model thinks. An effort the model does not take becomes the nearest one it does, named in `x-sgr-ignored-parameters`.
  - `max_tokens` (integer): A reasoning budget in tokens.
  - `enabled` (boolean): Turn reasoning on or off.
  - `exclude` (boolean): Keep the reasoning text out of the answer while the model still reasons.
- `provider` (object): Steers one request across the model's providers. With the OpenAI SDK, send it in `extra_body`. Every field accepts `null`. A name matches a provider's display name, its tag or the tag's first part, ignoring case: `llm.buzz` or `llm-buzz` names llm.buzz's own provider, and `llm-buzz/eu` only its capacity in the EU.
  - `order` (string[]): Try these providers first, in this order, then the others. At most 64 names.
  - `only` (string[]): Use only these providers.
  - `ignore` (string[]): Never use these providers.
  - `allow_fallbacks` (boolean): `false` stops moving to other providers.
  - `sort` (string, one of `price`, `throughput`, `latency`, `smart`): The order to try providers in. Ignored when `order` is set.
  - `zdr` (boolean): `true` keeps the request on providers that declare 0 days of retention.
  - `data_collection` (string, one of `allow`, `deny`): `deny` keeps the request on providers that declare no training and 0 days of retention.
- `session_id` (string): A name for the conversation, 1 to 256 characters, so its turns stay on the provider that holds its cache.

## Responses

- 200: Anthropic's message object. `usage` always carries `cache_creation_input_tokens` and `cache_read_input_tokens`, and `cost` in US dollars; readable reasoning arrives as a `thinking` block.
- 400: A field is missing or malformed, or the model cannot do what the request asks, in Anthropic's error body as an `invalid_request_error`; the message names the field.
- 401: Messages keeps Anthropic's error body: a 401 is an `authentication_error`, a 402 a `billing_error`, a 403 a `permission_error` and a 429 a `rate_limit_error`.

## Example (curl)

```bash
curl -X POST https://api.llm.buzz/api/v1/messages \
  -H "Authorization: Bearer $LLM_BUZZ_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "anthropic/claude-haiku-5.5",
  "max_tokens": 256,
  "messages": [
    {
      "role": "user",
      "content": "Say hello in one word."
    }
  ]
}'
```

## Example (Python)

```python
import os
from anthropic import Anthropic

client = Anthropic(base_url="https://api.llm.buzz/api", api_key=os.environ["LLM_BUZZ_KEY"])
message = client.messages.create(
    model="anthropic/claude-haiku-5.5",
    max_tokens=256,
    messages=[{"role": "user", "content": "Say hello in one word."}],
)
print(message.content[0].text)
```

## Example (TypeScript)

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

const client = new Anthropic({ baseURL: "https://api.llm.buzz/api", apiKey: process.env.LLM_BUZZ_KEY });
const message = await client.messages.create({
  model: "anthropic/claude-haiku-5.5",
  max_tokens: 256,
  messages: [{ role: "user", content: "Say hello in one word." }],
});
```

## Example response

```json
{
  "id": "msg_...",
  "type": "message",
  "role": "assistant",
  "model": "anthropic/claude-haiku-5.5",
  "content": [
    {
      "type": "text",
      "text": "Hello!"
    }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 14,
    "output_tokens": 4,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "cost": 0.0000034
  }
}
```
