# Models

GET /v1/agents/models

Lists the models a session can run on, with an `allowed` flag for the caller's plan. Ids from this list go in `model` on [`POST /message`](/documentation/api-reference/message).

## Request

```bash
curl -s "$SAI_API_URL/v1/agents/models" \
  -H "Authorization: Bearer $SAI_API_KEY"
```

## Response

```json
{
  "models": [
    {
      "id": "auto",
      "name": "Sai Agent",
      "provider": "anthropic",
      "tier": "balanced",
      "costTier": "$",
      "allowed": true
    },
    {
      "id": "anthropic/claude-sonnet-5",
      "name": "Claude 5 Sonnet",
      "provider": "anthropic",
      "tier": "balanced",
      "costTier": "$$",
      "allowed": true
    },
    {
      "id": "anthropic/claude-opus-5-5",
      "name": "Claude 5.5 Opus",
      "provider": "anthropic",
      "tier": "reasoning",
      "costTier": "$$$",
      "allowed": true
    },
    {
      "id": "google/gemini-3.8-flash",
      "name": "Gemini 3.8 Flash",
      "provider": "google",
      "tier": "fast",
      "costTier": "$",
      "allowed": true
    }
  ],
  "default": "auto"
}
```

The list is longer than shown; the ids above are real.

| Field      | Notes                                                              |
| ---------- | ------------------------------------------------------------------ |
| `id`       | Pass as `model`. `auto` lets Sai pick.                             |
| `name`     | Display name.                                                      |
| `provider` | `anthropic`, `google`, `openai`, `minimax`, `openrouter` or `xai`. |
| `tier`     | `reasoning`, `balanced` or `fast`.                                 |
| `costTier` | `free`, `$`, `$$` or `$$$`. Relative credit cost per task.         |
| `allowed`  | Whether this plan may use it. `auto` is always allowed.            |
| `default`  | The id used when a session has no model set: `auto`.               |

## Free plan

The free plan is limited to an allowlist; everything else is listed with `allowed: false`. Sending one of those returns `403` from `POST /message` with the allowed ids:

```json
{
  "error": "model_not_allowed_for_plan",
  "message": "The model \"anthropic/claude-opus-5-5\" is not available on the free plan. Upgrade to a paid plan to use it.",
  "allowedModels": ["auto", "deepseek/deepseek-v4-flash", "openrouter/deepseek/deepseek-v4-flash"]
}
```

The allowlist is a server setting and can change; read `allowed` rather than hard-coding ids.

## Gotchas

- The model is per session and sticks until you pass a different one. You do not need to send `model` on every message.
- `costTier` is relative. Credit charged for a task is shown in the portal.
- Call this once when you need a specific model, not before every task.
