RunarsRunars Docs
EndpointsAPI Endpoints

POST /v1/messages

Anthropic Messages API compatible endpoint

Generate a response using the Anthropic Messages API format. This endpoint is compatible with the Anthropic SDK and Claude Code.

Endpoint

POST https://api.runars.ca/v1/messages

Authentication

Include your API key:

-H "x-api-key: sk-runars-..."

Or use Bearer token:

-H "Authorization: Bearer sk-runars-..."

Request body

For a comparison of common parameters across all endpoints, see Parameters Reference.

FieldTypeRequiredDescription
modelstringYesModel identifier, must be "glm-5.2"
max_tokensintegerYesMaximum tokens in the response (1–8000)
messagesarrayYesArray of message objects with role and content
streambooleanNoEnable streaming (default: false)
toolsarrayNoArray of tool/function definitions (optional for tool calling)
tool_choicestring|objectNoWhich tool to use ("auto", "required", or specific tool name)
systemstringNoSystem prompt/instructions

Message format

Each message in the messages array must have:

{
  "role": "user" or "assistant",
  "content": "text content" or [
    { "type": "text", "text": "..." },
    { "type": "tool_use", "id": "...", "name": "...", "input": {...} },
    { "type": "tool_result", "tool_use_id": "...", "content": "..." }
  ]
}

Response (non-streaming)

{
  "id": "msg_01ABC...",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "The response text here."
    }
  ],
  "model": "glm-5.2",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 42,
    "output_tokens": 15,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0
  }
}

Response (streaming)

With stream: true, the endpoint returns server-sent events:

event: message_start
data: {"type":"message_start","message":{"id":"msg_...","type":"message",...}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The "}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"response "}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":15}}

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

Examples

Simple text request

curl https://api.runars.ca/v1/messages \
  -H "x-api-key: sk-runars-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "glm-5.2",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": "What is the capital of France?"
      }
    ]
  }'

Using the Anthropic SDK with streaming

import Anthropic from "@anthropic-ai/sdk"

const anthropic = new Anthropic({
  baseURL: "https://api.runars.ca",
  apiKey: process.env.ANTHROPIC_API_KEY,
})

const stream = anthropic.messages.stream({
  model: "glm-5.2",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: "Tell me a short story about a robot.",
    },
  ],
})

stream.on("text", (text) => {
  process.stdout.write(text)
})

await stream.finalMessage()

With tool calling

curl https://api.runars.ca/v1/messages \
  -H "x-api-key: sk-runars-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "glm-5.2",
    "max_tokens": 1024,
    "tools": [
      {
        "name": "get_weather",
        "description": "Get the current weather",
        "input_schema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in Toronto?"
      }
    ]
  }'

The response will include a tool_use content block with the tool name and input. You can then send the tool result back in a subsequent message.

Add Anthropic's web search server tool and Runars executes the searches for you — no client round-trips:

{
  "model": "glm-5.2",
  "max_tokens": 1024,
  "tools": [
    {
      "type": "web_search_20250305",
      "name": "web_search",
      "max_uses": 5,
      "allowed_domains": ["example.com"]
    }
  ],
  "messages": [
    { "role": "user", "content": "What happened in the news today?" }
  ]
}
  • Gateway-executed: searches run server-side at Runars; the model sees results and answers with citations in one call. No tool_use stops, no client execution.
  • Response blocks: server_tool_use (the query) and web_search_tool_result (the sources) appear alongside the cited text block, and usage.server_tool_use.web_search_requests reports the count.
  • Multi-turn: pass the assistant's server_tool_use / web_search_tool_result blocks back unchanged — the encrypted_content blobs are opaque round-trip state.
  • Options: max_uses (cap per request, default 5), allowed_domains / blocked_domains, and user_location localization are honored.
  • Billing: $10 / 1,000 executed searches (standard rate) plus normal token costs; errored searches are not billed.
  • Not supported here: other server tools (web_fetch, code_execution, …) are rejected with a 400, and /v1/chat/completions does not support web search at all.

Error responses

400 Bad Request

Missing required field:

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "Missing required field: max_tokens"
  }
}

401 Unauthorized

Invalid or missing API key:

{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}

402 Payment Required

Insufficient credit balance:

{
  "type": "error",
  "error": {
    "type": "billing_error",
    "message": "Insufficient credits"
  }
}

429 Too Many Requests

Rate limit exceeded:

{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "message": "Rate limit exceeded"
  }
}

The response includes a Retry-After header.

Token usage

  • Input tokens: Count towards pricing and rate limits.
  • Output tokens: Count towards pricing and rate limits.
  • Cache write tokens (if using prompt caching): Billed at 1.25× (5m TTL) or 2× (1h TTL) the input token rate.
  • Cache read tokens: Billed at 0.1× the input token rate.

See Pricing for details.

On this page