← Окно

API Окна: говорящий аватар по фото и звуку

Тот же функционал, что в интерфейсе: загрузить портрет и звук, собрать заказ, следить за очередью, забрать видео. Оплата — с баланса аккаунта в кредитах.

Base URLhttps://api.okno.tools/v1АвторизацияAuthorization: Bearer okn_live_… · Ключ создаётся в кабинете.ФорматJSON (UTF-8) · файлы — multipart/form-data · время — RFC 3339, UTCЛимиты60 запросов в минуту на ключ · 120 загрузок в час · до 3 незавершённых заказов · до 20 роликов в заказеOpenAPIopenapi.yaml
POST/uploads

Загрузка файлов

Сначала загрузите портрет и звук — получите id загрузок. Картинка до 10 МБ (JPG, PNG, WebP; от 128 до 8192 пикселей по стороне, пропорции от 1:4 до 4:1), звук до 25 МБ и до 60 сек (WAV, MP3, M4A). Загрузка без заказа хранится 24 часа; один id можно указать в нескольких роликах.

kindобязательноimage или audio
fileобязательноФайл
curl https://api.okno.tools/v1/uploads \
  -H "Authorization: Bearer $OKNO_KEY" \
  -F kind=audio -F file=@news_1002.mp3

→ 200
{ "id": "up_8Jq2…", "kind": "audio", "name": "news_1002.mp3", "size": 227244, "duration_seconds": 14.2 }
POST/avatars/quote

Расчёт стоимости

То же тело, что у создания заказа, но ничего не списывает: сколько секунд и кредитов уйдёт и хватает ли баланса.

→ 200
{ "total_seconds": 15, "billed_seconds": 20, "cost_credits": 800,
  "balance_credits": 1240, "enough": true, "min_order_seconds": 20,
  "clips": [ { "duration_seconds": 15, "cost_credits": 800 } ] }
POST/avatars/orders

Создать заказ

Передайте один или несколько роликов — все ролики заказа обрабатываются одним пакетом. 720p — 40 кредитов за секунду звука, 480p — 28. Сумма длительностей меньше 20 сек списывается как 20 сек. Кредиты резервируются сразу; за ролик, который не сгенерировался, возвращаются.

clips[].imageобязательноid загрузки изображения
clips[].audioобязательноid загрузки звука, до 60 сек
clips[].resolutionнеобязательно720p или 480p, по умолчанию 720p
clips[].promptнеобязательноОписание поведения, до 500 символов
clips[].negative_promptнеобязательноЧего избегать, до 500 символов
clips[].seedнеобязательноЦелое число 0…2147483647; без него — случайный
webhook_urlнеобязательноПубличный http(s)-адрес; переопределяет вебхук аккаунта
speedнеобязательноПриоритет: 1 (по умолчанию), 1.5 или 2 — во столько раз дороже, заказ обрабатывается раньше заказов с меньшим приоритетом. Точный срок не гарантируем
Idempotency-KeyнеобязательноЗаголовок: повтор запроса с тем же ключом в течение суток вернёт тот же ответ и не создаст второй заказ

Для одного ролика можно не загружать файлы заранее: multipart/form-data с файлами image и audio и полями resolution, prompt, negative_prompt, seed, webhook_url, speed.

curl https://api.okno.tools/v1/avatars/orders \
  -H "Authorization: Bearer $OKNO_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c…" \
  -d '{
    "clips": [
      { "image": "up_Hx41…", "audio": "up_8Jq2…", "resolution": "720p", "seed": 829104 }
    ]
  }'

→ 202
{ "order": { "id": 1042, "status": "active", "stage": "queued", "queue_position": 1,
  "total_seconds": 15, "billed_seconds": 20, "cost_credits": 800, "cancellable": true,
  "clips": [ { "id": 5121, "status": "queued", "progress": 0, … } ] } }
GET/avatars/orders/{id}

Статус заказа

stage: queued → generating → done. status заказа: active, затем done, partial (часть роликов не удалась) или failed. У ролика status: queued, processing, done или failed; progress 0–100, eta_seconds — оценка до готовности. Когда ролик готов — video_url и expires_at: видео хранится 7 дней. Опрашивать раз в 10–30 секунд или ждать вебхук.

→ 200
{ "order": { "id": 1042, "status": "active", "stage": "generating",
  "clips": [
    { "id": 5121, "status": "processing", "progress": 64, "eta_seconds": 180, … },
    { "id": 5122, "status": "queued", "progress": 0, … }
  ] } }
GET/avatars/orders

Список заказов

Заказы аккаунта, новые сверху. Если есть ещё, в ответе next — передайте его в before для следующей страницы.

limitнеобязательно1–100, по умолчанию 20
beforeнеобязательноВернуть заказы с id меньше этого
curl "https://api.okno.tools/v1/avatars/orders?limit=20" \
  -H "Authorization: Bearer $OKNO_KEY"

→ 200
{ "orders": [ { "id": 1042, "status": "done", … } ], "next": 1023 }
POST/avatars/orders/{id}/cancel

Отмена заказа

Пока заказ ждёт в очереди (cancellable: true), его можно отменить — резерв вернётся на баланс. Когда генерация началась — 409 not_cancellable.

→ 200
{ "order": { "id": 1042, "status": "failed", "refunded_credits": 800,
  "clips": [ { "id": 5121, "status": "failed", "cancelled": true, … } ] } }
POST/avatars/orders/{id}/speed

Смена приоритета заказа

Пока генерация заказа не началась (speed_changeable: true), приоритет можно сменить. При повышении доплата резервируется на балансе (не хватает — 402 insufficient_balance), при понижении разница возвращается. Когда генерация началась — 409 speed_not_changeable.

speedобязательно1, 1.5 или 2
curl https://api.okno.tools/v1/avatars/orders/1042/speed \
  -H "Authorization: Bearer $OKNO_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "speed": 2 }'

→ 200
{ "order": { "id": 1042, "speed": 2, "speed_changeable": true, "queue_position": 1, … } }
GET/avatars/clips/{id}

Ролик и скачивание

Статус одного ролика. Само видео — GET /avatars/clips/{id}/download с тем же ключом: MP4, поддерживается Range. До готовности — 409 not_ready, после срока хранения — 410 expired.

→ 200
{ "clip": { "id": 5121, "order_id": 1042, "status": "done", "progress": 100,
  "image": "up_Hx41…", "audio": "up_8Jq2…", "resolution": "720p", "seed": 829104,
  "duration_seconds": 15, "cost_credits": 800,
  "video_url": "https://api.okno.tools/v1/avatars/clips/5121/download", "expires_at": "2026-10-18T12:04:31Z" } }

curl -L -o 5121.mp4 https://api.okno.tools/v1/avatars/clips/5121/download \
  -H "Authorization: Bearer $OKNO_KEY"
POSTwebhook_url

Вебхуки

Если указан webhook_url (в запросе или в кабинете), по завершении заказа мы отправим POST с заказом в том же виде, что GET /avatars/orders/{id}. Подпись — в заголовке X-Okno-Signature: sha256= и HMAC-SHA256 тела секретом из кабинета; сравнивайте с подписью сырого тела. Ответьте 2xx; иначе повторим через 30 сек и через 2 мин. Запросы приходят с IP 82.202.173.145 — его можно внести в список разрешённых.

X-Okno-Signature: sha256=5d41402abc4b2a76b9719d911017c592…

{ "event": "order.finished",
  "order": { "id": 1042, "status": "done",
    "clips": [ { "id": 5121, "status": "done", "video_url": "https://api.okno.tools/v1/avatars/clips/5121/download", … } ] } }
GET/balance

Баланс

Свободные кредиты, зарезервированные под незавершённые заказы, и действующие тарифы за секунду звука.

→ 200
{ "balance_credits": 1240, "held_credits": 0,
  "rates": { "avatars": { "720p": 40, "480p": 28 } },
  "min_order_seconds": 20, "max_clip_seconds": 60, "results_ttl_days": 7,
  "speeds": [1, 1.5, 2] }

Ошибки

Ответ с ошибкой: {"error": {"code", "message", "details"}}. message — по Accept-Language (ru или en), details.clip — номер ролика в clips[] с ошибкой. Ориентируйтесь на code.

400invalid_*, no_jobs, too_many_jobsНеверные параметры: invalid_resolution, invalid_seed, invalid_speed, invalid_webhook_url, prompt_too_long, neg_prompt_too_long…
400audio_too_long, image_bad_size, image_bad_ratioФайл не подходит по длине или размеру
401unauthorizedНет ключа или ключ неверный
402insufficient_balanceНедостаточно кредитов
403account_bannedАккаунт заблокирован
404not_found, upload_not_foundЗаказ, ролик или загрузка не найдены (или загрузка устарела)
409not_ready, not_cancellableВидео ещё не готово; отменять уже поздно
409idempotency_in_progressЗапрос с этим Idempotency-Key ещё выполняется
410expiredСрок хранения видео истёк
413file_too_largeФайл больше лимита
415unsupported_fileФормат файла не поддерживается
422idempotency_mismatchIdempotency-Key уже использован с другим телом
429rate_limited, too_many_activeСлишком много запросов или незавершённых заказов; см. Retry-After

ПопробоватьСоветы по портрету и звуку