Справочник API
Все эндпоинты API СОЮЗ на одной странице — аутентификация, модели, чат, картинки, видео, джобы, файлы, вебхуки. Параметры, форматы ответов, коды ошибок.
Базовый URL: https://api.souz.ai/v1
Аутентификация — Bearer-ключ на защищённых /v1/*-эндпоинтах. Исключения: публичные
GET /v1/models и GET /health, а файлы авторизуются подписью в URL:
Authorization: Bearer sk-souz-...
Обычные API-запросы и ответы — JSON (Content-Type: application/json). Исключения: chat stream
идёт как SSE, файловый endpoint отдаёт байты или redirect, неизвестный маршрут/необработанное
исключение сейчас могут быть простым текстом, а direct-host файла — произвольным ответом
хранилища. Обрабатываемые ошибки приходят коротким конвертом либо объектом failed-job.
Подробности: Ошибки.
GET /v1/credits
Остаток кредитов и лимит ключа — для мониторинга («алерт до того, как кончились»).
curl https://api.souz.ai/v1/credits -H "Authorization: Bearer sk-souz-..."
| Поле | Описание |
|---|---|
balance |
Доступно к трате (кредиты) |
reserved |
Удержано выполняющимися джобами |
credit_value_usd |
Курс: 0.01 (1 кредит = 1¢) |
rate_limit.requests_per_minute |
Действующий лимит этого ключа |
GET /v1/models
На внутреннем ProductionGo-профиле endpoint по умолчанию выключен и отвечает 404.
Он включается только после того, как RSA-123 сформирует сертифицированное пересечение
возможностей, а RSA-118 докажет одну ревизию для discovery, admission и worker routing.
curl https://api.souz.ai/v1/models -H "Authorization: Bearer sk-souz-..."
До прохождения gate список сертифицированных моделей передаётся внутреннему продукту вне API.
Код больше не строит контракт из первого provider variant. Формат будущей полной
типизированной витрины (constraints, pricing impact и degradation choices) — RSA-102.
| Поле | Описание |
|---|---|
id |
ID модели (souz/...) — его передаёшь в model |
name |
Человеческое название |
modality |
chat / image / video |
pricing |
Правило цены (см. Кредиты) |
limits |
max_prompt_chars, max_image_mb, image_formats |
POST /v1/chat/completions
Синхронный чат, OpenAI-совместимый (текст, vision, tools, reasoning, стриминг). Полное описание: Чат.
Тело: стандартное OpenAI (model, messages, stream, temperature, max_tokens,
tools, response_format, reasoning_effort, …). Сейчас проверяется только объявленный
Content-Length до 25 МБ; hard limit для chunked/отсутствующего заголовка — RSA-27.
Ответ: стандартный OpenAI chat.completion (или SSE-поток при stream: true). Без
стриминга в usage.cost возвращаются списанные кредиты; в стриме cost добавляется в
usage-чанк, если его прислал апстрим.
Ошибки: short-envelope 400 invalid_request для плохого JSON/обязательных полей и
400 invalid_input|content_blocked при терминальном отказе апстрима; 401,
402 insufficient_credits (только здесь, у чата), 404 model_not_found, 413, 429,
502 model_unavailable (только здесь). Текст message — всегда наш, по коду: ответ апстрима
в него не попадает. Логику строй на code (Принципы).
POST /v1/images/generations
Создать джобу генерации картинки. Полное описание: Картинки.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
model |
string | ✅ | ID модели |
prompt |
string | ✅ | Описание |
aspect_ratio |
string | — | 1:1 2:3 3:2 3:4 4:3 4:5 5:4 9:16 16:9 21:9 2:1 1:2 3:1 1:3 9:21 1:4 4:1 1:8 8:1 auto (по умолчанию 1:1); variant может поддерживать subset |
resolution |
string | — | 1K / 2K / 4K (по умолчанию 1K) |
quality |
string | — | standard / high / ultra; отдельный quality-tier, не alias разрешения |
output_format |
string | — | png / jpeg; jpg нормализуется в jpeg |
size |
string | — | OpenAI-стиль: 1024x1024 / 1792x1024 / 1024x1792 / 2048x2048 |
image / images |
string / string[] | — | Референсы: data URL или https URL; глобально не больше 14 до обхода/хеширования, модель может ограничить сильнее |
callback_url |
string | — | Вебхук этой джобы |
priority |
string | — | cost / speed (по умолчанию cost) — что оптимизировать при выборе порядка маршрутов; на цену не влияет. Вне словаря → invalid_request без джобы. Режима «надёжность» нет: надёжность — свойство всей системы (водопад доводит запрос до результата, пусть и дольше) |
| прочие поля | — | — | Только поля typed frozen-профиля модели, верхним уровнем; неизвестное/невалидное → invalid_request до job |
Неизвестное значение size, сочетание size с aspect_ratio/resolution и универсальный
вложенный params: {...} отклоняются invalid_request до claim/job/reserve.
Заголовки: Idempotency-Key — end-to-end ключ replay для async image/video. Claim берётся
до catalog/callback/reference preflight; mismatch → 409 idempotency_conflict, одинаковый
незавершённый admission → retryable 409 idempotency_in_progress. Старый exact bound v1
replay'ится даже если текущая версия уже отвергает его форму; этот read-only путь не создаёт и
не takeover'ит invalid-now claim. Детали — Джобы.
Ответы: 202 + объект джобы status: "queued" — принята; 200 + объект джобы — идемпотентный
повтор для существующей джобы, которая не failed (в любом статусе, включая queued и
in_progress); 400 + объект джобы failed — отказ сразу (модель отключена, поле не поддержано,
не хватило кредитов) или идемпотентный повтор для упавшей джобы; 400 + короткий конверт
invalid_request — ошибка на границе. Разбор — Ошибки. При callback_url в ответ
добавляется webhook_secret: keyed replay возвращает тот же секрет, unkeyed путь показывает его
один раз. До RSA-109 unkeyed callback прикрепляется
отдельным UPDATE после enqueue и может проиграть редкую гонку с завершением; polling остаётся
источником истины.
POST /v1/videos/generations
Создать джобу генерации видео. Полное описание: Видео.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
model |
string | ✅ | ID модели |
prompt |
string | ✅ | Описание (до 5000 символов) |
aspect_ratio |
string | — | 16:9 9:16 1:1 4:3 3:4 21:9 auto (по умолчанию 16:9); вне списка → 400 invalid_request без джобы. Что умеет конкретная модель — в capabilities.aspect_ratios; каноничное, но неподдержанное моделью значение → 400 с failed-джобой capability_mismatch, price: 0 |
duration |
string|number | — | Целое число секунд строкой или числом ("5"/5); другой JSON-тип или не целое → 400 invalid_request без джобы. Значения проверяются по манифестам модели. Не передан → capabilities.default_duration модели |
image / images |
string / string[] | — | Референсы (data URL или https URL) |
callback_url |
string | — | Вебхук этой джобы |
priority |
string | — | cost / speed (по умолчанию cost) — что оптимизировать при выборе порядка маршрутов; на цену не влияет. Вне словаря → invalid_request без джобы. Режима «надёжность» нет: надёжность — свойство всей системы (водопад доводит запрос до результата, пусть и дольше) |
| прочие поля | — | — | Продвинутые параметры модели: mode, sound, resolution, … |
Ответ: как у картинок (object: "video").
Длительность, по которой считается цена, — та же, с которой запрос уходит к модели: значение вне
capabilities.durationsотвергается до резервирования кредитов —400сfailed-джобой (error.code: capability_mismatch,price: 0); молчаливой подмены на провайдерский дефолт нет. Значение вне общего словаря параметра отклоняется раньше, коротким конвертом400 invalid_request, и джоба вообще не создаётся. Дляaspect_ratioтакая же гарантия сегодня действует только у Seedance 2.0 и Veo 3.1 (Seedance принимает весь свой официальный набор:1:14:33:416:99:1621:9auto); у Kling image-to-video соотношение сторон определяется картинкой-референсом.auto— каноническое имя «пусть решает модель»; провайдерские написания наружу не выходят. На видеоautoработает только у моделей, чейcapabilities.aspect_ratiosего содержит (Seedance 2.0, Veo 3.1) — у остальных это обычное неподдержанное значение.
GET /v1/jobs/{id}
Статус и результат джобы. Полное описание: Джобы.
Объект джобы:
| Поле | Описание |
|---|---|
id |
ID джобы |
object |
image / video / chat |
model |
Модель |
status |
queued → in_progress → completed / failed |
price |
Целые микро-USD (1 кредит = 10 000 µUSD), как все денежные поля API. До terminal state — верхняя оценка (maximum reserve); при completed — итоговое списание: себестоимость выполнившего маршрута × наценка, не выше оценки; при refund — 0 |
created_at |
Unix-время создания |
parameters |
Для новых normalized job: { schema, requested, effective, degradations }; у legacy job отсутствует. Reference source/URL наружу не возвращается |
data |
При completed: [{ "url": "подписанная ссылка" }] |
error |
При failed: { code, message, type }; у capability_mismatch также versioned provider-opaque details |
GET /v1/files/{name}?exp=...&sig=...
Скачать сгенерированный файл. Аутентификация — подпись в URL (ссылку выдаёт джоба), Bearer не нужен. Ссылку можно открывать в браузере.
Ошибки: 403 forbidden — обычно истёкшая подпись ссылки (файл может быть на месте). 410 file_expired — наш структурированный ответ: отдаём через прокси и объекта в хранилище нет. 404 — либо наш not_found в локальной ветке, либо непрозрачный ответ файлового хоста при прямой раздаче. Пока локальный handler сводит к 404 все ошибки чтения, включая права/I/O, поэтому ни один из этих 404 сам по себе не доказывает удаления. 502 storage_unavailable — временная проблема хранилища. Сначала свежая ссылка, потом повтор с паузой, дальше — поддержка; перегенерация оправдана после 410 или отдельно подтверждённого отсутствия (Джобы, RSA-92).
POST /v1/webhooks
Зарегистрировать постоянный вебхук. Тело: { "url": "https://..." }. Ответ 201: { id, object: "webhook", url, secret } — secret показывается один раз. Полное описание: Вебхуки.
GET /v1/webhooks
Список вебхуков: { "object": "list", "data": [{ id, url, enabled, created_at }] }.
DELETE /v1/webhooks/{id}
Отключить вебхук. Ответ: { id, object: "webhook", deleted: true }.
GET /health
Проверка живости API (без аутентификации): { "ok": true }.
Частота запросов
1000 запросов/мин по умолчанию на ключ; сейчас limiter покрывает только POST создания
image/video и chat completions, а не всю защищённую поверхность (RSA-20). Индивидуальный
лимит может отличаться. При превышении — 429 + Retry-After. Подробности: Лимиты.