Skip to content

Messages (Anthropic)

The Public Free Model APIs are also reachable through Anthropic’s Messages API, so a client built against Claude — Claude Code, the anthropic SDK, anything speaking that protocol — works by changing the base URL and the key.

This surface belongs to the gateway in front of the shared models. A dedicated endpoint is your own vLLM or SGLang, neither of which speaks the Anthropic protocol, so /v1/messages is a 404 there.

POST /v1/messages Bearer key or x-api-key

Also reachable at /api/v1/messages.

ParameterTypeDescription
modelstringRequiredModel to run, from the shared catalog.
messagesarrayRequiredConversation so far, in Anthropic’s block format.
max_tokensintegerRequiredCap on tokens generated. Anthropic requires this; so does the gateway.
systemstring or arrayOptionalSystem prompt, as a string or as an array of text blocks.
temperaturenumberOptionalSampling temperature, 0 to 1. Anthropic’s range, not OpenAI’s — 1.5 is rejected with 400.
streambooleanOptionalStream the response as server-sent events. Defaults to false.
toolsarrayOptionalTool definitions, if the model supports tool calling.
thinkingobjectOptionalExtended-thinking configuration. Mapped onto the reasoning controls the backend understands. The budget_tokens form is currently rejected — see below.
output_configobjectOptionaleffort controls adaptive reasoning depth on models that support it. Accepted tiers vary per model; low and medium work everywhere.
metadataobjectOptionaluser_id is used for sticky routing. Claude Code puts its session id here.
Terminal window
curl https://developer.amd.com.cn/radeon/api/v1/messages \
-H "x-api-key: $RADEON_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash",
"max_tokens": 256,
"system": "You are a concise assistant.",
"messages": [
{"role": "user", "content": "What is ROCm?"}
]
}'
from anthropic import Anthropic
client = Anthropic(
base_url="https://developer.amd.com.cn/radeon/api",
api_key="rc-...",
)
message = client.messages.create(
model="DeepSeek-V4-Flash",
max_tokens=256,
messages=[{"role": "user", "content": "Explain ROCm in two sentences."}],
)
print(message.content[0].text)

The SDK appends /v1/messages itself, which is why base_url stops at /api.

{
"id": "msg_9f3b21d0-4c8a-4f2e-b7d1-2a6c38e5b190",
"type": "message",
"role": "assistant",
"model": "DeepSeek-V4-Flash",
"content": [
{ "type": "text", "text": "ROCm is AMD's open software platform for GPU computing..." }
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 24,
"output_tokens": 118,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}

stop_reason is one of end_turn, max_tokens, tool_use, or refusal. It is derived from the backend’s OpenAI-style finish_reason, and an unrecognised one becomes end_turn. stop_sequence is always null, because stop sequences aren’t forwarded in the first place. Reasoning models emit thinking blocks in content alongside the text ones.

POST /v1/messages/count_tokens Bearer key or x-api-key

Anthropic SDKs call this before sending, to size a request. Takes the same body as /v1/messages and returns:

{ "input_tokens": 24 }

system and tools are included in the count, because both are billed as input.

Errors on both paths use Anthropic’s envelope, so SDK error handling works unchanged:

{
"type": "error",
"error": {
"type": "authentication_error",
"message": "Unauthorized: No API key provided."
}
}

Refusals from the platform in front of the gateway — an invalid key, admission control — are wrapped in detail instead. See Errors.

Rate limits are shared with /v1/chat/completions: both land on the same backend capacity and count against the same per-key gates. See Rate limits.