Генерация видео через API

Один POST-запрос тем же ключом, что и чат: описание сцены на вход, ссылка на mp4 на выход. Здесь собраны параметры, примеры на трёх языках и правила списания.

Эндпоинты и авторизация

Видео живёт на OpenAI-совместимом входе и работает тем же ключом, что и текстовые модели: меняется только путь. Anthropic-вход видео не генерирует.

МетодПутьНазначение
POSThttps://api.tokenator.top/v1/videos/generationsГенерация клипа по текстовому описанию. Тот же обработчик отвечает на /v1/videos.
GET/v1/videos/{id}?model=…Статус асинхронной задачи апстрима, если вы получили её идентификатор.
GET/v1/videos/modelsКаталог видеомоделей, доступных этому ключу, вместе с их параметрами.

Ключ передаётся заголовком Authorization: Bearer sk-your-tokenator-key. Отдельного ключа для видео нет — генерации списываются с того же ключа, что и токены.

Первый запрос

Генерация клипа
curl https://api.tokenator.top/v1/videos/generations \
  -H "Authorization: Bearer sk-your-tokenator-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "video-model-id",
    "prompt": "неоновый город под дождём, медленный пролёт камеры",
    "duration": 6,
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'

Ответ приходит, когда клип готов, и выглядит как обычный ответ генерации: массив data со ссылками.

Ответ
{
  "created": 1755600000,
  "data": [
    { "url": "https://api.tokenator.top/static/v/6f2c1a9b.mp4" }
  ]
}

Ссылка ведёт на файл, перевыложенный на стороне сервиса, — временные адреса провайдера наружу не попадают. Если модель отдаёт видео инлайном, вместо url в элементе будет b64_json с самим файлом.

Какие модели умеют видео

Прямо сейчас в каталоге нет включённых видеомоделей. Актуальный список всегда возвращает /v1/videos/models, а на витрине он лежит в каталоге.

Тот же список отдаёт API — вместе с длительностями, разрешениями, соотношениями сторон и значениями по умолчанию. Это надёжнее, чем зашивать параметры в код: список меняется вместе с каталогом.

Каталог видеомоделей
curl https://api.tokenator.top/v1/videos/models \
  -H "Authorization: Bearer sk-your-tokenator-key"
Ответ
{
  "object": "list",
  "data": [
    {
      "id": "video-model-id",
      "object": "video_model",
      "durations": [4, 6, 8],
      "resolutions": ["480p", "720p", "1080p"],
      "aspect_ratios": ["16:9", "9:16", "1:1"],
      "audio": true,
      "image_input": true,
      "default_duration": 4,
      "default_resolution": "720p",
      "default_aspect_ratio": "16:9"
    }
  ]
}

Параметры запроса

ПолеТипЧто делает
modelstringAPI ID видеомодели из каталога. Если поле не задано, берётся первая включённая видеомодель — лучше указывать явно.
promptstring, обязательноеОписание сцены. Пустая строка отклоняется с кодом 400.
nintegerСколько клипов сгенерировать за запрос: от 1 до 4. Значения больше 4 обрезаются до 4.
durationinteger, секундыДлительность клипа. Принимаются также seconds и duration_seconds. Максимум — 60 секунд, а конкретный список значений задаёт модель.
resolutionstringНапример 720p. Синонимы приводятся к каноническому виду: sd480p, hd720p, 1k и fhd1080p.
aspect_ratiostringСоотношение сторон, например 16:9. Запись через x (16x9) тоже понимается.
sizestringРазмер кадра вида 1280x720. Если aspect_ratio не задан, соотношение сторон выводится из него.
generate_audiobooleanПросить модель нарисовать звук. Работает только у моделей, которые заявили звук.
seedintegerЗерно генерации — с одним и тем же значением результат воспроизводим настолько, насколько это позволяет модель.
frame_imagesмассивСтартовые кадры для оживления готового изображения.
input_referencesмассивРеференсы стиля или персонажа. Вместе с frame_images — не больше четырёх изображений на запрос.

Незаполненные поля подставляются из значений модели по умолчанию, а значения вне заявленного списка отклоняются до обращения к провайдеру — неудачная попытка не тратит генерации. Поля callback_url, webhook_url и provider вырезаются из запроса и апстриму не уходят: обратные вызовы шли бы мимо вашего ключа.

Сколько ждать и что происходит внутри

Рендер видео занимает от десятков секунд до нескольких минут. Запрос синхронный: соединение держится, пока клип не готов, а чтобы промежуточные прокси не закрыли его по тишине, сервис досылает keep-alive прямо в тело ответа. Итоговый JSON приходит последним куском — обычный парсер прочитает его как есть.

Если провайдер отвечает асинхронной задачей, прокси сам опрашивает её статус и отдаёт готовый клип — писать свой цикл опроса не нужно. Общее ожидание ограничено 15 мин; по истечении приходит 504, а списанные генерации возвращаются на ключ.

Практический вывод: поднимите таймаут HTTP-клиента до 15 мин и не ставьте ретрай по таймауту — повторный запрос запустит второй рендер.

Статус задачи, если идентификатор уже есть
curl "https://api.tokenator.top/v1/videos/vid_123?model=video-model-id" \
  -H "Authorization: Bearer sk-your-tokenator-key"

Параметр model здесь обязателен по смыслу: по нему выбирается провайдер, у которого нужно спрашивать статус. Без него запрос уйдёт к первой включённой видеомодели.

Стартовый кадр и референсы

Модели, которые заявили вход изображением, умеют оживлять готовый кадр. Картинки передаются в frame_images, а референсы стиля или персонажа — в input_references; суммарно не больше четырёх на запрос. Если модель вход изображением не заявляла, запрос отклоняется с 400 — до списания генераций.

Оживление кадра
{
  "model": "video-model-id",
  "prompt": "камера медленно наезжает, ветер шевелит листву",
  "duration": 4,
  "frame_images": ["https://example.com/frame.jpg"]
}

SDK и готовые примеры

Видео-эндпоинт не входит в типизированную часть OpenAI SDK, поэтому вызывать его удобнее «сырым» запросом. Ключ и базовый адрес при этом остаются теми же, что и для чата — отдельный клиент заводить не нужно.

Python — openai
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-tokenator-key",
    base_url="https://api.tokenator.top/v1",
    timeout=900,
)

result = client.post(
    "/videos/generations",
    body={
        "model": "video-model-id",
        "prompt": "неоновый город под дождём",
        "duration": 6,
        "resolution": "720p",
    },
    cast_to=dict,
)

print(result["data"][0]["url"])
Python — requests
import requests

response = requests.post(
    "https://api.tokenator.top/v1/videos/generations",
    headers={"Authorization": "Bearer sk-your-tokenator-key"},
    json={
        "model": "video-model-id",
        "prompt": "неоновый город под дождём",
        "duration": 6,
        "resolution": "720p",
    },
    timeout=900,
)
response.raise_for_status()
print(response.json()["data"][0]["url"])
Node.js — fetch
const response = await fetch("https://api.tokenator.top/v1/videos/generations", {
  method: "POST",
  headers: {
    Authorization: "Bearer sk-your-tokenator-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "video-model-id",
    prompt: "неоновый город под дождём",
    duration: 6,
    resolution: "720p",
  }),
  signal: AbortSignal.timeout(900_000),
})

const result = await response.json()
console.log(result.data[0].url)

Готовые фрагменты под ваш ключ и адрес есть в дашборде ключа — там же, где сниппеты для чата.

Как списывается видео

Видео не тратит токены. У ключа есть отдельный счётчик генераций видео, и одна генерация — это один клип базового разрешения и базовой длительности. Более тяжёлые параметры стоят кратно дороже: множитель по разрешению задаёт оператор (например 480p — 1×, 720p — 2×, 1080p — 4×), а длительность масштабируется относительно базовой. Итоговое списание — число клипов × множитель модели × множитель разрешения × множитель длительности, округлённое вверх.

Генерации резервируются до обращения к провайдеру и возвращаются, если клип не приехал: неудачный рендер ничего не стоит. Пакеты видео продаются отдельно от токенов; ключ с token_limit: -1 — это ключ только под генерацию, текстовые модели ему недоступны.

Остаток генераций
curl https://api.tokenator.top/v1/tokens \
  -H "Authorization: Bearer sk-your-tokenator-key"
Ответ
{
  "name": "my-key",
  "limit": 1000000,
  "used": 240000,
  "remaining": 760000,
  "image_limit": 0,
  "image_used": 0,
  "image_remaining": 0,
  "video_limit": 20,
  "video_used": 3,
  "video_remaining": 17
}

Ограничения

  • До 4 клипов за один запрос (n); больше — обрезается до 4.
  • Длительность клипа — не больше 60 секунд, и не больше того, что заявила модель.
  • Не больше четырёх входных изображений на запрос (frame_images и input_references вместе).
  • Одновременных генераций на ключ: 1. Пятый запрос не встаёт в очередь, а сразу получает 429 с полем busy_for_seconds.
  • Общее ожидание одного запроса ограничено 15 мин.

Ошибки

СимптомПричинаЧто сделать
400 prompt requiredВ теле нет описания сцены или тело вообще не JSON.Проверьте Content-Type: application/json и непустой prompt.
400 о длительности, разрешении или соотношении сторонЗначение не входит в список, который заявила модель.Сообщение об ошибке перечисляет допустимые значения; их же возвращает /v1/videos/models.
400 does not generate videoУказана обычная текстовая или картиночная модель.Возьмите ID видеомодели из каталога.
429 с полем video_gen_limitГенерации видео на ключе закончились.Пополните видео-пакет в личном кабинете; остаток виден в /v1/tokens.
429 с полем video_concurrent_limitНа ключе уже идёт генерация: параллельные рендеры ограничены.Поле busy_for_seconds показывает, сколько идёт текущая генерация. Ставьте запросы в очередь, а не в параллель.
504Модель не закончила рендер за отведённое время.Попробуйте более короткий клип или меньшее разрешение. Списанные генерации возвращаются.
502 Request errorОшибка на стороне провайдера. Её текст клиенту не пересылается.Повторите запрос — Tokenator сам переключается на следующего провайдера модели. Если ошибка стабильна, напишите в поддержку.

Попробовать без кода

В дашборде ключа есть «Студия» с переключателем «Картинки / Видео»: длительность, разрешение и соотношение сторон выбираются кнопками, готовые клипы складываются в галерею. Это тот же эндпоинт и тот же счётчик генераций — удобно, чтобы проверить модель до того, как писать интеграцию.

Частые вопросы

Нужен ли отдельный ключ для генерации видео?

Нет. Работает тот же ключ, что и для чата: меняется только путь запроса. Отдельно покупается лишь пакет генераций.

Можно ли сгенерировать видео через Anthropic-формат?

Нет. Видео есть только на OpenAI-совместимом входе — /v1/videos/generations. Для чата оба формата по-прежнему взаимозаменяемы.

Как узнать, какие длительности и разрешения поддерживает модель?

Запросом /v1/videos/models: он возвращает списки durations, resolutions, aspect_ratios и значения по умолчанию. То же самое написано на странице модели в каталоге.

Списываются ли генерации, если рендер не удался?

Нет. Генерации резервируются до запроса и возвращаются на ключ, если клип не приехал — ошибка провайдера или таймаут ничего не стоят.

Сколько живёт ссылка на готовое видео?

Файл перевыкладывается на стороне сервиса и отдаётся с нашего адреса, а не по временной ссылке провайдера. Скачайте его сразу, если клип нужен надолго.

Можно ли запускать несколько генераций параллельно?

На один ключ — 1 одновременно; остальные запросы получают 429. Несколько клипов за один запрос заказываются полем n (до четырёх).