# Каналы

Канал модели обозначен цветом: `red` «Красный», `blue` «Синий» и т. д. Цвет за каналом
постоянен; цена, скорость и доступность меняются. Цвет не говорит о цене или скорости; один
цвет у двух моделей — разные каналы.

## Каналы модели — `GET /v1/models/{id}/channels`

Без ключа. По каждому каналу (схема `ModelChannels`):

- `id`, `name`, `color` — цвет, его название и HEX; `available` — принимает ли канал
  запросы сейчас;
- `rates` — ставки в микроединицах `currency`; `basis` — единица: `tokens` — 1M токенов
  (`input`, `output`, `cache_read`), `second`, `character`, `default_request` — запрос с
  параметрами по умолчанию (`request`); канал, который их не принимает, показывает цену
  запроса с первыми подходящими ему параметрами, точная цена для своих параметров — в
  превью роутинга. `null` — данных нет, а не нулевая цена. У канала с
  [динамической ценой](https://souz.ai/docs/pricing.md#динамическая-цена) (`dynamic: true`) `tokens` — цены, по которым
  считается итог, за 1M токенов: `input` — текст на входе, `output` — изображение или звук
  на выходе, `image_input` — изображения на входе и `reference_image` — оценка одного
  референса в деньгах (у речи оба `null`); у остальных каналов `tokens: null`;
- `parameters` — поддерживаемые параметры канала. Например, `"quality": {"enum": ["medium", "high"],
  "default": "medium"}`: без поля `quality` используется `medium`, явно можно запросить любой
  уровень из `enum`. Если `quality` в `parameters` нет, канал не принимает явный выбор качества;
- `limits` у чата — `context_tokens`, `max_input_tokens`, `max_output_tokens` одного вызова;
  `capabilities` — что канал умеет, `capabilities.supported_parameters` — какие параметры
  запроса он учитывает;
- `metrics` — измерения успешных запросов канала: задержка p50 и p90 в
  миллисекундах (у чата — до первого содержимого, у медиа — до результата) и скорость
  выдачи токенов после первого токена. `latency_samples` и `latency_window_seconds`
  описывают замеры задержки; `throughput_samples` и `throughput_window_seconds` —
  скорости выдачи. Для задержки используются последние 50 подходящих успехов чата
  или 20 у остальных модальностей за сутки; для скорости выдачи — последние 20 за сутки.
  Без трёх свежих замеров соответствующая оценка берётся за 7 дней. Если и их недостаточно, значение — `null`,
  число замеров и окно — 0. Окна двух метрик могут различаться; прежнее `window_seconds`
  равно большему из используемых окон, а без оценок — 86400. `measured_at` — последний
  успешный замер канала. `samples`, `success_samples` и `success_rate` всегда относятся
  к суткам: число успешных запросов и сбоев исполнения, число успехов и их доля 0…1.
  Доля публикуется от 20 таких запросов; ошибки параметров, отказы по содержимому,
  отмены, ограничения канала и перегрузка в неё не входят. Порядок пресетов учитывает
  также цену, ожидаемое время полного выполнения и устойчивость канала;
- `history` — стабильность за 7 дней: 28 интервалов по 6 часов (`points[]`: начало `at`,
  вызовы, доля успешных — `null` меньше чем при пяти вызовах, медиана задержки и у чата
  скорости) и итог окна (`attempts`, `success_rate`).

Закрытый канал пропадает из списка, его цвет остаётся в истории запросов. Название и цвет
`channel` из ответа для своего интерфейса — `GET /v1/channels`.

## Выбор канала — `routing_options`

Объект в теле запроса (SDK OpenAI — через `extra_body`, multipart транскрибации —
JSON-строкой):

| Поле | Что делает |
|---|---|
| `only` | только эти цвета; пустой массив не разрешает ни одного |
| `ignore` | все, кроме этих |
| `order` | эти первыми, затем остальные разрешённые; цвет вне `only` или из `ignore` — `400` |
| `allow_fallbacks` | `false` — только `order`, а без него — один лучший цвет; по умолчанию `true` |
| `sort` | `price`, `latency` или `throughput` (только чат) вместо порядка пресета |
| `max_price` | пределы ставок: `input`, `output`, `cache_read` — за 1M токенов, `request` — оценка всего запроса |
| `preferred_max_latency_ms` | мягкое предпочтение меньшей задержки |
| `preferred_min_throughput` | мягкое предпочтение скорости выдачи чата, токенов в секунду |
| `sticky` | у чата — предпочитать канал, который уже ответил в этом диалоге; по умолчанию `true` |
| `session_id` | явный идентификатор диалога чата, до 256 байт |

```json tab="Только синий"
{"model": "nano-banana-2", "prompt": "Панда читает книгу", "routing_options": {"only": ["blue"]}}
```

```json tab="Красный, затем оранжевый"
{"model": "nano-banana-2", "prompt": "Панда читает книгу", "routing_options": {"order": ["red", "orange"], "allow_fallbacks": false}}
```

```json tab="Кроме красного"
{"model": "nano-banana-2", "prompt": "Панда читает книгу", "routing_options": {"ignore": ["red"]}}
```

Цвета берите из каналов своей модели. Списки и пределы ставок действуют при любом пресете,
закреплении диалога и повторе. `{}` или `null` — Авто-роутинг на этот вызов, даже при
настройке аккаунта.

## Ошибки выбора

- Неизвестный цвет — `400 invalid_request` с `{"path": "routing_options"}`.
- Строгий выбор (`only`) канала, который не умеет поток, инструменты или нужный предел
  токенов, — `400 capability_mismatch` с полем и подходящими цветами в `allowed`.
- Настройки отсекли все каналы — `400 no_channel_matches` с
  `detail[{"path": "routing_options", "reason": "not_selected" | "above_max_price" | "fallback_disabled"}]`:
  повтор тех же настроек не поможет.
- Поля только для чата (`sort: "throughput"`, `preferred_min_throughput`, `session_id`) в
  запросе к другой модальности — `400`.
- `max_price.request` ограничивает оценку по заданным параметрам и **не гарантирует
  предел итога чата**: число токенов известно только после ответа.

## Превью — `POST /v1/models/{id}/routing/preview`

Бесплатно и без ключа: те же `routing`, `routing_options` и `max_price_multiplier`, что
пойдут в запрос, и `params` с параметрами (у чата — `input_tokens`, `output_tokens`, `n`,
`tools`, `vision`, `structured_output`, `file_input`, `audio_input`, `video_input`,
`stream`; у речи — `speech_characters`, `speech_instructions`, `speech_dialogue`). Флаги —
что будет в запросе: каналы, которые этого не примут, уйдут в `excluded` как `unsupported`.
Ответ (схема `RoutingPreview`):
`channels` — `[{id, estimated_price, rates}]` в порядке попыток, `estimated_price` — цена первого
канала цепочки, `excluded` — остальные цвета с причиной (`not_selected`, `above_max_price`,
`unsupported`, `unavailable`, `fallback_disabled`). Пустой `channels` — подходящих каналов
нет, платный запрос получит `400 no_channel_matches`.

`channels[].rates` — тот же формат, что `rates` каталога каналов.
Для ставки чата используйте `input` и `output`, для суммы сценария — `estimated_price`.

Параметры превью проверяет так же, как запуск, и отказывает тем же конвертом:
`400 capability_mismatch` или `400 invalid_request` с `detail[]` — `path`, `reason`,
`allowed`. Путь параметра из `params` — как в запросе запуска (`aspect_ratio`, не
`params.aspect_ratio`).

```bash
curl https://api.souz.ai/v1/models/nano-banana-2/routing/preview \
  -H "Content-Type: application/json" \
  -d '{"routing_options": {"only": ["blue"]}, "params": {"aspect_ratio": "16:9"}}'
```

> [!NOTE]
> Превью не наследует настройки роутинга аккаунта и диалога — передавайте их явно. Оценка превью —
> не итог запроса.

## Канал для всего аккаунта

`GET` и `PATCH /v1/settings` (ключ управления с ролью разработчика или выше, либо кабинет —
раздел «Роутинг и вебхуки»): поле `routing_options` — карта «модель → настройки», например
`{"nano-banana-2": {"only": ["blue"]}}`. Ключ `*` — общие предпочтения без цветов;
настройка модели заменяет `*` целиком. **PATCH заменяет всю карту**: сначала `GET`, затем
добавьте модель и отправьте карту целиком; `null` очищает её. Неизвестная модель или
чужой цвет — `400` с путём вида `routing_options.nano-banana-2.only[0]`, ничего не
сохраняется.

Запрос без `routing_options` наследует настройку своей модели или `*`; объект в запросе
заменяет настройку целиком. Поля `routing` и `max_price_multiplier` наследуются
независимо.

Изменение 09.10.2026: цвета каналов один раз переназначены — у каждой модели рабочие
каналы идут с красного подряд в порядке пресета `balanced`. Канал остался тем же, сменился
только его цвет. Цвета в сохранённых `routing_options` (аккаунт и запросы) теперь
указывают на другие каналы: сверьте их с `GET /v1/models/{id}/channels`. В истории запросов
остался цвет, под которым запрос выполнялся. Дальше цвета снова не меняются.

## Диалог чата держится канала

Закрепление нужно ради кэша промпта. Диалог с `session_id` закрепляется за каналом,
который ответил, на 10 минут (по аккаунту и модели). Без `session_id` диалог определяется
по началу сообщений и закрепляется, только если ответил первый канал по пресету и у этого
канала есть цена чтения из кэша; ответ запасного канала диалог не переносит. Каждый
успешный ответ того же канала продлевает срок. Явный `order` важнее закрепления,
`sticky: false` его отключает. Сохранение кэша модели не гарантируется.

## Каким каналом выполнен запрос

Поле `channel` — в ответе чата и каждом чанке потока, в задаче, вебхуке и истории; до
выбора — `null`. При ошибке — канал последней попытки; успеха и списания он не означает.

---

Оглавление документации: https://souz.ai/llms.txt. Всё руководство одним файлом: https://souz.ai/llms-full.txt. Справочник методов: https://souz.ai/docs/api-reference.md.
