# Get why Auto picked a reply's model

Return why Auto chose the model of one assistant reply: what it read in the message, the model, effort and speed it picked, the best option of another model, the priority it routed with and who set it, what the reply cost and how fast its first word came, and which retry directions are still worth offering.

Only a reply answered with `model: "auto"` has one. The same choice is announced during the turn as the [`response.model_selected`](/api-reference/objects/streaming-event-object) event; this endpoint is how a client reads it again later, for example when the person opens the model chip of an older reply. Choices are kept for 90 days.

## Authentication

Requires authentication (Bearer token or `x-api-key`). The caller must have the same access to the thread that [listing its messages](/api-reference/threads/messages) requires — owner, Space member with view-or-better, or a live-share joiner. Anyone else receives a `404`.

## Feature

Requires the Auto model to be switched on for the caller's organization. While it is off, every Auto model endpoint answers `404` with code `AUTO_MODEL_NOT_ENABLED`.

## Path Parameters

**`thread_id`** string required

The thread that owns the message (`thread_` prefix).

**`message_id`** string required

The assistant message (`msg_` prefix). Must be on this thread — a message id from another thread is a `404`.

## Language and organization

`summary` and `priority.set_by.name` are written in the reader's language: the `Accept-Language` header, else the language saved on the account, else `en-GB`. The Auto model switch is read for your current organization (the `X-Organization-Id` header, or the token's organization).

A reply in a thread you cannot open answers `404 THREAD_NOT_FOUND`, the same as for a thread that does not exist — including another member's thread in your own organization.

## Returns

Returns `200 OK`:

- **`message_id`** `string` — The assistant message (echoed).
- **`route_id`** `string` — The routing decision (`ard_` prefix); the same id `response.model_selected` carried.
- **`model`** `string` — The model key Auto picked.
- **`model_title`** `string | null` — Its customer-facing name.
- **`effort`** `string` — `off`, `low`, `medium`, `high` or `max`.
- **`speed_tier`** `string` — `standard` or `priority`.
- **`basis`** `string` — How the pick was made: `jev` (Auto read the message), `heuristic` (a quick read, used when the full read was not available in time), `sticky` (the same model as the previous reply) or `retry`.
- **`summary`** `string` — One line on the message, e.g. `Coding, hard, needs careful reasoning`.
- **`signals`** `object` — What Auto read in the message: `difficulty` (0 very easy to 4 very hard), `task` (`chat`, `writing`, `translation`, `coding`, `analysis`, `research`, `tool_work` or `extraction`), `deep_reasoning`, `stakes` (0 low to 2 high) and `quick_reply`.
- **`runner_up`** `object | null` — The best option of another model: `model`, `model_title`, `effort`, and `same_price_band` (true when its cost is within 25% of the pick's). `null` when there was none.
- **`priority`** `object` — `preset` (`balanced`, `faster`, `lower_cost`, `best_quality` or `custom`) and `set_by` (`layer` and `name` of the rule that set it).
- **`this_reply`** `object` — `cost_chf` (a decimal string), `first_word_s` (seconds until the first word) and `measured`. `measured` is `true` only when both figures were measured on this reply; `false` means they are the estimate Auto routed with, so show them as approximate.
- **`retry`** `object` — `smarter` and `faster`: whether to offer each retry direction. A direction this reply already exhausted is `false`.
- **`retry_exhausted`** `boolean` — True when this reply was a retry that found nothing stronger or faster allowed.
- **`feedback`** `string | null` — What the person did after this reply: `retry_smarter`, `retry_faster`, `regenerated` or `switched`.
- **`created_at`** `string` — When the route was chosen (ISO 8601).


## Code Examples

### cURL


```bash
curl https://api.aitronos.com/v1/threads/thread_8f3c/messages/msg_1a2b/route \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Python SDK


```python
from aitronos import Aitronos

client = Aitronos(api_key="your-api-key")

route = client.auto_model.get_message_route(thread_id="thread_8f3c", message_id="msg_1a2b")
print(route["model_title"], route["summary"])
```

### Python (requests)


```python
import requests

resp = requests.get(
    "https://api.aitronos.com/v1/threads/thread_8f3c/messages/msg_1a2b/route",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
)
route = resp.json()
print(route["model_title"], route["summary"])
```

### JavaScript


```javascript
const resp = await fetch(
  "https://api.aitronos.com/v1/threads/thread_8f3c/messages/msg_1a2b/route",
  { headers: { Authorization: "Bearer YOUR_TOKEN" } },
);
const route = await resp.json();
console.log(route.model_title, route.summary);
```

## Response Example


```json
{
  "message_id": "msg_7f3a9c2e1b4d4e8f9a0b1c2d3e4f5a6b",
  "route_id": "ard_0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e",
  "model": "ftg-4-pro",
  "model_title": "FTG 4 Pro",
  "effort": "high",
  "speed_tier": "standard",
  "basis": "jev",
  "summary": "Coding, hard, needs careful reasoning",
  "signals": {"difficulty": 3, "task": "coding", "deep_reasoning": true, "stakes": 1, "quick_reply": false},
  "runner_up": {"model": "ftg-4", "model_title": "FTG 4", "effort": "max", "same_price_band": true},
  "priority": {"preset": "balanced", "set_by": {"layer": "department", "name": "Support"}},
  "this_reply": {"cost_chf": "0.031", "first_word_s": 6.4, "measured": true},
  "retry": {"smarter": true, "faster": true},
  "retry_exhausted": false,
  "feedback": null,
  "created_at": "2026-10-24T12:00:00Z"
}
```

## Error Responses

A reply Auto did not route, a message of another thread, or a choice older than 90 days:


```json
{
  "success": false,
  "error": {
    "code": "AUTO_MODEL_ROUTE_NOT_FOUND",
    "message": "There's no Auto model choice recorded for this message.",
    "type": "client_error",
    "status": 404,
    "details": {"message_id": "msg_1a2b"},
    "trace_id": "0e41d8a2-6b3c-4f5d-9e7a-1b2c3d4e5f6a",
    "timestamp": "2026-10-27T04:52:06Z"
  }
}
```

A thread you cannot open, including another member's thread in your organization:


```json
{
  "success": false,
  "error": {
    "code": "THREAD_NOT_FOUND",
    "message": "The requested thread could not be found.",
    "type": "client_error",
    "status": 404,
    "details": {"thread_id": "thread_8f3c"},
    "trace_id": "3c9f1e7b-2a4d-4b6e-8f0a-5d7c9e1b3a5f",
    "timestamp": "2026-10-27T04:52:06Z"
  }
}
```

The Auto model is switched off for the organization:


```json
{
  "success": false,
  "error": {
    "code": "AUTO_MODEL_NOT_ENABLED",
    "message": "Auto isn't available for this organisation.",
    "type": "client_error",
    "status": 404,
    "details": {"feature": "auto_model"},
    "trace_id": "5c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
    "timestamp": "2026-10-27T04:51:33Z"
  }
}
```

## Related Resources

- [Auto Model concept](/docs/documentation/core-concepts/auto-model)
- [Auto model route object](/api-reference/objects/auto-model-route-object)
- [List a thread's messages](/api-reference/threads/messages)
- [Streaming events](/api-reference/objects/streaming-event-object)