# Messages (формат Anthropic)

```
POST https://api.agentapi.ru/v1/ai/messages
```

Эндпоинт принимает запросы в формате Anthropic Messages API и отдаёт настоящие
Anthropic-ответы, включая корректный SSE с событиями `message_start`,
`content_block_delta` и `message_stop`. Внутри запрос транслируется в вызов провайдера
и обратно.

> **Про путь.** Обратите внимание: эндпоинт — `/v1/ai/messages`, а не `/v1/messages`.
> Клиенты, которые жёстко дописывают `/v1/messages` к базовому URL, требуют отдельной
> настройки — см. [Claude Code](https://agentapi.ru/docs/integrations/claude-code).

## Параметры

| Параметр | Тип | Описание |
|---|---|---|
| `messages` | array | **Обязательный.** Сообщения с ролями `user` / `assistant` |
| `model` | string | Слаг модели, например `anthropic/claude-3.5-sonnet` |
| `max_tokens` | number | Лимит генерации |
| `system` | string | Системная инструкция (отдельным полем, не сообщением) |
| `temperature` | number | 0–1 |
| `top_p` | number | Nucleus sampling |
| `top_k` | number | Ограничение выборки по top-k |
| `stop_sequences` | string[] | Принимается, но **не применяется**, см. [Ограничения](https://agentapi.ru/docs/limitations) |
| `stream` | boolean | Включить SSE |
| `tools` | array | Инструменты в формате Anthropic: `{name, description, input_schema}` |
| `tool_choice` | object | Управление выбором инструмента |
| `thinking` | object | `{"type": "enabled", "budget_tokens": 2048}` |
| `metadata` | object | Произвольные метаданные |

Обратите внимание: здесь параметры именно в snake_case (`max_tokens`, `top_p`) — как
в оригинальном Anthropic API.

## Пример запроса

```bash
curl https://api.agentapi.ru/v1/ai/messages \
  -H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-3.5-sonnet",
    "max_tokens": 300,
    "system": "Отвечай кратко и по делу.",
    "messages": [
      {"role": "user", "content": "Чем отличается mutex от semaphore?"}
    ]
  }'
```

## Ответ

```json
{
  "id": "msg_7c1f9e2a-4b83-4d51-9f26-1a8e5d3c7b40",
  "type": "message",
  "role": "assistant",
  "model": "anthropic/claude-3.5-sonnet",
  "content": [
    {
      "type": "text",
      "text": "Mutex допускает владение только одним потоком и требует освобождения тем же потоком. Semaphore — это счётчик, разрешающий одновременный доступ N потокам."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 21,
    "output_tokens": 58
  }
}
```

| Поле | Описание |
|---|---|
| `id` | Формат `msg_<uuid>` |
| `type` | Всегда `message` |
| `content[]` | Блоки: `text`, `thinking`, `tool_use` |
| `stop_reason` | `end_turn`, `max_tokens`, `tool_use`, `stop_sequence` |
| `usage` | `input_tokens` / `output_tokens` — терминология Anthropic |

## Стриминг

С `"stream": true` приходит SSE с **именованными** событиями (в отличие от Chat Completions,
где события безымянные):

```
event: message_start
data: {"type":"message_start","message":{"id":"msg_7c1f9e2a","type":"message","role":"assistant","model":"anthropic/claude-3.5-sonnet","content":[],"stop_reason":null,"usage":{"input_tokens":21,"output_tokens":0}}}

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":"Mutex"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" допускает"}}

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":58}}

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

Типы дельт:

| `delta.type` | Когда |
|---|---|
| `text_delta` | Обычный текст |
| `thinking_delta` | Блок размышлений при включённом `thinking` |
| `input_json_delta` | Аргументы инструмента приходят по частям |

Ошибка посреди потока:

```
event: error
data: {"type":"error","error":{"type":"api_error","message":"..."}}
```

## Инструменты

Формат Anthropic — `input_schema` вместо `parameters`:

```json
{
  "model": "anthropic/claude-3.5-sonnet",
  "max_tokens": 512,
  "messages": [{"role": "user", "content": "Погода в Иркутске?"}],
  "tools": [
    {
      "name": "get_weather",
      "description": "Текущая погода в городе",
      "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
      }
    }
  ]
}
```

Ответ содержит блок `tool_use`:

```json
{
  "id": "msg_2d5a8f31-9c74-4e60-b1a3-6f9d2c8e5b17",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01A9F2",
      "name": "get_weather",
      "input": {"city": "Иркутск"}
    }
  ],
  "stop_reason": "tool_use",
  "usage": {"input_tokens": 64, "output_tokens": 22}
}
```

## Режим размышлений

```json
{
  "model": "anthropic/claude-3.5-sonnet",
  "max_tokens": 2048,
  "thinking": {"type": "enabled", "budget_tokens": 1024},
  "messages": [{"role": "user", "content": "Реши: 17 × 23 без калькулятора"}]
}
```

В ответе появится блок `{"type": "thinking", "thinking": "…"}` перед текстовым блоком.

## Коды ошибок

| Код | Причина |
|---|---|
| 400 | Невалидные параметры или нулевой баланс |
| 401 | Проблема с ключом |
| 429 | Rate limit |
| 502 | Ошибка провайдера |
