SupaNexus

Messages (Anthropic) — Markdown source

Raw Markdown for copying or feeding to AI agents.

> **AI Agents**: Index `/api/llms.txt` | Full EN `/api/llms-full-en.txt` | Full ZH `/api/llms-full-zh.txt` | OpenAPI `/api/openapi.yaml`
> Base URL: `<BASE_URL>/v1`

# Messages (Anthropic-compatible)

Create a model response using the **Anthropic Messages API** format — similar to [OpenRouter `/v1/messages`](https://openrouter.ai/docs/api/api-reference/anthropic-messages/create-messages).

```
POST <BASE_URL>/v1/messages
```

Use this endpoint when integrating **Anthropic SDK**, **Claude Code**, or other clients that expect native Anthropic shapes. Non-Anthropic upstreams are translated to OpenAI Chat Completions. Prefer this endpoint for Claude images.

## Authentication

Required: `Authorization: Bearer <API_KEY>` (same SupaNexus API key as `/v1/chat/completions`).

## Request headers

| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | Bearer API Key |
| `Content-Type` | Yes | `application/json` |
| `Idempotency-Key` | No | Deduplicate within 24h per API key |
| `Accept-Language` / `X-Locale` | No | Localized error text where applicable |

## Request body

SupaNexus accepts standard Anthropic Messages JSON and reads `model` and `stream`.

```json
{
  "model": "anthropic/claude-3-5-sonnet",
  "max_tokens": 1024,
  "messages": [
    {"role": "user", "content": "Hello!"}
  ],
  "stream": false
}
```

| Field | Required | Description |
|-------|----------|-------------|
| `model` | Yes | Model id from `GET /v1/models` |
| `messages` | Yes | Anthropic message array |
| `max_tokens` | Yes | Maximum output tokens (Anthropic requirement) |
| `system` | No | System prompt (string or content blocks) |
| `stream` | No | `true` for Anthropic SSE events |
| `temperature`, `top_p`, `stop_sequences` | No | Passed through when supported |
| `tools`, `tool_choice`, `thinking`, `metadata` | No | Passed through in Anthropic-compatible form when supported |

## Multimodal input (images)

When the model’s `architecture.input_modalities` includes `"image"`, `messages[].content` may be a **content-block array** carrying both text and images.

### Base64 image example

```json
{
  "model": "anthropic/claude-sonnet-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/jpeg",
            "data": "/9j/4AAQSkZJRg..."
          }
        },
        {"type": "text", "text": "Describe this image"}
      ]
    }
  ]
}
```

### URL image example

```json
{
  "type": "image",
  "source": {
    "type": "url",
    "url": "https://example.com/photo.jpg"
  }
}
```

### Limitation: OpenAI-protocol upstream models

If the target model’s upstream uses the **OpenAI Chat Completions** protocol (not `anthropic/*`), Anthropic image blocks are **not** converted to `image_url`, and the upstream typically rejects the request. Use [`POST /v1/chat/completions`](./chat-completions.md) with OpenAI `image_url` instead — see [Parameters → Multimodal input](./parameters.md).

**Rule of thumb**: for images, keep the client protocol aligned with the model’s upstream — use this endpoint for `anthropic/*`, and `/v1/chat/completions` for other models.

## Non-streaming response

Anthropic-shaped JSON:

```json
{
  "id": "msg_...",
  "type": "message",
  "role": "assistant",
  "model": "claude-3-5-sonnet-20241022",
  "content": [{"type": "text", "text": "Hello! How can I help?"}],
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 12, "output_tokens": 8}
}
```

## Streaming

When `stream: true`, SupaNexus returns Anthropic event-stream (`message_start`, `content_block_delta`, `message_delta`, `message_stop`). See [Streaming](./streaming.md) for general SSE notes.

## Response headers (SupaNexus)

Same as Chat Completions: `X-SNX-Trace-ID`, `X-SNX-Model`, `X-SNX-Provider`.

## Error format

On `/v1/messages`, SupaNexus returns **Anthropic-style** errors (not OpenRouter numeric `error.code`):

```json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "you must provide a model parameter"
  }
}
```

| HTTP | Typical `error.type` |
|------|----------------------|
| 400 | `invalid_request_error` |
| 401 | `authentication_error` |
| 402 | `billing_error` |
| 404 | `not_found_error` |
| 429 | `rate_limit_error` |
| 503 | `overloaded_error` |

For OpenRouter-shaped errors, use [`POST /v1/chat/completions`](./chat-completions.md) instead.

## OpenAI vs Anthropic endpoints

| Client | Endpoint | Error body |
|--------|----------|------------|
| OpenAI SDK | `POST /v1/chat/completions` | OpenRouter `{error:{code,message}}` |
| Anthropic SDK / Claude Code | `POST /v1/messages` | Anthropic `{type,error:{type,message}}` |

Both use the **same SupaNexus API key** and share routing, quota, and billing.

## Related

- [Anthropic SDK Integration](./anthropic-sdk-integration.md)
- [Chat Completions](./chat-completions.md)
- [Authentication](./authentication.md)
- [Errors](./errors.md)