Skip to content

Формат видео OpenAI

POST /v1/videos и GET /v1/videos/{task_id} — диалект видео OpenAI того же асинхронного API задач, что описан в разделах Создание задачи генерации видео и Получение задачи видео. Тело отправки использует те же поля; разница в ответе: и ответ на отправку, и GET возвращают объект видео OpenAI, а не запись задачи. Этот формат используют модели Sora, его же ожидает видео-клиент OpenAI SDK.

МетодПутьНазначение
POST/v1/videosОтправить задачу генерации
GET/v1/videos/{task_id}Прочитать задачу как объект видео OpenAI
GET/v1/videos/{task_id}/contentСкачать байты готового видео
POST/v1/videos/{video_id}/remixСоздать задачу на основе существующего видео
Terminal window
curl https://api.routeapi.ai/v1/videos \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "A calico cat playing a piano on stage",
"size": "1280x720",
"seconds": "4"
}'

Поля запроса — те же, что в разделе Создание задачи генерации видео: model, prompt, seconds / duration, size, input_reference, images и metadata. input_reference учитывается моделями, поддерживающими референсное изображение. Принимается и multipart/form-data, поэтому файл можно загрузить напрямую:

Terminal window
curl https://api.routeapi.ai/v1/videos \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-F "model=sora-2" \
-F "prompt=A calico cat playing a piano on stage" \
-F "size=1280x720" \
-F "seconds=4" \
-F "input_reference=@cat.jpg"
{
"id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV",
"task_id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1792048458
}

id — это ID задачи RouteAPI. task_id — псевдоним для совместимости, который может исчезнуть в будущих ответах; читайте id. Всегда обращайтесь к задаче по этому id; идентификаторы внутри сохранённой полезной нагрузки вышестоящего сервиса — не то значение, которое нужно для опроса или скачивания.

Ответ на отправку также содержит заголовок X-New-Api-Other-Ratios с применёнными тарифными множителями, например {"seconds":5,"size":1} для запроса Sora.

Получение объекта видео

Section titled “Получение объекта видео”
GET /v1/videos/{task_id}
Terminal window
curl https://api.routeapi.ai/v1/videos/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{
"id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV",
"task_id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV",
"object": "video",
"model": "seedance-2.0",
"status": "completed",
"progress": 100,
"created_at": 1792048458,
"completed_at": 1792048569,
"metadata": { "url": "https://...mp4" }
}
ПолеОписание
idID задачи RouteAPI
objectВсегда "video"
modelМодель, выполнившая задачу
statusqueued, in_progress, completed или failed
progressЦелое число от 0 до 100
created_at / completed_atUnix-секунды. Некоторые адаптеры заполняют completed_at временем последнего обновления строки, поэтому определяйте завершение по status, а не по этому полю
expires_at, size, seconds, remixed_from_video_idПрисутствуют только если поставщик их возвращает
metadata.urlURL видео для поставщиков, сообщающих его через объект видео. Используйте /v1/videos/{task_id}/content, если нужны байты независимо от поставщика
error.code / error.messageЗаполняются при сбое задачи, например expired или cancelled для Seedance

Поля собственной полезной нагрузки вышестоящего сервиса (например, expires_at или size) появляются только если поставщик их возвращает; набор выше — то, что RouteAPI гарантированно отображает. На каналах Gemini и Vertex статус задачи обновляется у поставщика до построения этого объекта.

Задача привязана к пользователю API Key: id, принадлежащий другому аккаунту, сообщается как task_not_exist, как и на эндпоинте записи задачи.

GET /v1/videos/{task_id}/content

Возвращает байты видео, потоково передаваемые через RouteAPI. Ответ содержит Cache-Control: public, max-age=86400 и Content-Type вышестоящего сервиса. Маршрут принимает API Key или сессию консоли и отдаёт только задачи, принадлежащие вызывающей стороне. Коды ошибок и пример curl см. в разделе Скачивание видео.

POST /v1/videos/{video_id}/remix

Создаёт новую задачу из существующего видео. RouteAPI ищет video_id среди ваших задач, определяет по нему модель и закрепляет запрос за каналом, создавшим исходное видео, чтобы результат оставался совместимым.

Terminal window
curl https://api.routeapi.ai/v1/videos/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV/remix \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "The same cat, now wearing a tiny hat" }'

Remix имеет смысл для семейства Sora (sora-2, sora-2-pro): запрос передаётся в собственный remix-эндпоинт вышестоящего сервиса, а prompt обязателен. Для других платформ запрос всё равно принимается, модель и канал определяются по исходной задаче, а задача строится адаптером этой модели — но вышестоящий сервис никогда не получает инструкцию remix, поэтому новая задача является обычной генерацией, а не производной от video_id.

Remix наследует тарифные множители исходной задачи, если адаптер их записал, поэтому новая задача тарифицируется как исходная, а не по значениям по умолчанию.

Модели Sora используют это семейство эндпоинтов напрямую; значимые параметры — size и seconds.

МодельДопустимые размеры
sora-2720x1280, 1280x720
sora-2-pro720x1280, 1280x720, 1792x1024, 1024x1792
  • Неподдерживаемый размер возвращает 400 с кодом invalid_size до какого-либо резервирования.
  • Значения по умолчанию — 720x1280 и 4 секунды.
  • seconds (или duration) проверяется так же, как у любой видеомодели: отрицательные значения и значения больше 3600 отклоняются с 400 invalid_seconds.
  • input_reference передаётся как референсное изображение; работают и JSON, и multipart.
  • Стоимость рассчитывается из seconds и size: вывод 1792x1024 или 1024x1792 стоит с множителем размера (1.666667) поверх посекундной ставки. Применённые множители возвращаются в X-New-Api-Other-Ratios.
  • В этом семействе поддерживается remix.

Доступность и цена зависят от аккаунта — убедитесь, что модель есть в GET /v1/models, и проверьте страницу модели.

После маршрутизации применяется формат ошибки задачи:

СтатусКодЗначение
400invalid_requestОтсутствует или пустой prompt, неверное тело или поле неверного типа
400invalid_secondsduration / seconds отрицательно или больше 3600
400invalid_sizeМодель не принимает такой размер (например, неподдерживаемый размер Sora)
400task_not_existvideo_id в remix неизвестен или принадлежит другому аккаунту
400task_source_unavailableКанал исходной задачи удалён, отключён, или адаптер для него отсутствует
400asset_remix_conflictRemix задачи без материалов попытался сослаться на материал asset://
429—Ёмкость вышестоящего сервиса исчерпана; сообщение заменяется общим уведомлением о повторе
500build_request_failed, do_request_failedЗадачу не удалось преобразовать или соединение с вышестоящим сервисом не удалось
500convert_to_openai_video_failedСохранённые данные задачи не удалось преобразовать в объект видео
501not_implementedGET /v1/videos/{task_id} на платформе, чей адаптер не умеет преобразование в видео OpenAI
любойfail_to_fetch_taskВышестоящий сервис ответил на отправку статусом, отличным от 200; HTTP-статус берётся у него

Запросы, отклонённые до маршрутизации, вместо этого используют стандартное тело {"error": {"message": ..., "type": "error", "code": ...}}.