# Reasoning

Source: https://aiand-docs-staging.pages.dev/capabilities/reasoning/

A reasoning model writes out its reasoning before it answers. These models list `reasoning` in `capabilities` on [`GET /v1/models`](/models/catalog/). Reasoning tokens are billed as output tokens, and usage counts them separately as `reasoning_tokens`.

## Chat Completions

The reasoning comes back beside `content` under two names, `reasoning_content` and `reasoning`, which always hold the same text. Engines and client libraries disagree on the name, so every model returns both. Read whichever one your client expects.

```json
"message": {
  "role": "assistant",
  "content": "391",
  "reasoning_content": "17 × 23 = 17 × 20 + 17 × 3 = 340 + 51 = 391.",
  "reasoning": "17 × 23 = 17 × 20 + 17 × 3 = 340 + 51 = 391."
}
```

When streaming, the reasoning arrives first as deltas carrying both fields, then the answer as `delta.content`:

```text
data: {"choices":[{"index":0,"delta":{"reasoning_content":"17 × 23","reasoning":"17 × 23"},"finish_reason":null}],...}
data: {"choices":[{"index":0,"delta":{"content":"391"},"finish_reason":null}],...}
```

```python
stream = client.chat.completions.create(
    model="moonshotai/kimi-k3",
    messages=[{"role": "user", "content": "What is 17 × 23?"}],
    stream=True,
)
for chunk in stream:
    if not chunk.choices:
        continue
    delta = chunk.choices[0].delta
    reasoning = getattr(delta, "reasoning_content", None)
    if reasoning:
        print(reasoning, end="")
    if delta.content:
        print(delta.content, end="")
```

<Aside>
  A client that shows only `delta.content` shows nothing while the model reasons. That is the reasoning step, not a stalled stream. `max_tokens` covers the reasoning and the answer together, so a low limit can end the reply inside the reasoning, with `finish_reason: "length"` and no `content`.
</Aside>

You don't need to send the reasoning back in later turns. If an assistant turn you send fills both fields, `reasoning_content` is the one used.

## Responses

The reasoning is an output item of type `reasoning`, ahead of the message. Its text is in `content[].text` (type `reasoning_text`) when the model returns it; `summary[].text` holds a summary instead, when one is produced. Usage counts it in `output_tokens_details.reasoning_tokens`.

## Messages

Ask for the reasoning with `thinking: { "type": "enabled" }`, or `"adaptive"`, which is accepted identically. It comes back as a `thinking` content block ahead of the text; when streaming, it arrives in `content_block_delta` events whose `delta.type` is `thinking_delta`. Without it you get the answer alone, unless the model put its whole reply inside the reasoning; that turn comes back as an ordinary `text` block. See [Messages](/api/messages/).

## Reasoning effort

Send a level in `reasoning_effort` on Chat Completions, `reasoning.effort` on Responses, and `reasoning_effort` or `output_config.effort` on Messages. Each model lists the levels it takes in `reasoning_efforts` on [`GET /v1/models`](/models/catalog/). The applied level comes back in [`X-Reasoning-Effort`](/reference/response-headers/). How each endpoint validates the level is described on its own page.
