API Reference
API REFERENCE

Генерация видео (API)

Асинхронный /v1/videos — создание, опрос статуса, скачивание mp4. Оплата в рублях по факту, хранение результата 72 часа.

/v1/videos — асинхронный API генерации видео. Вы создаёте задачу, опрашиваете её статус и, когда видео готово, скачиваете mp4. Тот же Bearer-ключ sk-gw-..., что и для остального API. Цена — в рублях, списывается по факту.

Идентификатор задачи (id), polling_url и unsigned_urls указывают только на эндпоинты Hubris (https://api.hubris.pw).

Scope ключа

  • POST /v1/videos требует scope videos:write (денежно-мутирующий — создаёт задачу и резервирует средства).
  • GET /v1/videos/{id} и GET /v1/videos/{id}/content требуют videos:read.
  • GET /v1/videos/models требует models:read — тот же scope, что и обычный каталог GET /v1/models, потому что это тоже просто листинг каталога.

Полноправные ключи sk-gw- (без ограничения scope) покрывают все три. У scoped-ключей и OAuth-токенов проверьте, что нужный scope выдан на /keys.

Жизненный цикл

POST /v1/videos  →  202 { id, status: "pending", polling_url }

        ▼  (опрос раз в несколько секунд)
GET /v1/videos/{id}  →  200 { status: "pending" | "in_progress" | "completed" | "failed" }

        ▼  (когда status = "completed")
GET /v1/videos/{id}/content?index=0  →  video/mp4 (сырые байты)

Статусы наружу: pending, in_progress, completed, failed. Промежуточные внутренние состояния схлопываются в in_progress.

Создание — POST /v1/videos

POSThttps://api.hubris.pw/v1/videos

Обязательны model (из каталога видео-моделей, см. GET /v1/videos/models) и prompt. Ответ — HTTP 202.

curl -s https://api.hubris.pw/v1/videos \-H "Authorization: Bearer $HUBRIS_API_KEY" \-H "Content-Type: application/json" \-d '{  "model": "kwaivgi/kling-v3.0-pro",  "prompt": "Кот в скафандре катается на скейтборде по Луне",  "duration": 8,  "resolution": "720p",  "aspect_ratio": "16:9",  "generate_audio": true}'
import os, requestsr = requests.post(  "https://api.hubris.pw/v1/videos",  headers={"Authorization": f"Bearer {os.environ['HUBRIS_API_KEY']}"},  json={      "model": "kwaivgi/kling-v3.0-pro",      "prompt": "Кот в скафандре катается на скейтборде по Луне",      "duration": 8,      "resolution": "720p",      "aspect_ratio": "16:9",      "generate_audio": True,  },)job = r.json()print(job["id"], job["status"])
const r = await fetch("https://api.hubris.pw/v1/videos", {method: "POST",headers: {  Authorization: `Bearer ${process.env.HUBRIS_API_KEY}`,  "Content-Type": "application/json",},body: JSON.stringify({  model: "kwaivgi/kling-v3.0-pro",  prompt: "Кот в скафандре катается на скейтборде по Луне",  duration: 8,  resolution: "720p",  aspect_ratio: "16:9",  generate_audio: true,}),});const job = await r.json();console.log(job.id, job.status);
{
  "id": "b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a",
  "status": "pending",
  "polling_url": "https://api.hubris.pw/v1/videos/b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a",
  "created": 1752192000
}

Опциональные поля: size ("1280x720", шорткат к resolution+aspect_ratio; при явном resolution и/или aspect_ratio они перекрывают size), seed (int, только если модель поддерживает детерминизм), frame_images[] — до двух опорных кадров, чтобы оживить картинку первым и/или последним кадром:

{
  "frame_images": [
    {
      "type": "image_url",
      "image_url": { "url": "https://example.com/frame.png" },
      "frame_type": "first_frame"
    }
  ]
}

image_url.url принимает https://-ссылку (без логина/пароля в URL) или data:image/png;base64,... / data:image/jpeg;base64,... (до 10 МБ в base64). Поля callback_url и input_references в v1 не поддерживаются — запрос с ними вернёт 400 invalid_request (не молчаливый дроп).

Идемпотентность

Передайте заголовок Idempotency-Key: <ваш-ключ> — повторный POST с тем же ключом от того же аккаунта вернёт уже созданную задачу, не создавая вторую и не резервируя средства повторно. Используйте при сетевых ретраях создания.

Опрос статуса — GET /v1/videos/{id}

GEThttps://api.hubris.pw/v1/videos/{id}
curl -s https://api.hubris.pw/v1/videos/b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a \
  -H "Authorization: Bearer $HUBRIS_API_KEY"
{
  "id": "b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a",
  "status": "completed",
  "created": 1752192000,
  "unsigned_urls": [
    "https://api.hubris.pw/v1/videos/b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a/content?index=0"
  ],
  "usage": { "cost": 4200 }
}
  • usage.cost — стоимость в копейках (integer), появляется только при status: "completed". 4200 = 42,00 ₽. Это итоговая сумма, списанная с баланса — не оценка.
  • unsigned_urls появляются только при status: "completed" и, несмотря на имя (унаследовано от формата апстрима), требуют тот же Bearer-ключ — это эндпоинты Hubris, не публичные подписанные ссылки.
  • При status: "failed" приходит поле error с нейтральным текстом.

Пример полного цикла (bash)

ID=$(curl -s https://api.hubris.pw/v1/videos \
  -H "Authorization: Bearer $HUBRIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kwaivgi/kling-v3.0-pro","prompt":"Закат над океаном, дрон"}' \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')

while true; do
  STATUS=$(curl -s "https://api.hubris.pw/v1/videos/$ID" \
    -H "Authorization: Bearer $HUBRIS_API_KEY" \
    | python3 -c 'import sys,json;print(json.load(sys.stdin)["status"])')
  echo "status=$STATUS"
  [ "$STATUS" = "completed" ] && break
  [ "$STATUS" = "failed" ] && { echo "generation failed"; exit 1; }
  sleep 5
done

curl -s "https://api.hubris.pw/v1/videos/$ID/content?index=0" \
  -H "Authorization: Bearer $HUBRIS_API_KEY" -o result.mp4

Опрашивайте не чаще раза в несколько секунд — частые повторы одного и того же GET не ускорят генерацию.

Скачивание — GET /v1/videos/{id}/content

GEThttps://api.hubris.pw/v1/videos/{id}/content?index=0

Отдаёт сырые байты video/mp4. Требует Bearer-ключ и доступен только владельцу задачи. В v1 доступен единственный клип — index=0 (параметр можно не передавать, по умолчанию тот же); index больше нуля вернёт 400 index_out_of_range. Запрос до готовности видео или после истечения хранения — 404 video_not_ready.

Хранение результата — 72 часа

Готовый ролик хранится у Hubris 72 часа с момента создания задачи, затем удаляется без возможности восстановления. Скачайте и сохраните файл у себя в течение этого окна. Запрос /content после удаления вернёт 404 video_not_ready — так же, как если бы видео ещё не было готово (Hubris не палит разницу между «протухло» и «не готово»).

Каталог видео-моделей — GET /v1/videos/models

GEThttps://api.hubris.pw/v1/videos/models
curl -s https://api.hubris.pw/v1/videos/models \
  -H "Authorization: Bearer $HUBRIS_API_KEY"

Возвращает { "object": "list", "data": [...] } — активные видео-модели с поддерживаемыми разрешениями, соотношениями сторон, длительностями, доступностью звука/seed/опорных кадров и ценами в рублях за единицу (секунда или видео). Видео-модели скрыты из обычного GET /v1/models — получить их там тоже можно, но отдельным запросом: GET /v1/models?output_modalities=video.

Коды ошибок

HTTPcodetypeКогда
400invalid_requestinvalid_request_errorКривой запрос, неподдерживаемая ось (длительность/разрешение/пропорции не из каталога модели), callback_url/input_references
400index_out_of_rangeinvalid_request_errorindex в /content вне диапазона (v1 — только index=0)
402insufficient_balanceinvalid_request_errorНедостаточно средств для резерва под задачу
404model_not_foundinvalid_request_errorМодель с таким id не видео-модель или неактивна
404not_foundinvalid_request_errorЗадачи с таким id не существует или она принадлежит другому аккаунту
404video_not_readyinvalid_request_error/content до completed или после 72-часового TTL
413request_too_largeinvalid_request_errorТело запроса (обычно — frame_images в base64) превышает лимит
429too_many_active_jobsrate_limit_errorДостигнут лимит одновременных видео-задач аккаунта
502 / 504upstream_errorapi_errorПровайдер модели не принял задачу (502) или не ответил вовремя (504)
503exchange_rate_unavailableapi_errorКурс ЦБ РФ временно недоступен — нельзя посчитать резерв под задачу

Полный формат ошибок и стратегия retry — на странице Ошибки.

Приватность и хранение данных

Видео-генерация выполняется на инфраструктуре внешних провайдеров моделей и не покрывается режимом Zero Data Retention: провайдеры временно хранят входные данные (промпт, кадры frame_images) и результат на своей стороне на время генерации. У Hubris готовый ролик хранится 72 часа, затем удаляется.

Privacy Mode на видео не распространяется. Автоматическое маскирование персональных данных (Privacy Mode) работает только для текстовых запросов Chat Completions; промпты и кадры видео уходят провайдеру как есть — не передавайте туда персональные данные третьих лиц.

Трансграничная передача (152-ФЗ). Если вы вызываете /v1/videos от имени своих пользователей, вы отвечаете за наличие их согласия на обработку и трансграничную передачу входов и выходов (промпты, кадры, результат) за пределы РФ, а также на 72-часовое хранение результата у Hubris. Условия использования API фиксируют это в оферте.

Hubris не логирует содержимое ваших запросов: prompt, байты видео и frame_images не попадают в логи — только метаданные (модель, стоимость, статус, латентность).

Что дальше

  • Ошибки — таблица всех кодов и retry-стратегий.
  • Биллинг — как считается usage.cost.
  • Privacy Mode — что покрывает маскирование, а что нет.
  • Студия видео в личном кабинете — тот же API под UI, без curl.

Обновлено:

Генерация видео (API) · Hubris