KovAPIKovAPI
POST https://kovapi.com/v1/videos/generations

Вариант Seedance 2.0 с оплатой за ролик: одна цена за 5, 10 или 15 секунд, 720P, горизонтальный формат 16:9 или вертикальный 9:16, до 9 референсных изображений, звук в каждом ролике. Асинхронные задачи; при ошибке ничего не списывается.

Попробовать в песочнице →

Быстрый старт

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

Шаг 1 · Отправка (сразу возвращает id задачи, HTTP 202)

curl
curl https://kovapi.com/v1/videos/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "seedance-2.0-clip", "prompt": "Маяк на рассвете, волны разбиваются о скалы, камера медленно наезжает", "duration": 10, "resolution": "720P", "size": "16:9"}'

Ответ (HTTP 202)

JSON
{
  "id": "img_5c2e8f1a9b3d7e6f0a4c8b2d",
  "object": "video.generation.job",
  "status": "queued",
  "created": 1791281400,
  "model": "seedance-2.0-clip"
}

Шаг 2 · Опрашивайте каждые 5–10 секунд, пока status не станет succeeded или failed

curl
curl https://kovapi.com/v1/videos/jobs/img_5c2e8f1a9b3d7e6f0a4c8b2d \
  -H "Authorization: Bearer YOUR_API_KEY"

Ответ при успехе

JSON
{
  "id": "img_5c2e8f1a9b3d7e6f0a4c8b2d",
  "object": "video.generation.job",
  "status": "succeeded",
  "created": 1791281400,
  "model": "seedance-2.0-clip",
  "data": [
    {"url": "https://img.kovapi.com/i/8c1f0e5d2b7a49e3a6d0c4f1b9e2a7d5.mp4"}
  ],
  "usage": {"clips": 1, "model": "seedance-2.0-clip"}
}

Шаг 3 · data[0].url — это ролик (MP4). Он хранится 15 дней; чтобы пользоваться им дольше, скачайте его в своё хранилище.

Полный пример (Python: отправить, дождаться, сохранить на диск)

Python
import time
import requests

BASE = "https://kovapi.com/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

# 1. отправка
job = requests.post(f"{BASE}/videos/generations", headers=HEADERS, json={
    "model": "seedance-2.0-clip",
    "prompt": "Маяк на рассвете, волны разбиваются о скалы, камера медленно наезжает",
    "duration": 10,
    "resolution": "720P",
    "size": "16:9",
}).json()
if "error" in job:
    raise SystemExit(job["error"]["message"])

# 2. опрос каждые 10 секунд, не дольше часа
deadline = time.time() + 3600
while job["status"] not in ("succeeded", "failed") and time.time() < deadline:
    time.sleep(10)
    job = requests.get(f"{BASE}/videos/jobs/{job['id']}", headers=HEADERS).json()

# 3. скачивание видео
if job["status"] == "succeeded":
    url = job["data"][0]["url"]
    with open("seedance-2.0-clip.mp4", "wb") as f:
        f.write(requests.get(url).content)
    print("saved", url)
elif job["status"] == "failed":
    print("failed:", job["error"]["code"], job["error"]["message"])
else:
    print("still", job["status"], job["id"])

Пока задача в очереди, опрос также возвращает queue_position (сколько задач впереди вашей) и eta_seconds (ожидаемое время ожидания). Если ваш лимит ожидания истёк, не отправляйте задачу заново: она никуда не делась, продолжайте опрашивать тот же id позже.

Аутентификация

Header
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Чтобы начать, создайте API-ключ в консоли.

Основные характеристики

Длительность5 / 10 / 15 с
Разрешение720P
Пропорции16:9 / 9:16
Референсные изображениядо 9 · используются как референсы (персонажи, сцена, стиль), но не как кадр
Референсные видеоне поддерживается
Референсное аудионе поддерживается
Звуквсегда включён; отключить нельзя (audio: false отклоняется)
Длина промптадо 5 000 байт (UTF-8; около 1 666 иероглифов)
Оплатаза ролик: одна цена при любой длительности

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

JSON-тело запроса POST /v1/videos/generations:

ПараметрТипОбязательныйОписание
modelstringДаID модели: seedance-2.0-clip.
promptstringДаОписание того, что происходит в ролике: картинка, работа камеры и движение. До 5 000 байт (UTF-8; один иероглиф занимает 3 байта, то есть это около 1 666 иероглифов).
durationintegerНетДлительность в секундах: только 5 / 10 / 15; по умолчанию 15. Для вертикального 9:16 — только 15.
resolutionstringНетТолько 720P; можно не передавать.
sizestringНетПропорция: 16:9 / 9:16; по умолчанию 16:9. Можно также передавать как aspect_ratio.
imagesarrayНетРеференсные изображения, не более 9. Они задают персонажей, сцену и стиль и никогда не используются как кадр. В промпте ссылайтесь на них как @Image1, @Image2 в порядке передачи. Одно изображение можно передать в image.
audiobooleanНетКаждый ролик выходит со звуком, отключить его нельзя; false отклоняется (400), поэтому не передавайте этот параметр.
callback_urlstringНетКуда отправить результат, когда задача завершится; подробнее — в разделе о вебхуках ниже.
nintegerНетКаждая задача создаёт один ролик; передавать параметр не нужно. При значении больше 1 всё равно создаётся один ролик, но при отправке резервируется стоимость n роликов, а лишнее возвращается после завершения задачи.

Другие поля (seed, negative_prompt, fps, watermark и т. п.) дальше не передаются и не влияют на цену; результат всегда в MP4 и возвращается в виде url.

Цена

Оплата за ролик: одна цена за ролик независимо от его длительности; зависит она только от разрешения. Сумма резервируется при отправке и полностью возвращается при ошибке. 1 кредит = $0.005.

РазрешениеКредитов за роликUSD за ролик
720P200$1.00

Референсные материалы

  • Референсные изображения (не более 9) задают персонажей, сцену и стиль и никогда не используются как кадр; в промпте ссылайтесь на них как @Image1, @Image2.
  • Эта модель не принимает референсные видео и аудио: если передать их, вернётся ошибка 400.
  • Ролик выдаётся той длительности, которую вы заказали; для вертикального 9:16 — только 15 с.
  • Реальные человеческие лица подходят в качестве референсных изображений, маскирование не требуется. Пожалуйста, убедитесь, что у вас есть право использовать внешность людей, изображённых на фото.
  • Каждое изображение — публичная ссылка на изображение, data: URI или base64, не более 16 MB; несколько изображений передавайте массивом в images. При отправке мы сначала сохраняем изображения у себя, и только потом задача встаёт в очередь; изображение, которое не удаётся прочитать, отклоняется с ошибкой 400, в message указано, какое именно, и ничего не списывается.
  • Референсные материалы мы размещаем у себя и храним 7 дней, готовые ролики — 15 дней.

Референсные изображения для персонажа и сцены

curl
curl https://kovapi.com/v1/videos/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "seedance-2.0-clip", "prompt": "Мальчик из @Image1 сворачивает на улицу из @Image2, оглядывается и улыбается", "images": ["https://example.com/character.png", "https://example.com/street.png"], "duration": 10, "size": "16:9"}'

Изображения нумеруются @Image1, @Image2 в порядке передачи.

Требования к контенту

Каждая задача Seedance проходит проверку контента: промпт, файлы-референсы и готовый ролик — и изображение, и звук. Задача, не прошедшая проверку, завершается с content_policy, деньги не списываются.

Когда идёт проверка

При отправке проверяются промпт и референсы; после генерации ролика ещё раз проверяются изображение и звук. Поэтому отказ может прийти через несколько секунд после отправки или только после окончания рендера (это может занять больше получаса). Задача, завершившаяся со status failed и error.code content_policy, не прошла проверку; с вебхуком придёт событие video.failed.

Без оплаты

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

Звук

Звук (реплики, закадровый текст, пение и эффекты) модель генерирует по промпту, и он проверяется вместе с изображением: реплики, закадровый текст и тексты песен из промпта озвучиваются или поются. Если в ролике не нужны голоса, не пишите в промпте реплики и тексты песен. Эта модель всегда добавляет звук, отключить его нельзя. Если не прошёл звук, error.param равен audio, а в message сказано, был ли это сгенерированный звук или ваше аудио-референс.

Что чаще всего отклоняется

  • Сексуальный контент, обнажённость или сексуальные намёки, в том числе изображения, созданные или смонтированные с помощью ИИ
  • Кровь, жестокость, самоповреждение и насильственные травмы, например огнестрельные ранения и кровотечение
  • Огнестрельное оружие, взрывчатка и наркотики
  • Любой сексуализированный контент с несовершеннолетними; несовершеннолетние рядом с алкоголем, табаком, наркотиками или в опасных ситуациях тоже отклоняются
  • Политики, знаменитости, спортсмены, бизнесмены и другие публичные лица — внешность или голос, включая двойников
  • Персонажи и объекты, защищённые авторским правом, например персонажи Disney или Marvel
  • Контент с ненавистью или дискриминацией, фейковые новости

Длинные сценарии

Одна сцена с нарушением отклоняет весь ролик, и чаще всего это случается в длинных раскадровочных сценариях: перестрелка или крупный план крови в экшен-сцене, несовершеннолетние, которые пьют или курят, — и весь ролик не пройдёт. Перед отправкой прочитайте сценарий целиком и удалите или перепишите такие сцены.

Реальные люди

Чтобы использовать фото реального человека как референс, нужно право на использование его изображения; принимает ли модель такие референсы, указано выше на этой странице.

После отказа

Повторная отправка того же самого снова будет отклонена. Найдите часть, которая скорее всего нарушает правила, перепишите промпт или замените референс и отправьте заново.

Код ошибки: content_policy · status: failed

Статус задачи и поля ответа

GET /v1/videos/jobs/{id} возвращает эти статусы; все поля описаны в разделе Асинхронные задачи. Опрашивайте каждые 5–10 секунд или получайте результат вебхуком (см. ниже). Опрос бесплатный, и прочитать задачу может любой ключ того же аккаунта.

СтатусЧто значит
queuedВ очереди. В ответе есть queue_position (сколько задач впереди) и eta_seconds (ожидаемое время ожидания).
processingГенерируется.
succeededГотово. Результат в data[0].url, детали оплаты в usage.
failedОшибка. Причина в error; зарезервированные кредиты возвращаются полностью.
  • processing может снова смениться на queued: например, при высокой нагрузке, пока готовый ролик скачивается повторно или после перезапуска сервиса. Если задачу не удалось выполнить, шлюз может автоматически запустить рендер заново; сколько бы ни было повторов, задача оплачивается один раз.
  • Один аккаунт выполняет до 50 задач одновременно; остальные ждут в порядке отправки, а задача, не начавшаяся за 15 минут, завершается ошибкой с полным возвратом. Записи о задачах хранятся 3 дня, ссылки на видео — 15 дней.

Сколько ждать

Обычно 5–10 минут.

Медианное время рендера в наших тестах: 5.7 мин.

Ошибки и возвраты

Ошибка при отправке сразу возвращается как HTTP 4xx / 5xx: задача не создаётся, ничего не списывается. О неудаче после того, как задача принята, сообщает эндпоинт задачи, а резерв возвращается полностью. Все коды перечислены в разделе Коды ошибок.

Ошибки при отправке

HTTPcodeПричинаЧто делать
400invalid_requestНедопустимый параметр: длительность, разрешение, пропорция или число референсов выходят за пределы, допустимые для этой модели; промпт слишком длинный; не удаётся прочитать референсное изображение или видео; передан audio: false модели, ролики которой всегда со звуком, и т. п. Что именно не так, указано в message.Исправьте то, что указано в message, и отправьте снова.
400invalid_callback_urlcallback_url — не публичный адрес http(s) или длиннее 2000 символов.Укажите адрес, доступный из интернета.
400model_not_foundID модели написан с ошибкой, model не передан или модель нельзя использовать на этом эндпоинте (например, чат-модель на эндпоинте изображений).Берите ID модели из GET /v1/models или из справочника API.
401invalid_api_keyКлюч не существует, удалён или отключён, либо отключён аккаунт.Проверьте ключ на странице API Keys в консоли.
402insufficient_quotaБаланса не хватает, чтобы зарезервировать стоимость этого запроса. Шлюз сначала резервирует максимально возможную стоимость запроса, поэтому ошибка может возникнуть и при всплеске одновременных вызовов.Если был всплеск запросов, подождите несколько секунд и повторите; в остальных случаях пополните баланс.
429rate_limit_exceededПревышен лимит запросов в минуту, заданный для этого ключа (считается за последние 60 секунд). Заголовка Retry-After нет.Подождите несколько секунд и повторите или увеличьте лимит ключа в консоли.
503model_maintenanceМодель на обслуживании и не принимает запросы; пока идёт обслуживание, другая модель вместо неё не ответит.Повторите, когда обслуживание закончится; ход работ — на странице статуса.
503service_unavailableВременный сбой на нашей стороне, например при сохранении референсного файла. Задача не создана, ничего не списано.Повторите чуть позже.

Неудачные задачи (status — failed)

codeКогда возникаетЧто делать
content_policyВидео: промпт, референс или сгенерированный видеоряд либо звук не прошли проверку контента (если отклонён звук, param равен audio). Wan Standard и Prime: исходные материалы не прошли проверку. error.reason — FaceDetectionSuspect (предположительно лицо реального человека) или DataInspectionFailed (отклонён входной контент). В error.message указаны причина и рекомендуемые изменения. Неудачные задания не оплачиваются.Перепишите промпт или замените референс и только потом отправляйте снова: те же входные данные будут отклонены повторно.
render_failedВидео: на этот раз ролик не получился; обычно это разовый сбой.Повторная отправка того же запроса обычно проходит успешно.
invalid_materialВидео: поставщик обнаружил проблему во входных данных. Это общая ошибка, и часто она разовая.Сначала отправьте задачу ещё раз без изменений; если ошибка повторяется, проверьте референсы и длину промпта.
duration_rejectedВидео: длительность не принята. Чаще всего референсное аудио или видео длиннее допустимого, пусть даже на долю секунды.Обрежьте референсное аудио или видео до допустимой длины и отправьте снова: те же входные данные снова не пройдут.
reference_unreadableВидео: модели не удалось скачать референсное изображение, видео или аудио; чаще всего ссылка ведёт на веб-страницу (YouTube, страница облачного диска).Укажите ссылку, которая ведёт прямо на файл, или загрузите файл в Playground: те же входные данные снова не пройдут.
render_timeoutВидео: очередь или рендер заняли слишком много времени, и поставщик отказался от задачи.Отправьте задачу заново.
wait_timeoutВидео: за 120 минут результата не было, задача завершилась по таймауту, кредиты возвращены полностью; если ролик будет готов позже, он выдаётся бесплатно.Отправьте задачу заново.
upstream_unstableВидео: во время рендера оборвалось соединение.Отправьте задачу заново.
result_fetch_failedВидео создано, но на нашей стороне его так и не удалось скачать или сохранить, несмотря на повторные попытки.Отправьте задачу заново.
upstream_errorЛюбая другая ошибка: автоматические повторы не помогли, задача ждала 15 минут и так и не запустилась, поставщик отказал без объяснения причины и т. п.; что именно произошло, указано в message.Обычно повторная отправка проходит успешно.

Ориентируйтесь на code, а не на текст message. Любой незнакомый code (или его отсутствие) обрабатывайте как upstream_error: повторная отправка обычно проходит успешно. За каждую неудачную задачу деньги возвращаются полностью.

Вебхуки вместо опроса

Добавьте при отправке callback_url — как только задача завершится, успешно или с ошибкой, шлюз отправит на этот URL ровно то же, что возвращает эндпоинт опроса; запрос подписан, а при неудачной доставке повторяется. Общий адрес для всего аккаунта можно также задать в консоли, в разделе «Настройки → Вебхуки». Документация по вебхукам →

curl · callback_url
curl https://kovapi.com/v1/videos/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "seedance-2.0-clip", "prompt": "Маяк на рассвете, волны разбиваются о скалы, камера медленно наезжает", "duration": 10, "resolution": "720P", "size": "16:9", "callback_url": "https://your-domain.com/webhook"}'