Вариант Seedance 2.0 с оплатой за ролик: одна цена за 5, 10 или 15 секунд, 720P, горизонтальный формат 16:9 или вертикальный 9:16, до 9 референсных изображений, звук в каждом ролике. Асинхронные задачи; при ошибке ничего не списывается.
Попробовать в песочнице →Быстрый старт
Три шага: отправить задачу, опросить её и забрать ссылку на видео. Замените YOUR_API_KEY своим ключом, и команды ниже заработают как есть.
Шаг 1 · Отправка (сразу возвращает id задачи, HTTP 202)
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)
{
"id": "img_5c2e8f1a9b3d7e6f0a4c8b2d",
"object": "video.generation.job",
"status": "queued",
"created": 1791281400,
"model": "seedance-2.0-clip"
}Шаг 2 · Опрашивайте каждые 5–10 секунд, пока status не станет succeeded или failed
curl https://kovapi.com/v1/videos/jobs/img_5c2e8f1a9b3d7e6f0a4c8b2d \ -H "Authorization: Bearer YOUR_API_KEY"
Ответ при успехе
{
"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: отправить, дождаться, сохранить на диск)
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 позже.
Аутентификация
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:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| model | string | Да | ID модели: seedance-2.0-clip. |
| prompt | string | Да | Описание того, что происходит в ролике: картинка, работа камеры и движение. До 5 000 байт (UTF-8; один иероглиф занимает 3 байта, то есть это около 1 666 иероглифов). |
| duration | integer | Нет | Длительность в секундах: только 5 / 10 / 15; по умолчанию 15. Для вертикального 9:16 — только 15. |
| resolution | string | Нет | Только 720P; можно не передавать. |
| size | string | Нет | Пропорция: 16:9 / 9:16; по умолчанию 16:9. Можно также передавать как aspect_ratio. |
| images | array | Нет | Референсные изображения, не более 9. Они задают персонажей, сцену и стиль и никогда не используются как кадр. В промпте ссылайтесь на них как @Image1, @Image2 в порядке передачи. Одно изображение можно передать в image. |
| audio | boolean | Нет | Каждый ролик выходит со звуком, отключить его нельзя; false отклоняется (400), поэтому не передавайте этот параметр. |
| callback_url | string | Нет | Куда отправить результат, когда задача завершится; подробнее — в разделе о вебхуках ниже. |
| n | integer | Нет | Каждая задача создаёт один ролик; передавать параметр не нужно. При значении больше 1 всё равно создаётся один ролик, но при отправке резервируется стоимость n роликов, а лишнее возвращается после завершения задачи. |
Другие поля (seed, negative_prompt, fps, watermark и т. п.) дальше не передаются и не влияют на цену; результат всегда в MP4 и возвращается в виде url.
Цена
Оплата за ролик: одна цена за ролик независимо от его длительности; зависит она только от разрешения. Сумма резервируется при отправке и полностью возвращается при ошибке. 1 кредит = $0.005.
| Разрешение | Кредитов за ролик | USD за ролик |
|---|---|---|
| 720P | 200 | $1.00 |
Референсные материалы
- Референсные изображения (не более 9) задают персонажей, сцену и стиль и никогда не используются как кадр; в промпте ссылайтесь на них как
@Image1,@Image2. - Эта модель не принимает референсные видео и аудио: если передать их, вернётся ошибка 400.
- Ролик выдаётся той длительности, которую вы заказали; для вертикального 9:16 — только 15 с.
- Реальные человеческие лица подходят в качестве референсных изображений, маскирование не требуется. Пожалуйста, убедитесь, что у вас есть право использовать внешность людей, изображённых на фото.
- Каждое изображение — публичная ссылка на изображение,
data:URI или base64, не более 16 MB; несколько изображений передавайте массивом вimages. При отправке мы сначала сохраняем изображения у себя, и только потом задача встаёт в очередь; изображение, которое не удаётся прочитать, отклоняется с ошибкой 400, вmessageуказано, какое именно, и ничего не списывается. - Референсные материалы мы размещаем у себя и храним 7 дней, готовые ролики — 15 дней.
Референсные изображения для персонажа и сцены
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: задача не создаётся, ничего не списывается. О неудаче после того, как задача принята, сообщает эндпоинт задачи, а резерв возвращается полностью. Все коды перечислены в разделе Коды ошибок.
Ошибки при отправке
| HTTP | code | Причина | Что делать |
|---|---|---|---|
| 400 | invalid_request | Недопустимый параметр: длительность, разрешение, пропорция или число референсов выходят за пределы, допустимые для этой модели; промпт слишком длинный; не удаётся прочитать референсное изображение или видео; передан audio: false модели, ролики которой всегда со звуком, и т. п. Что именно не так, указано в message. | Исправьте то, что указано в message, и отправьте снова. |
| 400 | invalid_callback_url | callback_url — не публичный адрес http(s) или длиннее 2000 символов. | Укажите адрес, доступный из интернета. |
| 400 | model_not_found | ID модели написан с ошибкой, model не передан или модель нельзя использовать на этом эндпоинте (например, чат-модель на эндпоинте изображений). | Берите ID модели из GET /v1/models или из справочника API. |
| 401 | invalid_api_key | Ключ не существует, удалён или отключён, либо отключён аккаунт. | Проверьте ключ на странице API Keys в консоли. |
| 402 | insufficient_quota | Баланса не хватает, чтобы зарезервировать стоимость этого запроса. Шлюз сначала резервирует максимально возможную стоимость запроса, поэтому ошибка может возникнуть и при всплеске одновременных вызовов. | Если был всплеск запросов, подождите несколько секунд и повторите; в остальных случаях пополните баланс. |
| 429 | rate_limit_exceeded | Превышен лимит запросов в минуту, заданный для этого ключа (считается за последние 60 секунд). Заголовка Retry-After нет. | Подождите несколько секунд и повторите или увеличьте лимит ключа в консоли. |
| 503 | model_maintenance | Модель на обслуживании и не принимает запросы; пока идёт обслуживание, другая модель вместо неё не ответит. | Повторите, когда обслуживание закончится; ход работ — на странице статуса. |
| 503 | service_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 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"}'