Anthropic Messages
Official docs: Messages · Streaming messages · Count tokens
POST /v1/messages is the Anthropic-native wire entrypoint: the auth header, message structure, and event-stream names all keep Claude's shape, so Claude SDK, Claude Code, and similar clients only need to point their base URL at ModelGo.
| Item | Value |
|---|---|
| Endpoint | POST /v1/messages |
| Base URL (Anthropic SDK) | https://api.modelgo.ai (no /v1) |
| Authentication | x-api-key: $MODELGO_API_KEY |
| Version header | anthropic-version, optional; defaults to 2023-06-01 |
| Protocol value | anthropic_messages |
Request examples
curl https://api.modelgo.ai/v1/messages \
-H "x-api-key: $MODELGO_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "<model>",
"max_tokens": 1024,
"system": "You are a concise assistant.",
"messages": [{"role": "user", "content": "Introduce ModelGo in one sentence."}]
}'import os
import anthropic
client = anthropic.Anthropic(
api_key=os.environ["MODELGO_API_KEY"],
base_url="https://api.modelgo.ai",
)
msg = client.messages.create(
model="<model>",
max_tokens=1024,
messages=[{"role": "user", "content": "Introduce ModelGo in one sentence."}],
)
print(msg.content[0].text)Common fields
| Field | Required | Description |
|---|---|---|
model | Yes | Platform logical model name |
max_tokens | Yes | Output cap |
messages | Yes | Message array; role is user / assistant, content is a string or block array |
system | No | System prompt, kept separate from messages |
temperature / top_p | No | Sampling parameters |
stop_sequences | No | Stop sequences |
tools / tool_choice | No | Tool definitions and selection; return tool_result as a content block inside a user message |
stream | No | true returns the native event stream |
The model in the response may be the upstream's internal name (for example pa/venus-cathedral-5), which differs from the requested logical name; billing and policy follow the requested model and the console configuration.
Streaming events
Streaming keeps Anthropic's native event: frames; the gateway never rewrites them into OpenAI's data:-only SSE. The order is message_start → content_block_start → several content_block_delta → content_block_stop → message_delta → message_stop. There is no data: [DONE] sentinel; the stream ends on message_stop.
usage on message_start carries input and cache counts; usage on message_delta carries output counts. Settlement bills the sum of both.
Token counting
POST /v1/messages/count_tokens is estimated locally by the gateway and never forwarded upstream: it counts input_tokens over system, messages, and tools, which is how clients such as Claude Code decide when to compact context. The endpoint is still gated by the model catalog and policy, but it is not billed.
curl https://api.modelgo.ai/v1/messages/count_tokens \
-H "x-api-key: $MODELGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<model>","messages":[{"role":"user","content":"hello"}]}'Key conventions
- When a logical model does not declare
anthropic_messages, this entrypoint answers HTTP 400 witherror_class=model_protocol_not_offered(app_error_id=4005). - The error envelope is Anthropic-shaped:
{"type":"error","error":{"type":"authentication_error","message":"...","code":401,"metadata":{...}}}, plus a top-leveltrace_id. GET /v1/modelsreturns an Anthropic-shaped model list (data[].display_name) when the request carries bothx-api-keyandanthropic-version.- Request bodies are capped at 10 MiB.
- A request that reached the upstream but then failed settles at the reserved amount; see Errors & Rate Limits.
Client setup for Claude Code and friends is in Claude Code; the comparison across all three text entrypoints is in the text generation overview.