Skip to navigation

Claude Messages

Call Claude Fable 5.1, Opus 5.5, Sonnet 5.5 and Haiku 5.5 through one Anthropic Messages endpoint with a BeatAPI key.

  • One endpoint, POST /v1/messages, for every current Claude model. Change model to switch.
  • Text and image input, text output, streaming, tool use, extended thinking and prompt caching.
  • Works with the Anthropic SDK: set the base URL to https://direct.beatapi.io (without /v1) and use a BeatAPI key.
  • Claude models answer only on Anthropic Messages. A call to /v1/responses returns 400.

Use https://direct.beatapi.io as the base URL for text requests: it is not subject to Cloudflare’s 100-second limit, so a long non-streaming request is not cut off. https://api.beatapi.io also works and is the fallback if direct.beatapi.io is unreachable from your network. The key, models and prices are the same on both. Image and video APIs use https://api.beatapi.io only.

POST/v1/messagesTry it

Opens this endpoint in the API Explorer. Enter your BeatAPI API key and send: the call is real and is billed to your own balance.

Models

Send one of these IDs as model. Each is a separate model; do not treat them as aliases of each other.

Model IDContext (tokens)Max output (tokens)PositioningInput, USD per 1M tokensOutput, USD per 1M tokensNotes
claude-opus-5-51,000,000128,000Claude Opus model for long-running agentic coding and knowledge work, priced below Opus 5$2.00$10.00Long-running agentic coding and knowledge work.
claude-sonnet-5-51,000,000128,000Claude Sonnet 5.5 for coding, reasoning, and professional work with a 1M-token context window.$1.00$5.00Everyday coding, reasoning and professional work.
claude-haiku-5-51,000,000128,000Fastest Claude model for high-volume, latency-sensitive work such as classification, extraction, and routing$0.05$0.25The fastest Claude, for high-volume work such as classification, extraction and routing.
claude-fable-5-11,000,000128,000Claude model for demanding reasoning and long-horizon agentic work$5.00$25.00Long-form writing and work where voice and structure matter most.
  • Prices are the base tier, discount already applied. A long-context tier, cached-input rates and cache writes are not in this table; see the price table.
  • — means the catalogue does not publish the number.

Older IDs of this family still work and are listed on Legacy models.

Quick start

Install the anthropic package on your server, keep the key in BEATAPI_API_KEY, and never put it in browser code. These are request examples, not recorded model outputs.

Read the answer from the text blocks in content, then check stop_reason and usage. An HTTP 200 alone does not prove the answer satisfies your task: validate it in your application. Text requests return directly; do not poll /v1/tasks for them.

curl --request POST \
--url https://direct.beatapi.io/v1/messages \
--header "x-api-key: $BEATAPI_API_KEY" \
--header 'anthropic-version: 2023-06-01' \
--header 'Content-Type: application/json' \
--data '{
"model": "claude-sonnet-5-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Design a resilient webhook retry strategy for a payments API."
}
]
}'

Endpoint and authentication

POST https://direct.beatapi.io/v1/messages

x-api-key string Required

Your BeatAPI key. Authorization: Bearer <BEATAPI_API_KEY> is also accepted.

Send the anthropic-version header, for example anthropic-version: 2023-06-01. The key goes in x-api-key or in Authorization: Bearer <key>; both work, so an existing Anthropic client only needs its base URL changed.

Claude models answer only on Anthropic Messages. Calling one on /v1/responses returns 400.

Request parameters

Standard Anthropic Messages fields are accepted. Request-format compatibility does not mean every beta feature or server tool is supported, so test the options you rely on.

model string Required

The exact model ID.

Allowed values: claude-fable-5-1, claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5

  • Older IDs that still work (claude-opus-5, claude-sonnet-5, claude-haiku-4-5-20251001) are on Legacy models.
  • Call GET /v1/models with your key to confirm which models are enabled for it.

max_tokens integer Required

Upper bound on the generated tokens, thinking included.

  • Always send it. If it is missing or 0, a default limit is applied, and that default may be lower than you expect.
  • The largest accepted value is 1,073,741,823; a larger value is 400 bad_request. Keep it at or below the max output of the model in the table above.
  • max_tokens is also used to estimate how much balance a request needs. A very large value can be refused with 402 insufficient_credits even when the real output would be small. Set it to what you need.

messages object[] Required

The conversation, oldest message first. Each message has a role (user or assistant) and content. content is a string, or an array of content blocks.

  • Block types you will use: text, image (base64 or URL source), tool_use (in an assistant message), and tool_result (in a user message).
  • An empty or missing messages array is 400 bad_request.

Example

[
{
"role": "user",
"content": [
{ "type": "text", "text": "What is in this image?" },
{ "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "<base64>" } }
]
}
]

system string | object[] Optional

System prompt. A string, or an array of text blocks. Put cache_control on a block to cache a long, stable prefix.

Example

[
{
"type": "text",
"text": "<long, stable instructions>",
"cache_control": { "type": "ephemeral" }
}
]

stream boolean OptionalDefault: false

Return the answer as server-sent events. See the Streaming section below.

Default: false

stop_sequences string[] Optional

Custom strings that stop generation. The response then has stop_reason: "stop_sequence".

tools object[] Optional

Tools the model may call. Each has a name, a description and an input_schema (JSON Schema). When the model calls one, the answer has stop_reason: "tool_use"; run the tool and return the result in a following tool_result block.

Example

[
{
"name": "get_weather",
"description": "Get the current weather for a city.",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
]

tool_choice object Optional

Whether and how the model must use tools.

Allowed values: {"type":"auto"}, {"type":"any"}, {"type":"tool","name":"..."}, {"type":"none"}

  • auto lets the model decide, any forces some tool, tool forces the named tool, none forbids tools.

Example

{ "type": "auto" }
{ "type": "tool", "name": "get_weather" }

thinking object Optional

Extended thinking. Set type to turn it on or off. Thinking tokens count toward max_tokens and are billed as output tokens.

Allowed values: adaptive, enabled, disabled

  • thinking.type is one of the values above. enabled takes thinking.budget_tokens (an integer of at least 1,024, below max_tokens).
  • thinking.display is summarized or omitted. Newer models may return no thinking text unless you ask for summarized.
  • Set the depth of adaptive thinking with output_config.effort.

Per model

  • claude-fable-5-1: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.
  • claude-opus-5-5: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.
  • claude-sonnet-5-5: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.

Example

{
"thinking": { "type": "adaptive" },
"output_config": { "effort": "high" }
}

output_config.effort string Optional

How much reasoning the model does. Start with high, then evaluate one level lower and higher on your own workload.

Allowed values: low, medium, high, xhigh, max

cache_control object Optional

Prompt caching. Put it on a system, messages or tools block to cache everything up to that block, or at the top level of the request. ttl is 5m (default) or 1h.

Allowed values: {"type":"ephemeral"}

  • Cache reads, 5-minute cache writes and 1-hour cache writes are metered separately; a cached prefix is charged as a cache read, not as fresh input.
  • The cache hit counts are in usage.cache_read_input_tokens and usage.cache_creation_input_tokens.

Example

{ "type": "ephemeral" }
{ "type": "ephemeral", "ttl": "1h" }

Tool use loop

When stop_reason is tool_use, append the assistant message as it was returned, run the tool, and send the result in a tool_result block of the next user message. Send the same tools again.

{
"max_tokens": 1024,
"messages": [
{ "role": "user", "content": "What is the weather in Paris?" },
{
"role": "assistant",
"content": [
{ "type": "tool_use", "id": "toolu_example", "name": "get_weather", "input": { "city": "Paris" } }
]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_example", "content": "18 C, light rain" }
]
}
]
}

Response

A non-streaming call returns one JSON object. This is an abbreviated example.

{
"id": "msg_example",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5-5",
"content": [
{
"type": "text",
"text": "Retry with exponential backoff and jitter, and make every handler idempotent."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 19,
"output_tokens": 16
}
}

Response fields

FieldTypeDescription
idstringThe message ID. Log it, together with the request ID, for support and billing audits.
modelstringThe model that answered.
content[].typestringtext, tool_use, or thinking when thinking text is returned.
content[].textstringThe answer text of a text block.
stop_reasonstringend_turn for a complete answer, max_tokens when max_tokens was reached, stop_sequence, or tool_use when the model calls a tool.
usage.input_tokensintegerInput tokens that were not served from the cache.
usage.output_tokensintegerOutput tokens, thinking included.
usage.cache_read_input_tokensintegerInput tokens read from the prompt cache.
usage.cache_creation_input_tokensintegerInput tokens written to the prompt cache.

Streaming

Set "stream": true. The response is a stream of Anthropic server-sent events, compatible with the Anthropic SDK.

  • The events are message_start, ping, content_block_start, content_block_delta, content_block_stop, message_delta and message_stop.
  • Text arrives in text_delta, tool input in input_json_delta (concatenate the fragments, then parse), and thinking text in thinking_delta.
  • stop_reason and the final output token count arrive in message_delta.
  • The response is text/event-stream; without streaming it is application/json. A failure before the model is called is returned as a normal JSON error with an HTTP status, not as a stream event.
  • Set explicit timeouts and reconnect a streamed response safely.
event: message_start
data: {"type":"message_start","message":{"id":"msg_example","type":"message","role":"assistant","model":"claude-sonnet-5-5","content":[],"stop_reason":null,"usage":{"input_tokens":19,"output_tokens":1}}}
event: ping
data: {"type":"ping"}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Retry"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" with backoff"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":16}}
event: message_stop
data: {"type":"message_stop"}

Errors

Error or symptomCauseFix
400: missing messages or model, or max_tokens too largemessages is empty or absent, model is empty, or max_tokens is above 1,073,741,823.Send both fields and a max_tokens within the limit.
400 on /v1/responsesClaude models are not served on OpenAI Responses.Call POST /v1/messages.
400 about a thinking settingThe model does not accept that setting, for example budget_tokens on a model that uses adaptive thinking.Use the setting listed for the model under thinking above.
402 insufficient_creditsBalance below the price of the request, often because max_tokens is very large.Top up, or lower max_tokens.
403 forbiddenThe account is on free credit and the model is not on the free list, or the model is outside the key’s group.Top up, use a free model, or use a key whose group can reach the model.
404 not_foundUnknown model ID, or not enabled for this key.List the enabled models with GET /v1/models.
429 rate_limit_exceededAccount or free-model limit reached.Wait Retry-After, then retry.
200 with stop_reason: "max_tokens" and a short or empty answermax_tokens was used up, often by thinking, before the answer was written.Raise max_tokens, or lower output_config.effort.

HTTP errors at a glance

Authentication, routing, rate-limit and unknown-model failures are answered before the model is called, in the BeatAPI envelope: error.code, error.message, retryable, request_id. Every other failure keeps the Anthropic shape {"type": "error", "error": {"type", "message"}}: the code is in error.type and the request id ends message. See Errors.

HTTP statusCodeWhat to do
400bad_request, content_policy_violationFix the request or the input; do not resend it unchanged.
401missing_api_key, invalid_api_keyCheck the key. Do not retry.
402insufficient_creditsTop up, or raise the key’s limit. A very large max_tokens can trigger it.
403forbiddenThe model is outside the key’s group or IP allowlist, or free credit cannot call this model.
404not_foundUnknown model: list the enabled ones with GET /v1/models.
429rate_limit_exceededWait Retry-After or retry_after_seconds, then retry with backoff.
500internal_error, temporary_errorRetry once or twice with backoff.
503model_unavailable, upstream_timeout, temporary_errorRetry with backoff, or use another model.

Full code table and retry policy: Errors.

Notes

  • Claude models answer only on Anthropic Messages, not on OpenAI Responses.
  • Thinking tokens are billed as output tokens and count toward max_tokens. Budget enough output for thinking plus the answer.
  • Keep API keys on trusted servers, log the response request ID, and retry only 429, 500 and 503.

Authentication

AuthorizationBearer

Send your API key as Authorization: Bearer <BEATAPI_API_KEY>.

Request

This endpoint expects an object.
modelenumRequired

The exact model ID.

Older IDs that still work (claude-opus-5, claude-sonnet-5, claude-haiku-4-5-20251001) are on Legacy models.

Call GET /v1/models with your key to confirm which models are enabled for it.

claude-fable-5-1, claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5

Allowed values:
max_tokensintegerRequired

Upper bound on the generated tokens, thinking included.

Always send it. If it is missing or 0, a default limit is applied, and that default may be lower than you expect.

The largest accepted value is 1,073,741,823; a larger value is 400 bad_request. Keep it at or below the max output of the model in the table above.

max_tokens is also used to estimate how much balance a request needs. A very large value can be refused with 402 insufficient_credits even when the real output would be small. Set it to what you need.

messageslist of objectsRequired

The conversation, oldest message first. Each message has a role (user or assistant) and content. content is a string, or an array of content blocks.

Block types you will use: text, image (base64 or URL source), tool_use (in an assistant message), and tool_result (in a user message).

An empty or missing messages array is 400 bad_request.

systemstring or list of objectsOptional

System prompt. A string, or an array of text blocks. Put cache_control on a block to cache a long, stable prefix.

streambooleanOptionalDefaults to false

Return the answer as server-sent events. See the Streaming section below.

stop_sequenceslist of stringsOptional

Custom strings that stop generation. The response then has stop_reason: "stop_sequence".

toolslist of objectsOptional

Tools the model may call. Each has a name, a description and an input_schema (JSON Schema). When the model calls one, the answer has stop_reason: "tool_use"; run the tool and return the result in a following tool_result block.

tool_choiceobjectOptional

Whether and how the model must use tools.

auto lets the model decide, any forces some tool, tool forces the named tool, none forbids tools.

{"type":"auto"}, {"type":"any"}, {"type":"tool","name":"..."}, {"type":"none"}

thinkingobjectOptional

Extended thinking. Set type to turn it on or off. Thinking tokens count toward max_tokens and are billed as output tokens.

thinking.type is one of the values above. enabled takes thinking.budget_tokens (an integer of at least 1,024, below max_tokens).

thinking.display is summarized or omitted. Newer models may return no thinking text unless you ask for summarized.

Set the depth of adaptive thinking with output_config.effort.

claude-fable-5-1: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.

claude-opus-5-5: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.

claude-sonnet-5-5: Use {"type":"adaptive"} and set depth with output_config.effort; budget_tokens is rejected.

adaptive, enabled, disabled

output_configobjectOptional
cache_controlobjectOptional

Prompt caching. Put it on a system, messages or tools block to cache everything up to that block, or at the top level of the request. ttl is 5m (default) or 1h.

Cache reads, 5-minute cache writes and 1-hour cache writes are metered separately; a cached prefix is charged as a cache read, not as fresh input.

The cache hit counts are in usage.cache_read_input_tokens and usage.cache_creation_input_tokens.

{"type":"ephemeral"}

Response

A non-streaming call returns one JSON object. This is an abbreviated example.

idstringOptional
The message ID. Log it, together with the request ID, for support and billing audits.
modelstringOptional
The model that answered.
contentlist of objectsOptional
stop_reasonstringOptional

end_turn for a complete answer, max_tokens when max_tokens was reached, stop_sequence, or tool_use when the model calls a tool.

usageobjectOptional

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
403
Forbidden Error
404
Not Found Error
429
Too Many Requests Error
500
Internal Server Error
503
Service Unavailable Error