Skip to content

Messages (Anthropic)

Token Factory is also reachable through Anthropic’s Messages API, so a client built for Claude, such as Claude Code or the anthropic SDK, works once you change the base URL and the key.

This surface belongs to the gateway in front of Token Factory. A model service on your instance is your own vLLM server, so whether /v1/messages works there depends on the vLLM version it runs.

POST /v1/messages API key (Bearer or x-api-key)

Also reachable at /api/v1/messages.

ParameterTypeDescription
modelstringRequiredModel to run, from Token Factory.
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. This is Anthropic’s range, not OpenAI’s, so 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 on every model whose tiers are verified.
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 API key (Bearer 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, such as an invalid key or 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.