Messages
Create a message with the Anthropic Messages API. This is the endpoint Claude Code uses.
Follows Anthropic's Messages format. A successful response body passes through unchanged. Deference rebuilds error bodies in the Anthropic envelope. Provider errors that describe your request keep valid Anthropic types and wording. The request passes through except for two rewrites: a model id that is not the catalog id is replaced with that id, and a provider-run web_search tool's max_uses is capped to the request's tool-step allowance. A trailing [1m] is removed before the request is sent. Use https://deference.si as the SDK base URL, without /v1.
Send a request
curl https://deference.si/v1/messages \
-H "x-api-key: $DEFERENCE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5.5",
"max_tokens": 1024,
"messages": [{ "role": "user", "content": "Say hello in one sentence." }]
}'import os
import anthropic
client = anthropic.Anthropic(base_url="https://deference.si", api_key=os.environ["DEFERENCE_API_KEY"])
message = client.messages.create(
model="anthropic/claude-sonnet-5.5",
max_tokens=1024,
messages=[{"role": "user", "content": "Say hello in one sentence."}],
)
print(message.content[0].text)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://deference.si",
apiKey: process.env.DEFERENCE_API_KEY,
});
const message = await client.messages.create({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
messages: [{ role: "user", content: "Say hello in one sentence." }],
});
console.log(message.content);Headers
- x-api-keystringRequired
- Your key.
Authorization: Bearer sk-df-...works too. - anthropic-versionstring
- Forwarded as sent. Anthropic's SDKs set it.
- anthropic-betastring
- Forwarded as sent. Any beta value is accepted.
Request body
- modelstringRequired
- The model id, such as
anthropic/.claude-sonnet-5.5 - max_tokensinteger
- The output limit. Required when the model lists no maximum output; without one the call returns
400 output_cap_required. An explicit value is held in full up to the model's maximum. When omitted, the hold is the model's full maximum output, with no 32,768-token clamp. Deference does not send a cap of its own. - messagesarrayRequired
- Alternating
userandassistantturns. Content can be a string or an array of blocks. - systemstring | array
- The system prompt. Send blocks to use
cache_control. - streamboolean
- Return server-sent events.
- toolsarray
- Tools the model may call.
- tool_choiceobject
- How the model picks a tool.
- temperaturenumber
- Sampling temperature.
- thinkingobject
- Extended thinking settings, for models that support them.
A query string such as ?beta=true is ignored.
Credit held
Deference reserves credit for the prompt, the full max_tokens and allowed web-search steps. It never lowers max_tokens on Messages. A web_search tool's max_uses is capped to the request's tool-step allowance, which defaults to 30 and can be lowered with max_tool_calls — but not when stop_server_tools_when is set, which keeps the allowance at 30. Omitted or invalid max_uses uses that allowance.
A request whose hold does not fit in your available credit, or in its key's remaining limit, returns 402 with billing_error: lower max_tokens or add credit. A request that free credit pays for runs on what it can hold. See Pricing.
Files and URLs
- A model reads a PDF or other file itself only if it lists
fileinput. For other models, the request returns400 unsupported_unless it asks for the free parser:parameter "plugins": [{ "id": "file-parser", "pdf": { "engine": "cloudflare-ai" } }]. - Every file part, inline or given as a URL, and every image or video given as a URL is held at the larger of the text estimate and the model's context window, or 1,000,000 tokens when that window is unknown.
- A non-streamed call ends at 5 minutes when response headers have not arrived or the body stalls for that long, and otherwise at 15 minutes. It returns
504witherror.type: timeout_. Nothing is charged yet, and the hold stays reserved, because the provider may still have run it. The OpenAI endpoints useerror error.code: upstream_. A stream has no deadline of its own, but the same 5-minute header or body stalls end it. Before headers that costs zero. After headers, a reported cost is charged plus OpenRouter's 5% platform fee. Deference adds no markup. Stream long requests.timeout
Response
{
"id": "msg_01Ab3xQz9k",
"type": "message",
"role": "assistant",
"model": "anthropic/claude-sonnet-5.5",
"content": [{ "type": "text", "text": "Hello, nice to meet you." }],
"stop_reason": "end_turn",
"usage": { "input_tokens": 14, "output_tokens": 9 }
}usage also reports cache_ and cache_read_input_tokens when caching applies.
Errors
Errors use Anthropic's envelope with type: "error" and Deference's request_id. The x-request-id and request-id headers carry the same id. See Errors.