Reasoning / thinking tokens
What you'll build: control how much Muse Spark thinks before answering, account for the tokens that thinking costs, and carry reasoning across turns with the Responses API.
| Section | API fundamentals |
| Capabilities | Reasoning |
| Time to complete | ~10 min |
| Model | muse-spark-1.3 |
| Language | Python |
| Prerequisites | the chat completions recipe, Python 3.10+, the openai package, and a MODEL_API_KEY. |
Muse Spark is a reasoning model: it works through a problem internally before producing an answer. You set the depth with reasoning_effort, and the thinking shows up in usage as reasoning_tokens. See the chat completion guide and the Responses API guide.
Setup
One cell wires up the client: it reads your key from the environment and falls back to Colab secrets when you run in a notebook.
pythonimport osfrom openai import OpenAI# Auth: in Colab, read the key from the secrets manager (the key icon in the# left sidebar); otherwise read the MODEL_API_KEY environment variable.try:from google.colab import userdataapi_key = userdata.get("MODEL_API_KEY")except Exception:api_key = os.environ.get("MODEL_API_KEY")if not api_key:raise RuntimeError("Set MODEL_API_KEY in your environment (or add it to Colab secrets).")# The OpenAI SDK does not auto-read MODEL_API_KEY, so pass it explicitly.client = OpenAI(base_url="https://api.meta.ai/v1", api_key=api_key)# Connectivity check: a one-line call that confirms the key and endpoint work.ping = client.chat.completions.create(model="muse-spark-1.3",messages=[{"role": "user", "content": "Reply with the single word: ready"}],)print(ping.choices[0].message.content)
Control how much the model thinks
reasoning_effort sets how much internal reasoning the model does before answering. Values run from minimal through low, medium, up to high: higher means more reasoning tokens and usually better answers on hard problems. Watch reasoning_tokens climb with the effort. (xhigh is accepted, but it maps to the same reasoning strength as high, so high is effectively the maximum.)
pythonquestion = ("A farmer has 17 sheep. All but 9 run away. He then buys 3 times as many as ""he has left. How many sheep does he have? Answer with just the number.")for effort in ("minimal", "low", "medium", "high"):response = client.chat.completions.create(model="muse-spark-1.3",messages=[{"role": "user", "content": question}],reasoning_effort=effort,)reasoning_tokens = response.usage.completion_tokens_details.reasoning_tokensanswer = response.choices[0].message.content.strip()print(f"{effort:>8}: {reasoning_tokens:>4} reasoning tokens -> {answer[:20]}")
Reasoning tokens are output tokens
reasoning_tokens are part of completion_tokens: you pay for them as output and they count against your output-token budget, even though they never appear in the response text. Two things to know:
- The default effort (when you omit
reasoning_effort) is still being finalized, so this recipe doesn't assert a specific level. Set the parameter when the depth matters. - To spend the fewest reasoning tokens, set a low effort such as
minimal. The full spectrum isnone<minimal<low<medium<high, andxhighmaps to the same reasoning strength ashigh(sohighis the effective maximum). The API defines the string"none"to switch reasoning off — that's the string, not PythonNone, which leaves the parameter unset — but it isn't reliably available yet on the public endpoint, so verify before relying on it.
Match effort to the task
High effort on a simple task burns reasoning tokens for no benefit. Compare high and minimal on a trivial question: the answer is the same, the token bill is not.
pythontrivial = "What is 12 * 8? Reply with just the number."for effort in ("high", "minimal"):response = client.chat.completions.create(model="muse-spark-1.3",messages=[{"role": "user", "content": trivial}],reasoning_effort=effort,)reasoning_tokens = response.usage.completion_tokens_details.reasoning_tokensanswer = response.choices[0].message.content.strip()print(f"{effort:>8}: {reasoning_tokens:>4} reasoning tokens -> {answer}")
Same answer either way. Reserve high — the effective maximum — for genuinely hard problems and keep simple calls at minimal or low.
Reasoning is internal
The chain-of-thought is not returned as text on Chat Completions: the non-standard reasoning_content field is empty today on the public endpoint, so don't build on reading it here. You still see how much thinking happened through reasoning_tokens.
pythonresponse = client.chat.completions.create(model="muse-spark-1.3",messages=[{"role": "user", "content": "Name a prime number between 10 and 20."}],reasoning_effort="low",)message = response.choices[0].messageprint("answer:", message.content)print("reasoning_content:", (message.model_extra or {}).get("reasoning_content"))print("reasoning_tokens:", response.usage.completion_tokens_details.reasoning_tokens)
Get at the reasoning on the Responses API
The Responses API returns a reasoning output item. Its content is encrypted — you can replay it across turns, not read it — and the human-readable summary is empty for Muse Spark today. Request it with store=False and include=["reasoning.encrypted_content"].
pythonresp = client.responses.create(model="muse-spark-1.3",input="In one sentence, why is the sky blue?",reasoning={"effort": "low"},include=["reasoning.encrypted_content"],store=False,)print("output items:", [item.type for item in resp.output])for item in resp.output:if item.type == "reasoning":print("reasoning id:", item.id)print("summary:", item.summary)print("encrypted_content present:", bool(getattr(item, "encrypted_content", None)))print("answer:", resp.output_text)
Carry reasoning across turns
In a multi-step flow the model needs its earlier reasoning to stay consistent. The simplest way is to let the server keep it: pass previous_response_id and the server replays the stored reasoning and history for you. (A stateless client that holds its own history replays the encrypted reasoning item instead — see the Responses API guide.)
pythonfirst = client.responses.create(model="muse-spark-1.3",input="I'm planning a 3-day trip to Lisbon. Suggest one neighborhood to stay in.",)print("Turn 1:", first.output_text[:100], "...")followup = client.responses.create(model="muse-spark-1.3",input="Why that one over the alternatives?",previous_response_id=first.id,)print("Turn 2:", followup.output_text[:160])
Summary
| Pattern | How |
|---|---|
| Control depth | reasoning_effort: none < minimal < low < medium < high (xhigh = same strength as high) |
| Cost | reasoning_tokens are output tokens (usage.completion_tokens_details.reasoning_tokens) |
| Match effort | minimal/low for simple tasks, high for hard ones |
| Inspect | reasoning_content is empty on Chat today; Responses returns an encrypted reasoning item |
| Carry across turns | previous_response_id (server-managed), or replay the encrypted reasoning item |
Next steps
- Stream the answer while the model reasons first: recipe 02 — Streaming responses.
- Manage long agentic histories within the context window: recipe 08 — Long context.
- Read the chat completion guide and the Responses API guide.