> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixroute.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Smart Routing API

> Create and configure Smart Routing keys, model tiers, inference, and routing statistics.

## Overview

Smart Routing automatically selects a model from a configured model pool according to request complexity. In the System API, a route is represented by an API-key record with `smart_routing: true`; it uses the same `/api/token/` create, update, status, reveal, and delete endpoints as a standard key.

| Console label | API field | Purpose                          |
| ------------- | --------- | -------------------------------- |
| Simple        | `simple`  | Fast and cost-efficient requests |
| Complex       | `complex` | More demanding tasks             |
| Ultra         | `super`   | Highest-capability baseline tier |

The stored tier object also contains `reasoning`. The current console sets it to the same model as `simple` for compatibility.

<Warning>
  `smart_route_tiers` is a JSON-encoded string. Do not send it as a nested JSON object.
</Warning>

## Read the current presets

Preset model IDs are deployment configuration. Retrieve them from `/api/status` instead of copying model names from screenshots:

```bash theme={null}
status_response=$(curl -fsS "$BASE_URL/api/status")

jq -e '
  .success == true
  and .data.smart_routing_enabled == true
  and (.data.smart_routing_model_aliases | index("auto") != null)
' <<< "$status_response" >/dev/null

presets=$(jq -er '.data.smart_routing_presets | fromjson' \
  <<< "$status_response")

jq '.' <<< "$presets"
```

The first check stops the workflow when Smart Routing is disabled or `auto` is not advertised as a routing alias.

Select a preset and normalize the compatibility field:

```bash theme={null}
tiers=$(jq -ce '
  .[0].pools
  | .reasoning = .simple
  | {simple, reasoning, complex, super}
  | select(all(.[]; type == "string" and length > 0))
' <<< "$presets")
```

Verify that all three active tiers contain model IDs available to the selected group. Compare them case-insensitively against `.data.smart_routing_excluded_models`; excluded models cannot be selected.

## Create a Smart Routing key

```bash theme={null}
name="smart-route-$(date +%s)-$RANDOM"

payload=$(jq -n \
  --arg name "$name" \
  --arg tiers "$tiers" '{
    name: $name,
    expired_time: -1,
    remain_quota: 0,
    unlimited_quota: true,
    model_limits_enabled: false,
    model_limits: "",
    allow_ips: "",
    group: "default",
    cross_group_retry: false,
    smart_routing: true,
    smart_route_tiers: $tiers
  }')

curl -fsS -X POST "$BASE_URL/api/token/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  -H "Content-Type: application/json" \
  -d "$payload" | jq
```

Creation does not return an ID. Locate the route with `exclude_smart_routing=false`:

```bash theme={null}
route=$(curl -fsS --get "$BASE_URL/api/token/search" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  --data-urlencode "keyword=$name" \
  --data-urlencode "exclude_smart_routing=false" \
  --data-urlencode "p=1" \
  --data-urlencode "size=10")

route_id=$(jq -er --arg name "$name" '
  [.data.items[]
    | select(.name == $name and .smart_routing == true)]
  | if length == 1 then .[0].id
    else error("expected exactly one matching Smart Routing key")
    end
' <<< "$route")
```

## Update the model pool

Read the current record and modify the decoded tier configuration. The update body must preserve every other mutable field.

```bash theme={null}
current=$(curl -fsS "$BASE_URL/api/token/$route_id" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID")

new_tiers=$(jq -cer '
  .data.smart_route_tiers
  | fromjson
  | .complex = "YOUR_COMPLEX_MODEL"
  | .reasoning = .simple
' <<< "$current")

update_payload=$(jq --arg tiers "$new_tiers" '.data | {
  id,
  name,
  expired_time,
  remain_quota,
  unlimited_quota,
  model_limits_enabled,
  model_limits,
  allow_ips,
  group,
  cross_group_retry,
  smart_routing,
  smart_route_tiers
} | .smart_routing = true | .smart_route_tiers = $tiers' <<< "$current")

curl -fsS -X PUT "$BASE_URL/api/token/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  -H "Content-Type: application/json" \
  -d "$update_payload" | jq
```

Changes apply to subsequent requests made with the route key.

## Reveal and use the route key

```bash theme={null}
stored_key=$(curl -fsS -X POST "$BASE_URL/api/token/$route_id/key" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  | jq -er '.data.key')

route_api_key="sk-${stored_key#sk-}"
```

Use the inference endpoint and set `model` to `auto`:

```bash theme={null}
curl -fsS https://api.mixroute.ai/v1/chat/completions \
  -H "Authorization: Bearer $route_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [
      {"role":"user","content":"Summarize the tradeoffs of this architecture."}
    ]
  }' | jq
```

Do not send the system access token to the inference endpoint.

## Routing statistics

Read aggregate statistics for all route keys:

```bash theme={null}
curl -fsS "$BASE_URL/api/token/smart_route/stats" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" | jq
```

Filter by key and Unix-second time range:

```bash theme={null}
curl -fsS --get "$BASE_URL/api/token/smart_route/stats" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "New-Api-User: $USER_ID" \
  --data-urlencode "token_id=$route_id" \
  --data-urlencode "start=START_UNIX_SECONDS" \
  --data-urlencode "end=END_UNIX_SECONDS" | jq
```

The response includes `requests`, `actual_quota`, `saved_quota`, `daily` entries with `baseline` and `actual`, `tier_dist`, and `trial_start_ts`.

Read current service-fee and trial configuration from `/api/status`:

```bash theme={null}
curl -fsS "$BASE_URL/api/status" | jq '{
  trial_days: .data.smart_routing_free_trial_days,
  service_fee_percent: .data.smart_routing_service_fee_percent
}'
```

## Operational constraints

* Requests use the OpenAI-compatible `/v1/chat/completions` format.
* Claude targets are accessed through OpenAI compatibility mode, so Claude-native-only features may not be available.
* Switching target models can prevent provider-side prompt-cache reuse.
* Disable a route through the status-only update endpoint before deleting it when rotating production credentials.

For the console workflow and integration links, see [Smart Routing](/en/api-reference/smart-routing).
