Как получить доступ к видео-API Seedance 2.0 (2026)
Быстрый старт Seedance 2.0 API: один ключ ofox, POST /v1/videos, опрос до completed, чтение unsigned_urls[0]. Код Python и Node, цена от $0.07/с.
Seedance 2.0 — это модель ByteDance для text-to-video и image-to-video, и самый быстрый способ её вызвать — через ofox: один API-ключ, оплата в долларах и единственный асинхронный REST-эндпоинт. Вы отправляете POST https://api.ofox.io/v1/videos с ID модели и промптом, получаете polling_url, опрашиваете задачу, пока статус не станет completed, затем читаете клип из unsigned_urls[0]. Никаких отдельных аккаунтов по вендорам, никакого отдельного SDK. Дальше — рабочий быстрый старт: аутентификация, вызов text-to-video на Python и Node, асинхронный жизненный цикл, входы с изображениями и референсами и сколько на самом деле стоит клип.
| Эндпоинт | POST https://api.ofox.io/v1/videos (async) |
| Аутентификация | один Bearer-ключ ofox |
| ID моделей | bytedance/seedance-2.0, -fast, -mini |
| Время до первого клипа | около 5 минут |
| Получить результат | опрос GET /v1/videos/{id}, чтение unsigned_urls[0] |
Что вам нужно
Три вещи, и две из них у вас уже есть, если вы используете ofox для чата или запросов изображений.
- API-ключ ofox. Базовый URL —
https://api.ofox.io/v1, а аутентификация — стандартный заголовокAuthorization: Bearer. Тот же ключ, что вы используете для OpenAI-совместимых запросов чата и изображений, отправляет и видеозадачи, поэтому отдельный аккаунт или вендорский SDK настраивать не нужно. - Эндпоинт. Всё идёт через
POST /v1/videosиGET /v1/videos/{id}. Это вся поверхность API. - ID модели.
bytedance/seedance-2.0— это флагман: text-to-video, image-to-video, video-to-video, синхронный звук, клипы от 4 до 15 секунд, вплоть до 4K.bytedance/seedance-2.0-fastиbytedance/seedance-2.0-mini— более дешёвые уровни, и оба упираются в 720p.
Задайте ключ один раз:
export OFOX_API_KEY="sk-..."
Первый запрос: text-to-video
Генерация видео — это не блокирующий вызов, как chat completion. Клипу нужно время на рендер, поэтому POST /v1/videos сразу возвращает 202 Accepted с polling_url, а вы опрашиваете этот URL, пока задача не достигнет терминального состояния. Режим определяется по полям, которые вы отправляете: отсутствие поля с изображением означает text-to-video.
Вот полный цикл на Python. Он отправляет задачу, опрашивает в разумном темпе и забирает клип из unsigned_urls[0].
import os, time, requests
BASE = "https://api.ofox.io/v1"
HEAD = {"Authorization": f"Bearer {os.environ['OFOX_API_KEY']}"}
TERMINAL = {"completed", "failed", "cancelled", "expired"}
job = requests.post(f"{BASE}/videos", headers=HEAD, json={
"model": "bytedance/seedance-2.0",
"prompt": "A red kayak cuts through morning fog on a still lake, slow dolly forward.",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9",
})
job.raise_for_status() # 202 Accepted
task_url = job.json()["polling_url"]
while True:
task = requests.get(task_url, headers=HEAD).json()
if task["status"] in TERMINAL: # выходим на ВСЕХ четырёх терминальных состояниях
break
time.sleep(2) # опрос каждые 1–2с, не в плотном цикле
if task["status"] == "completed":
print("clip:", task["unsigned_urls"][0]) # поля output_url не существует
print("billed:", task["usage"]["video_cost"], "USD",
"for", task["usage"]["video_seconds"], "s")
else:
print("job ended as:", task["status"])
Та же форма на Node с fetch:
const BASE = "https://api.ofox.io/v1";
const HEAD = {
Authorization: `Bearer ${process.env.OFOX_API_KEY}`,
"Content-Type": "application/json",
};
const TERMINAL = ["completed", "failed", "cancelled", "expired"];
const job = await fetch(`${BASE}/videos`, {
method: "POST",
headers: HEAD,
body: JSON.stringify({
model: "bytedance/seedance-2.0",
prompt: "A red kayak cuts through morning fog on a still lake, slow dolly forward.",
duration: 8,
resolution: "1080p",
aspect_ratio: "16:9",
}),
});
const { polling_url } = await job.json(); // 202 Accepted
let task;
do {
await new Promise((r) => setTimeout(r, 2000)); // опрос каждые 1–2с
task = await (await fetch(polling_url, { headers: HEAD })).json();
} while (!TERMINAL.includes(task.status));
if (task.status === "completed") {
console.log("clip:", task.unsigned_urls[0]); // не output_url
console.log("billed:", task.usage.video_cost, "USD");
}
Две вещи сбивают тех, кто вызывает API впервые. Первая — обращение к resp["output_url"], которого не существует и который возвращает None в Python или undefined в Node. Клип лежит в unsigned_urls[0]. Вторая — цикл опроса, который проверяет только completed. Задача, завершившаяся как failed или expired, никогда не выставит completed, поэтому цикл, игнорирующий остальные терминальные состояния, крутится вечно. Прерывайтесь на всех четырёх.
Работа с асинхронным жизненным циклом
Задача Seedance проходит через фиксированный набор состояний. Три из них промежуточные, четыре — терминальные. Состояния processing не существует, поэтому не проверяйте его.
| Статус | Фаза | Что делать |
|---|---|---|
pending | Принято, ещё не в очереди | Продолжайте опрос каждые 1–2с |
queued | В очереди на рендер | Продолжайте опрос каждые 1–2с |
in_progress | Рендеринг | Продолжайте опрос каждые 1–2с |
completed | Готово, URL приложены | Скачивайте из unsigned_urls[0] |
failed | Ошибка генерации | Прочитайте ошибку, повтор или запасной вариант |
cancelled | Вы отменили задачу | Прекратите опрос |
expired | Задача истекла | Отправьте заново |
Темп опроса важен. GET /v1/videos/{id} — не чаще одного раза в секунду; примерно раз в одну-две секунды — оптимально. Долбить эндпоинт в плотном цикле — это трата квоты, и быстрее вы ничего не получите, ведь клип всё равно рендерится в апстриме.
У URL результата ограниченный срок жизни, так что воспринимайте completed как сигнал к скачиванию. unsigned_urls истекают примерно через 24 часа после завершения задачи. mirror_urls постоянны, но у каждой подписанной ссылки всё равно свой TTL. На практике: как только статус переключается на completed, сразу забирайте unsigned_urls[0] в собственное хранилище (S3, R2, GCS), а не сохраняйте URL от API, чтобы позже отдавать его клиентам.
Для продакшена обычно нужен вебхук, а не поток опроса. Передайте callback_url при создании, и ofox отправит payload с HMAC-подписью, когда задача достигнет терминального состояния. Адрес должен быть публичным HTTPS; приватный, loopback или иным образом недостижимый хост отклоняется на этапе отправки с 400 invalid_callback_url. Опрос и вебхуки не исключают друг друга, поэтому распространённый паттерн — вебхук для основного сценария плюс медленный опрос как подстраховка.
Нужно остановить задачу раньше времени? DELETE /v1/videos/{id} отменяет её, и задача переходит в cancelled.
Image-to-video и референсные изображения
Чтобы оживить статичный кадр или направить генерацию референсными кадрами, менять эндпоинт не нужно. Тот же POST /v1/videos, тот же опрос. Режим запроса определяется по тому, какие поля вы включаете.
- Без поля с изображением — это text-to-video, вызов выше.
frame_imagesдаёт image-to-video. Передайте один URL для единственного стартового кадра или первый и последний кадр для интерполяции между ними.input_referencesдаёт генерацию по референсам, где вы предоставляете изображения, задающие идентичность, стиль или внешний вид продукта.
Image-to-video из стартового кадра:
job = requests.post(f"{BASE}/videos", headers=HEAD, json={
"model": "bytedance/seedance-2.0",
"prompt": "The logo tilts up and catches a rim light, subtle rotation.",
"frame_images": ["https://your-cdn.com/first-frame.png"],
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9",
})
Всё дальше по цепочке идентично: 202, polling_url, тот же набор статусов и клип в unsigned_urls[0]. Звук генерируется на всех трёх уровнях, поэтому называйте нужный звук в промпте, иначе унаследуете то, что домыслит модель.
Цена: за разрешение, а не единая ставка
Именно в этой цифре чаще всего ошибаются. from $0.07/с рядом с Seedance 2.0 в каталоге — это порог для 480p, а не единая ставка. Цена растёт с запрашиваемым разрешением, так что реальная стоимость клипа — это ставка за секунду на вашем разрешении, умноженная на длину клипа. Вот прайс-лист флагмана для text-to-video:
| Разрешение | bytedance/seedance-2.0 (text-to-video) |
|---|---|
| 480p | $0.07/с |
| 720p | $0.16/с |
| 1080p | $0.34/с |
| 4K | $1.37/с |
Тарификация идёт за каждую секунду вывода, и ответ completed сообщает точную сумму в usage.video_cost. Так, 8-секундный клип 1080p стоит 8 x $0.34 = $2.72, а тот же клип в 4K — 8 x $1.37 = $10.96. Video-to-video стоит чуть дороже за секунду, чем text-to-video, на каждом разрешении — страница модели расписывает это полностью.
Более дешёвые уровни разменивают разрешение на стоимость и оба упираются в 720p: bytedance/seedance-2.0-fast — $0.06/с на 480p и $0.13/с на 720p, а bytedance/seedance-2.0-mini — $0.04/с на 480p и $0.08/с на 720p. Если большая часть вашего вывода всё равно уходит в ленту, которая сжимает до 720p, Mini за $0.08/с — самая низкая ставка на 720p из трёх.
Поскольку все три уровня используют один и тот же эндпоинт и отличаются лишь строкой model, вы можете направлять черновики на Mini и приберечь флагман для мастеров. Полное сравнение бок о бок, включая то, когда надбавка Fast над Mini оправдана, — в сравнении уровней Seedance 2.0, а полную матрицу цен по разрешению — на странице модели Seedance 2.0.
Один ключ, все видеомодели
Этот быстрый старт короткий потому, что ofox сводит весь видеостек к одной аутентификации и одной схеме. Паттерн у вас уже есть: отправьте на /v1/videos, опросите, скачайте. Смена модели — это правка строки.
Генерируйте на Seedance 2.0 ключом, который у вас уже есть. Начните с видео-API ofox: один ключ, оплата в долларах, платите только за отрендеренные секунды, без регистрации по каждому вендору.
Если для конкретного клипа Seedance не подходит, тот же эндпоинт открывает доступ к остальному каталогу. Wan от Alibaba стартует с минимума в 2 секунды, тогда как у Seedance порог — 4 секунды; этот размен разобран в сравнении Seedance 2.0 vs Wan. Точные поля запроса и ответа, включая каждый необязательный параметр, — в справочнике по видео-API ofox.
FAQ
Как вызвать API Seedance 2.0?
Отправьте POST https://api.ofox.io/v1/videos с Bearer-ключом ofox и JSON-телом с полями model, prompt, duration, resolution и aspect_ratio. Он возвращает 202 и polling_url. Опрашивайте GET /v1/videos/{id} каждые 1–2 секунды, пока status не станет completed, затем читайте клип из unsigned_urls[0].
Почему URL видео пустой, когда я читаю output_url?
Поля output_url не существует. Клип лежит в unsigned_urls (это массив, поэтому используйте unsigned_urls[0]) или в mirror_urls. Чтение resp["output_url"] каждый раз возвращает None.
Как долго действительны URL результатов Seedance 2.0?
unsigned_urls истекают примерно через 24 часа после завершения. mirror_urls постоянны, но у каждой подписанной ссылки свой TTL. Скачивайте файл, как только статус станет completed.
Сколько стоит API Seedance 2.0? За каждую секунду вывода по разрешению, а не по единой ставке. Флагманский text-to-video стоит $0.07/с на 480p, $0.16/с на 720p, $0.34/с на 1080p и $1.37/с на 4K. 8-секундный клип 1080p стоит $2.72.
Может ли Seedance 2.0 генерировать видео из изображения?
Да. Передайте frame_images для image-to-video или input_references для генерации по референсам. Режим определяется по полям; без изображения — это text-to-video.
Какая модель Seedance 2.0 самая дешёвая?
bytedance/seedance-2.0-mini — $0.04/с для 480p и $0.08/с для 720p. Она упирается в 720p, как и -fast. Только флагман доходит до 1080p и 4K.
Источники, проверенные для этого обновления
- Каталог видеомоделей ofox и пороговые цены за секунду
- Страница модели Seedance 2.0 на ofox, цены по разрешению от 480p до 4K
- Справочник по видео-API ofox: эндпоинт, опрос, перечень статусов, callback_url
- ByteDance Seed, обзор модели Seedance
- Сравнение уровней Seedance 2.0: Mini, Fast и флагман
- Сравнение видео-API Seedance 2.0 vs Wan
