Docs

Create Message

POST/v1/messages

Creates a message using the Anthropic Messages API format

On this page
  1. Request Headers
  2. Request Body
  3. Response
  4. Request Example
  5. Response Example
  6. Error Response Example
  7. Vision Input Example
  8. Extended Thinking Example

This endpoint provides native Anthropic Messages API compatibility. Use this for Claude models with features like extended thinking.

/v1/messages and /v1/messages/count_tokens remain chat-protocol compatibility endpoints under the chat family.

Request Headers

Header Authorization

Type: string

Required: no

Bearer token form: Bearer sk-your-api-key. Either Authorization or x-api-key is required.

Header x-api-key

Type: string

Required: no

Anthropic-style API key header. Use this instead of Authorization when your client expects Anthropic headers.

Header anthropic-version

Type: string

Required: no

Anthropic API version. Clients conventionally send 2023-06-01. The gateway does not validate it.

Request Body

Parameter model

Type: string

Location: body

Required: yes

Claude model ID (e.g., claude-sonnet-4-6 or claude-opus-4-6).

Parameter messages

Type: array

Location: body

Required: yes

Array of message objects with role and content.

For Claude models with vision support, content can be either a plain string or an array of content blocks. To send images, use structured content blocks rather than placing image URLs or Base64 strings directly into plain text.

Example content blocks:

  • text block: { "type": "text", "text": "Describe this image" }
  • image block via URL: { "type": "image", "source": { "type": "url", "url": "https://example.com/image.jpg" } }
  • image block via Base64: { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgoAAA..." } }

Parameter max_tokens

Type: integer

Location: body

Required: yes

Maximum tokens to generate.

Parameter system

Type: string

Location: body

System prompt (separate from messages array).

Parameter temperature

Type: number

Location: body

Sampling temperature (0-1).

Parameter stream

Type: boolean

Location: body

Enable streaming responses.

Parameter thinking

Type: object

Location: body

Extended thinking configuration for supported Claude models.

  • type (string): "enabled" to enable
  • budget_tokens (integer): Token budget for thinking

Parameter tools

Type: array

Location: body

Available tools for the model.

Parameter tool_choice

Type: object

Location: body

How the model should use tools. Options: auto, any, tool (specific tool).

Parameter top_p

Type: number

Location: body

Nucleus sampling parameter. Use either temperature or top_p, not both.

Parameter top_k

Type: integer

Location: body

Only sample from the top K options for each token.

Parameter stop_sequences

Type: array

Location: body

Custom stop sequences that will cause the model to stop generating.

Parameter metadata

Type: object

Location: body

Metadata to attach to the request for tracking purposes.

Response

Response Field id

Type: string

Unique message identifier.

Response Field type

Type: string

Always message.

Response Field role

Type: string

Always assistant.

Response Field content

Type: array

Array of content blocks (text, thinking, tool_use).

Response Field model

Type: string

Model used.

Response Field stop_reason

Type: string

Why generation stopped (end_turn, max_tokens, tool_use).

Response Field usage

Type: object

Token usage with input_tokens and output_tokens.

Request Example

curl -X POST "https://api.anypath.dev/v1/messages" \
  -H "x-api-key: sk-your-api-key" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "system": "You are a helpful assistant.",
    "messages": [
      {"role": "user", "content": "Hello, Claude!"}
    ]
  }'
from anthropic import Anthropic

client = Anthropic(
    api_key="sk-your-api-key",
    base_url="https://api.anypath.dev"
)

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system="You are a helpful assistant.",
    messages=[
        {"role": "user", "content": "Hello, Claude!"}
    ]
)

print(message.content[0].text)
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: 'sk-your-api-key',
  baseURL: 'https://api.anypath.dev'
});

const message = await client.messages.create({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  system: 'You are a helpful assistant.',
  messages: [
    { role: 'user', content: 'Hello, Claude!' }
  ]
});

console.log(message.content[0].text);
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    payload := map[string]interface{}{
        "model":      "claude-sonnet-4-6",
        "max_tokens": 1024,
        "system":     "You are a helpful assistant.",
        "messages": []map[string]string{
            {"role": "user", "content": "Hello, Claude!"},
        },
    }

    jsonData, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.anypath.dev/v1/messages", bytes.NewBuffer(jsonData))
    req.Header.Set("x-api-key", "sk-your-api-key")
    req.Header.Set("anthropic-version", "2023-06-01")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))
}
<?php
$payload = [
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'system' => 'You are a helpful assistant.',
    'messages' => [
        ['role' => 'user', 'content' => 'Hello, Claude!']
    ]
];

$ch = curl_init('https://api.anypath.dev/v1/messages');

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'x-api-key: sk-your-api-key',
        'anthropic-version: 2023-06-01',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode($payload)
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo $data['content'][0]['text'];

Response Example

{
  "id": "msg_abc123",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Hello! How can I help you today?"
    }
  ],
  "model": "claude-sonnet-4-6",
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 15,
    "output_tokens": 10
  }
}

Error Response Example

Anthropic‑shaped error responses follow the standard error envelope:

{
  "error": {
    "message": "API key spending limit exceeded.",
    "type": "spending_limit_exceeded",
    "code": "spending_limit_exceeded"
  }
}
{
  "error": {
    "message": "Rate limit exceeded. Please retry after the period indicated in the Retry-After header.",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded"
  }
}

Vision Input Example

For Claude models with vision support, place images inside messages[].content as structured image blocks.

{
  "model": "claude-sonnet-4-6",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Please describe this image."
        },
        {
          "type": "image",
          "source": {
            "type": "url",
            "url": "https://example.com/demo.jpg"
          }
        }
      ]
    }
  ]
}
{
  "model": "claude-sonnet-4-6",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Please describe this image."
        },
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/jpeg",
            "data": "/9j/4AAQSkZJRgABAQ..."
          }
        }
      ]
    }
  ]
}

Extended Thinking Example

message = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={
        "type": "enabled",
        "budget_tokens": 10000
    },
    messages=[{"role": "user", "content": "Solve this math problem..."}]
)

for block in message.content:
    if block.type == "thinking":
        print(f"Thinking: {block.thinking}")
    elif block.type == "text":
        print(f"Response: {block.text}")