Reasoning
Solve harder problems by giving the model more time to think. Muse Spark is a reasoning model: it generates internal reasoning tokens before visible output, and you control how much with reasoning_effort.
How it works
When you send a request, the model works through the problem internally first. That reasoning stays private and does not appear in the response body. Reasoning tokens count toward your output-token budget (max_tokens on Chat Completions, max_output_tokens on the Responses API) and toward billed completion tokens.
Set reasoning_effort to choose depth:
| Value | Behavior |
|---|---|
"none" | Disables reasoning. Not supported by Muse Spark: returns HTTP 400. |
"minimal" | Shortest reasoning pass. |
"low" | Light reasoning. |
"medium" | Moderate depth. |
"high" | Deep reasoning. |
"xhigh" | Deeper reasoning. |
"max" | Extended reasoning beyond "xhigh". Standard-tier muse-spark-1.3 only; not available on Contributor-tier models. |
Higher effort means more reasoning — and more reasoning tokens, latency, and cost. "none" disables reasoning entirely, which Muse Spark does not support.
When you omit the parameter, the model still reasons at a model-determined level.
Usage
Chat Completions
Send reasoning_effort at the top level of a chat completion request:
pythonimport osfrom openai import OpenAIclient = OpenAI(base_url="https://api.meta.ai/v1",api_key=os.environ["MODEL_API_KEY"],)response = client.chat.completions.create(model="muse-spark-1.3",reasoning_effort="high",messages=[{"role": "user","content": "Prove that the square root of 2 is irrational.",},],)print(response.model_dump_json(indent=2))
typescriptimport OpenAI from 'openai';const apiKey = process.env.MODEL_API_KEY;if (!apiKey) {throw new Error('MODEL_API_KEY is not set');}const client = new OpenAI({baseURL: 'https://api.meta.ai/v1',apiKey,});const response = await client.chat.completions.create({model: 'muse-spark-1.3',reasoning_effort: 'high',messages: [{role: 'user',content: 'Prove that the square root of 2 is irrational.',},],});console.log(JSON.stringify(response, null, 2));
pythonimport jsonimport osimport requestsresponse = requests.post("https://api.meta.ai/v1/chat/completions",headers={"Authorization": f"Bearer {os.environ['MODEL_API_KEY']}","Content-Type": "application/json",},json={"model": "muse-spark-1.3","reasoning_effort": "high","messages": [{"role": "user","content": "Prove that the square root of 2 is irrational.",},],},)response.raise_for_status()print(json.dumps(response.json(), indent=2))
shellcurl -X POST "https://api.meta.ai/v1/chat/completions" \-H "Authorization: Bearer $MODEL_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "muse-spark-1.3","reasoning_effort": "high","messages": [{"role": "user","content": "Prove that the square root of 2 is irrational."}]}'
Responses API
On the Responses API, nest the same control as reasoning.effort:
pythonimport osfrom openai import OpenAIclient = OpenAI(base_url="https://api.meta.ai/v1",api_key=os.environ["MODEL_API_KEY"],)response = client.responses.create(model="muse-spark-1.3",reasoning={"effort": "high",},input="Prove that the square root of 2 is irrational.",)print(response.model_dump_json(indent=2))
typescriptimport OpenAI from 'openai';const apiKey = process.env.MODEL_API_KEY;if (!apiKey) {throw new Error('MODEL_API_KEY is not set');}const client = new OpenAI({baseURL: 'https://api.meta.ai/v1',apiKey,});const response = await client.responses.create({model: 'muse-spark-1.3',reasoning: {effort: 'high',},input: 'Prove that the square root of 2 is irrational.',});console.log(JSON.stringify(response, null, 2));
pythonimport jsonimport osimport requestsresponse = requests.post("https://api.meta.ai/v1/responses",headers={"Authorization": f"Bearer {os.environ['MODEL_API_KEY']}","Content-Type": "application/json",},json={"model": "muse-spark-1.3","reasoning": {"effort": "high",},"input": "Prove that the square root of 2 is irrational.",},)response.raise_for_status()print(json.dumps(response.json(), indent=2))
shellcurl -X POST "https://api.meta.ai/v1/responses" \-H "Authorization: Bearer $MODEL_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "muse-spark-1.3","reasoning": {"effort": "high"},"input": "Prove that the square root of 2 is irrational."}'
Log probabilities
Muse Spark is a reasoning model, so logprobs is not supported. logprobs: true (Chat Completions) and include: ["message.output_text.logprobs"] (Responses API) both return HTTP 400.
Multi-turn reasoning
You can carry reasoning context across turns so follow-ups build on earlier thinking. How you preserve it depends on the endpoint.
Responses API
Chain turns with previous_response_id. The server keeps reasoning context for you:
json{"model": "muse-spark-1.3","reasoning": {"effort": "high"},"input": "Now extend the proof to show that the square root of 3 is also irrational.","previous_response_id": "resp_abc123"}
For stateless replay, where you manage history yourself instead of chaining response IDs, request the model's encrypted reasoning with include: ["reasoning.encrypted_content"] and replay it as a reasoning input item on the next turn. See reasoning items in multi-turn input for the full pattern.
Chat Completions
Chat Completions cannot carry reasoning across turns for external API keys. Assistant messages expose a reasoning_content field, but it holds the model's private chain of thought and is redacted to empty before the response reaches an external caller, so there is nothing to replay and each turn reasons from scratch. It is populated only for internal callers holding the internal:private_cot attribute. Do not rely on reasoning_content for multi-turn continuity on this endpoint. For multi-step and agentic workloads where preserving chain of thought matters, use the Responses API above, which replays reasoning through encrypted content or previous_response_id.
Reasoning summaries
The raw chain of thought stays private, but on the Responses API you can request a natural-language summary of it. Set reasoning.summary to "auto", "concise", or "detailed":
json{"model": "muse-spark-1.3","reasoning": {"effort": "high", "summary": "auto"},"input": "Prove that the square root of 2 is irrational."}
Each profile controls how much reasoning the summary captures:
| Profile | Behavior |
|---|---|
"auto" | Compact summary, typically about one sentence. Best for most use cases. |
"concise" | Brief multi-sentence summary focused on the key reasoning steps. |
"detailed" | Longer summary that preserves more of the reasoning chain's structure. |
Summary length varies with reasoning complexity; these are targets, not guarantees.
When a summary is generated, it is returned in the summary array of the response's reasoning output item, and in streaming mode it is delivered as response.reasoning_summary_text.delta / response.reasoning_summary_text.done events.
Request summaries with the reasoning.summary field; the older generate_summary alias is deprecated and does not request one. A summary is human-readable explanatory text, distinct from the opaque encrypted_content used for multi-turn replay. Reasoning summaries are a Responses API feature. Chat Completions does not expose reasoning.summary.
Token usage
Reasoning tokens count toward both your output-token limit and billed completion tokens:
- Output-token limit:
max_tokens(Chat Completions) andmax_output_tokens(Responses API) cap reasoning tokens plus visible output tokens combined. If the model spends most of the budget on reasoning, the visible response may be truncated. Set the limit high enough to accommodate both. - Billing: Reasoning tokens are billed at the same rate as visible output tokens. The
usagebreakdown reports them separately ascompletion_tokens_details.reasoning_tokens(Chat Completions) oroutput_tokens_details.reasoning_tokens(Responses API).
Higher reasoning_effort produces more reasoning tokens, which means longer latency and higher cost. Use the lowest level that gives you acceptable results. At "max", reasoning tokens make up a larger share of output_tokens than at lower efforts, so set the output-token limit generously.
When to reach for reasoning
Higher reasoning effort helps with multi-step problem solving: proofs and calculations, complex code generation, architecture trade-off analysis, and task planning and sequencing.
For direct-answer tasks, such as lookups, formatting, and translation, set reasoning_effort to "low" for faster responses at lower cost. (Muse Spark does not support "none"; see How it works.)
Constraints
- Log probabilities: Not supported. Muse Spark is a reasoning model, so
logprobs: truereturnsHTTP 400. See Log probabilities. - Raw reasoning is not exposed as text: The model's chain of thought is private. The raw reasoning is not returned as readable text in the response body and is not emitted as stream events; only the visible output and, if you request one, a reasoning summary, is streamed. On the Responses API, the raw reasoning is available solely as encrypted content for replay via
include: ["reasoning.encrypted_content"]. During built-in tool loops (for example, when the model runsweb_search), reasoning output items appear with emptycontentso output indices stay stable, and no visible reasoning text is exposed. When you setinclude: ["reasoning.encrypted_content"], those items still carryencrypted_content, so stateless replay works across tool-loop turns. - Streaming: Because the model reasons before producing visible output, expect an initial latency before the first visible content chunk in streaming mode.
- Output-token limit: Covers reasoning plus visible output. Set it high enough to accommodate both.
Next steps
- Ship a reasoning conversation with Responses API, or keep it stateless with chat completion.
- Constrain a reasoned answer to a schema with structured output.
- Build multi-step agents that replay reasoning across turns with tool calling.