Developers / Docs / Messages API

Anthropic Messages API

ARK also speaks Anthropic's Messages API, so tools and agents built for Claude can run on open models served from Europe. Same key, same models, a different base URL.

POST https://api.ark-labs.cloud/api/anthropic/v1/messages

Set up the SDK

Point the SDK at https://api.ark-labs.cloud/api/anthropic (it adds /v1/messages itself) and pass your ARK key as auth_token, so it is sent as Authorization: Bearer. ARK does not read x-api-key or require anthropic-version.

import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.ark-labs.cloud/api/anthropic",
    auth_token=os.environ["ARK_API_KEY"],
)

message = client.messages.create(
    model="arklabsai/Qwen3.5-122B-A10B",
    max_tokens=1024,
    system="You are a concise assistant.",
    messages=[{"role": "user", "content": "Why does data residency matter for a European bank?"}],
)
print(message.content[0].text)
Response
{
  "id": "msg_01J9…",
  "type": "message",
  "role": "assistant",
  "model": "arklabsai/Qwen3.5-122B-A10B",
  "content": [{ "type": "text", "text": "Because supervisors expect…" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 31,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "output_tokens": 212,
    "output_tokens_details": { "thinking_tokens": 0 },
    "service_tier": "standard"
  }
}

Request fields

model, messages and max_tokens are required. system (a string or text blocks), temperature (0–1, default 0.6), top_p, top_k, stop_sequences (up to 4), stream, tools, tool_choice, thinking and output_config work as in Anthropic's API. metadata, service_tier, cache_control and a few others are accepted without effect. See the API reference for every field.

Content blocks

  • text; image with a base64 or url source (vision models only); document with a plain-text source; search_result.
  • tool_use and tool_result for tool conversations.
  • thinking blocks from earlier turns are accepted and dropped.
  • PDF documents and audio blocks are not supported and return 400.

If the last message is an assistant turn, Qwen models continue it (prefill), and only the continuation is returned.

Streaming

With "stream": true, ARK sends Anthropic's named events: message_start, content_block_start, ping, content_block_delta (text_delta, thinking_delta, input_json_delta), content_block_stop, message_delta with the stop reason and final usage, and message_stop.

Python
with client.messages.stream(
    model="arklabsai/Qwen3.6-35B-A3B",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a short poem about the Oder river."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Thinking

Turn reasoning on with thinking. The thinking arrives as a thinking block before the answer, and usage.output_tokens_details.thinking_tokens counts it.

thinkingResult
absent, or {"type": "disabled"}No thinking.
{"type": "enabled", "budget_tokens": 8192} or moreThinking, high level.
{"type": "enabled", "budget_tokens": 1024 … 8191}Thinking, medium level.
{"type": "adaptive"}Thinking, medium level.

budget_tokens selects the level; it does not cap the thinking. Use max_tokens to bound the total. output_config.effort (low … max) is honoured too. As on the OpenAI route, offering tools turns thinking off on the Qwen models.

Tools

Python
message = client.messages.create(
    model="arklabsai/Qwen3.6-35B-A3B",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Current weather for a city.",
        "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
    }],
    messages=[{"role": "user", "content": "Do I need an umbrella in Gdańsk?"}],
)
tool_use = next(b for b in message.content if b.type == "tool_use")
print(tool_use.name, tool_use.input)        # get_weather {'city': 'Gdańsk'}
  • Return results in a user message with tool_result blocks; is_error: true tells the model the tool failed.
  • tool_choice: auto, any, {"type": "tool", "name": …} or none; disable_parallel_tool_use limits the reply to one call.
  • Only your own (client) tools are supported. Anthropic's server tools, such as web search or code execution, return 400.

Count tokens

POST /api/anthropic/v1/messages/count_tokens returns the exact number of input tokens a request would use, including the system prompt, tools and images. It is free.

Python
count = client.messages.count_tokens(
    model="arklabsai/Qwen3.5-122B-A10B",
    messages=[{"role": "user", "content": "Why does data residency matter for a European bank?"}],
)
print(count.input_tokens)

Usage and stop reasons

  • input_tokens counts the uncached part of the prompt and cache_read_input_tokens the part served from ARK's prefix cache; their sum is the full prompt. cache_creation_input_tokens is always 0.
  • stop_reason is end_turn, max_tokens, stop_sequence or tool_use.
  • Every response has a request-id header; error bodies carry the same request_id.

Models

GET /api/anthropic/v1/models lists the models in Anthropic's format, paged with limit, after_id and before_id. Use the chat and vision models with /messages.