Skip to navigation

Muse Messages

Call Muse Wonder in the Anthropic Messages format with a BeatAPI key.

  • One endpoint, POST /v1/messages, for Muse Wonder.
  • Streaming and tool use, with a 1M-token context window.
  • Works with the Anthropic SDK: change the base URL and use a BeatAPI key. Send the anthropic-version header with every request.
  • tool_choice is passed to the model, though not every model enforces it; thinking does not take effect. See the parameter reference below.

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 this ID as model.

Model IDContext (tokens)Max output (tokens)PositioningInput, USD per 1M tokensOutput, USD per 1M tokensNotes
muse-wonder1,048,576131,072Meta Muse Wonder: a frontier reasoning model for complex personal and professional agentic work.$4.00$20.00Meta’s frontier reasoning model for complex personal and professional agentic work. Needs a funded account.
  • 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.

Quick start

Install the @anthropic-ai/sdk or anthropic package on your server, keep the key in BEATAPI_API_KEY, and never put it in browser code. The SDK sends the anthropic-version header for you. These are request examples, not recorded model outputs.

Read the answer from the text blocks of 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": "muse-wonder",
"max_tokens": 2000,
"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 2023-06-01) with every request; the Anthropic SDK adds it automatically. For authentication, x-api-key and Authorization: Bearer <BEATAPI_API_KEY> both work.

Request parameters

The request uses the Anthropic Messages shape. The fields below take effect; the last two are accepted by the SDK but do not change the result. A field that is not listed on this page is not guaranteed to have any effect.

model string Required

The exact model ID.

Allowed values: muse-wonder

  • Each ID is a separate model, not an alias of another.
  • 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, reasoning included.

  • The gateway does not compare your value with the model’s max output from the table above. Keep it at or below that number.
  • 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.

A reasoning model writes its reasoning first. If max_tokens is too small, the reasoning can use all of it: the text block is empty and stop_reason is max_tokens. Leave room for both, and raise the value when you see max_tokens.

messages object[] Required

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

  • Text blocks (text), the model’s tool requests (tool_use) and your results (tool_result) take effect.
  • A tool_result block must carry the tool_use_id of the tool_use block it answers.

system string | object[] Optional

The system prompt: a string, or an array of text blocks. The text blocks are joined into one system prompt.

stream boolean OptionalDefault: false

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

Default: false

temperature number Optional

Sampling temperature. Change this or top_p, not both.

top_p number Optional

Nucleus sampling threshold.

stop_sequences string[] Optional

Sequences at which generation stops.

tools object[] Optional

Tool definitions the model may call. Each tool takes effect through its name, description and input_schema. The model answers with a tool_use block; return the result in a tool_result block of the next user message.

tool_choice object Optional

How the model may use tools. {"type": "auto"} lets it decide (the default), {"type": "any"} makes it call one of the tools, {"type": "tool", "name": "..."} makes it call that tool, and {"type": "none"} stops it from calling any. disable_parallel_tool_use: true limits it to one call per answer. Ignored when tools is absent. The setting is passed to the model, but not every model enforces it: in our tests (2026-10-15) DeepSeek ignored it and Qwen enforced any but not a named tool, so check the answer for a tool_use block rather than assuming one.

thinking object Optional

Does not take effect. It neither turns reasoning on nor off, and it sets no reasoning budget. A model that reasons by default keeps doing so, and its reasoning comes back as thinking blocks.

Response

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

{
"id": "msg_example",
"type": "message",
"role": "assistant",
"model": "muse-wonder",
"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[]object[]Content blocks: thinking (on models that reason, before the answer), text and tool_use.
content[].textstringThe answer text of a text block.
stop_reasonstringend_turn for a complete answer, tool_use for a tool request, max_tokens when max_tokens was reached, stop_sequence when a stop sequence matched.
usageobjectinput_tokens and output_tokens. Reasoning counts as output. Calls are metered from actual token usage.

Streaming

Set "stream": true. The stream starts with message_start and ends with message_stop; the blocks in between arrive as content_block_start, content_block_delta and content_block_stop events, and message_delta carries the stop_reason.

  • The response is text/event-stream; without streaming it is application/json.
  • Text arrives in text_delta events. A reasoning model sends a thinking block with thinking_delta events before the text block. Tool arguments arrive in input_json_delta events.
  • 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","content":[],"usage":{"input_tokens":19,"output_tokens":1}}}
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"},"usage":{"output_tokens":16}}
event: message_stop
data: {"type":"message_stop"}

Errors

Error or symptomCauseFix
The text block is empty and stop_reason is max_tokensA reasoning model used the whole max_tokens budget on reasoning.Raise max_tokens, within the model max output.
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.

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

  • Muse also answers on Chat Completions and OpenAI Responses.
  • muse-wonder requires a funded account. An account that only holds free credit cannot call it.
  • Muse Wonder reasons before it answers. Reasoning counts as output tokens and is billed as output.
  • Send anthropic-version with every request. Do not rely on thinking: it does not take effect.
  • 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.

Each ID is a separate model, not an alias of another.

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

muse-wonder

Allowed values:
max_tokensintegerRequired

Upper bound on the generated tokens, reasoning included.

The gateway does not compare your value with the model’s max output from the table above. Keep it at or below that number.

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.

A reasoning model writes its reasoning first. If max_tokens is too small, the reasoning can use all of it: the text block is empty and stop_reason is max_tokens. Leave room for both, and raise the value when you see max_tokens.

messageslist of objectsRequired

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

Text blocks (text), the model’s tool requests (tool_use) and your results (tool_result) take effect.

A tool_result block must carry the tool_use_id of the tool_use block it answers.

systemstring or list of objectsOptional

The system prompt: a string, or an array of text blocks. The text blocks are joined into one system prompt.

streambooleanOptionalDefaults to false

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

temperaturedoubleOptional

Sampling temperature. Change this or top_p, not both.

top_pdoubleOptional
Nucleus sampling threshold.
stop_sequenceslist of stringsOptional
Sequences at which generation stops.
toolslist of objectsOptional

Tool definitions the model may call. Each tool takes effect through its name, description and input_schema. The model answers with a tool_use block; return the result in a tool_result block of the next user message.

tool_choiceobjectOptional

How the model may use tools. {"type": "auto"} lets it decide (the default), {"type": "any"} makes it call one of the tools, {"type": "tool", "name": "..."} makes it call that tool, and {"type": "none"} stops it from calling any. disable_parallel_tool_use: true limits it to one call per answer. Ignored when tools is absent. The setting is passed to the model, but not every model enforces it: in our tests (2026-10-15) DeepSeek ignored it and Qwen enforced any but not a named tool, so check the answer for a tool_use block rather than assuming one.

thinkingobjectOptional

Does not take effect. It neither turns reasoning on nor off, and it sets no reasoning budget. A model that reasons by default keeps doing so, and its reasoning comes back as thinking blocks.

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

Content blocks: thinking (on models that reason, before the answer), text and tool_use.

stop_reasonstringOptional

end_turn for a complete answer, tool_use for a tool request, max_tokens when max_tokens was reached, stop_sequence when a stop sequence matched.

usageobjectOptional

input_tokens and output_tokens. Reasoning counts as output. Calls are metered from actual token usage.

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