Каналы

Канал модели обозначен цветом: 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 — данных нет, а не нулевая цена. У канала с динамической ценой (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_fallbacksfalse — только order, а без него — один лучший цвет; по умолчанию true
sortprice, latency или throughput (только чат) вместо порядка пресета
max_priceпределы ставок: input, output, cache_read — за 1M токенов, request — оценка всего запроса
preferred_max_latency_msмягкое предпочтение меньшей задержки
preferred_min_throughputмягкое предпочтение скорости выдачи чата, токенов в секунду
stickyу чата — предпочитать канал, который уже ответил в этом диалоге; по умолчанию true
session_idявный идентификатор диалога чата, до 256 байт
{"model": "nano-banana-2", "prompt": "Панда читает книгу", "routing_options": {"only": ["blue"]}}

Цвета берите из каналов своей модели. Списки и пределы ставок действуют при любом пресете, закреплении диалога и повторе. {} или 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).

Терминал
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"}}'

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

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. При ошибке — канал последней попытки; успеха и списания он не означает.