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

# Messages

> POST /v1/messages — Anthropic Messages format through SERV.

```
POST https://inference-api.openserv.ai/v1/messages
```

Anthropic Messages format. Accepts Claude and most other models in the [catalog](../models) — see [endpoint compatibility](./compatibility).

## Request

<ParamField header="Authorization" type="string" required>
  `Bearer $SERV_API_KEY`.
</ParamField>

<ParamField body="model" type="string" required>
  Model ID from the [catalog](../models), for example `claude-haiku-4.5`.
</ParamField>

<ParamField body="max_tokens" type="integer" required>
  Maximum number of tokens to generate. Required by the Messages format.
</ParamField>

<ParamField body="system" type="string" required>
  The system prompt. SERV requires one.
</ParamField>

<ParamField body="messages" type="array" required>
  The conversation so far. Each entry has a `role` (`user` or `assistant`) and `content`.
</ParamField>

<ParamField body="thinking" type="object">
  Extended thinking controls, for example `{ "type": "enabled", "budget_tokens": 1024 }`.
</ParamField>

<ParamField body="tools" type="array">
  Tool definitions, in Anthropic format: `{ name, input_schema }`.
</ParamField>

<ParamField body="tool_choice" type="string | object">
  `"auto"`, `"any"`, or `{ "type": "tool", "name": "..." }`.
</ParamField>

<ParamField body="stop_sequences" type="array">
  Sequences that stop generation.
</ParamField>

<ParamField body="stream" type="boolean" default="false">
  Stream the response as server-sent events.
</ParamField>

All other Anthropic Messages parameters are accepted and forwarded to the model.

## Response

<ResponseField name="id" type="string">
  Unique identifier for the message.
</ResponseField>

<ResponseField name="type" type="string">
  Always `"message"`.
</ResponseField>

<ResponseField name="role" type="string">
  Always `"assistant"`.
</ResponseField>

<ResponseField name="model" type="string">
  The model used.
</ResponseField>

<ResponseField name="content" type="array">
  Output blocks. Find the block with `type: "text"` for the generated text.
</ResponseField>

<ResponseField name="stop_reason" type="string">
  Why generation ended. Common values: `end_turn`, `max_tokens`, `stop_sequence`, `tool_use`.
</ResponseField>

<ResponseField name="usage" type="object">
  Token counts: `input_tokens`, `output_tokens`.
</ResponseField>

<RequestExample>
  ```bash curl theme={null}
  curl https://inference-api.openserv.ai/v1/messages \
    -H "Authorization: Bearer $SERV_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "claude-haiku-4.5",
      "max_tokens": 1024,
      "system": "You answer in one sentence.",
      "messages": [{"role": "user", "content": "Hello!"}]
    }'
  ```

  ```js Anthropic SDK theme={null}
  import Anthropic from "@anthropic-ai/sdk";

  const client = new Anthropic({
    baseURL: "https://inference-api.openserv.ai",
    authToken: process.env.SERV_API_KEY,
  });

  const message = await client.messages.create({
    model: "claude-haiku-4.5",
    max_tokens: 1024,
    system: "You answer in one sentence.",
    messages: [{ role: "user", content: "Hello!" }],
  });
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "id": "msg_...",
    "type": "message",
    "role": "assistant",
    "model": "claude-haiku-4.5",
    "content": [{ "type": "text", "text": "Hello! How can I help?" }],
    "stop_reason": "end_turn",
    "usage": { "input_tokens": 16, "output_tokens": 7 }
  }
  ```
</ResponseExample>
