Seedance API
В каталоге 4 записи семейства Seedance: версии и режимы. Имя модели ставится в
поле model запроса createTask, а всё
остальное уходит вложенным объектом input. У каждой модели ниже её
поля, готовый вызов и ответ; общее для всех видео — на странице
Видео, а сам порядок вызова разобран в
разделе Как устроена задача.
Модели семейства
| Идентификатор | Модель | Задача | Страница на сайте |
|---|---|---|---|
| seedance/2-5 | Seedance 2.5 | text-to-video / image-to-video / reference-to-video | Открыть |
| seedance/2 | Seedance 2.0 | text-to-video / image-to-video / reference-to-video | Открыть |
| seedance/2-fast | Seedance 2.0 Fast | text-to-video / image-to-video / reference-to-video | Открыть |
| seedance/2-mini | Seedance 2.0 Mini | text-to-video / image-to-video / reference-to-video | Открыть |
Seedance 2.5
Открыть страницу моделиseedance/2-5
Поля запроса
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| model | текст | обязательное | seedance/2-5 |
| input | объект | обязательное | Параметры генерации — поля из таблицы ниже |
Поля input
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| prompt | текст | опц. | от 3 до 30 000 символов |
| first_frame_url | ссылка | опц. | одна ссылка на изображение |
| last_frame_url | ссылка | опц. | одна ссылка на изображение |
| reference_image_urls | список ссылок | опц. | до 30 ссылок на изображение |
| reference_video_urls | список ссылок | опц. | до 10 ссылок на видео |
| reference_audio_urls | список ссылок | опц. | до 10 ссылок на аудио |
| return_last_frame | да или нет | опц. | true или false |
| generate_audio | да или нет | опц. | true или false |
| resolution | значение из списка | опц. | 480p · 720p · 1080p |
| aspect_ratio | значение из списка | опц. | 1:1 · 4:3 · 3:4 · 16:9 · 9:16 · 21:9 · adaptive |
| duration | целое число | опц. | целое от 4 до 30 |
| output_format | значение из списка | опц. | mp4 · mov |
| web_search | да или нет | опц. | true или false |
| draft | да или нет | опц. | true или false |
| draft_task_id | текст | опц. | от 1 до 64 символов |
Поле draft. Черновик. Видео выходит в 480p и стоит как обычное в 480p; из готового черновика то же видео получают в 1080p — как это устроено.
Поле draft_task_id. Номер задачи черновика. Модель делает то же видео в 1080p, а остальное берёт из черновика — порядок двух запросов.
Черновик и тот же ролик в 1080p
Сначала делают черновик в 480p и смотрят, что получилось, затем по номеру его задачи получают тот же ролик в 1080p. Промпт, файлы, длительность, пропорции и звук второй запрос берёт из черновика.
Шаг 1. Черновик в 480p
К обычному запросу добавляют draft: true. Остальные поля и их правила те же. Поле resolution можно не присылать — шлюз поставит 480p; с другим значением запрос отклоняется.
curl -X POST "https://api.gen202.com/api/v1/jobs/createTask" \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2-5",
"input": {
"prompt": "Ginger cat in a white spacesuit floats in zero gravity above Earth. It slowly turns its head toward the camera, front paws drifting; sunlight glints across the helmet visor, the blue planet reflected in the glass. The camera eases backwards, revealing a solar panel at the edge of frame. Cinematic, soft rim light, shallow depth of field.",
"aspect_ratio": "1:1",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
],
"draft": true
}
}'
Номер задачи черновика приходит в ответе полем data.taskId. Второй запрос отправляют, когда задача пришла в состояние success:
curl "https://api.gen202.com/api/v1/jobs/recordInfo?taskId=cm8r4t0vk0001s60p2xq7f9ab" \
-H "Authorization: Bearer sk-ваш-ключ"
Шаг 2. Тот же ролик в 1080p
В поле draft_task_id передают номер задачи черновика. Поле resolution можно не присылать — шлюз поставит 1080p; с другим значением запрос отклоняется.
curl -X POST "https://api.gen202.com/api/v1/jobs/createTask" \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2-5",
"input": {
"draft_task_id": "cm8r4t0vk0001s60p2xq7f9ab",
"output_format": "mov"
}
}'
В ответе приходит номер новой задачи. Её состояние и ссылку на файл получают так же, как у любой задачи.
Эти поля второй запрос берёт из черновика. Присылать их вместе с draft_task_id нельзя — запрос отклоняется, даже если значения те же:
prompt, first_frame_url, last_frame_url, reference_image_urls, reference_video_urls, reference_audio_urls, generate_audio, aspect_ratio, duration, web_search.
Во втором запросе можно задать:
| Поле | Тип | Допустимые значения |
|---|---|---|
| resolution | значение из списка | только 1080p |
| output_format | значение из списка | mp4 · mov |
| return_last_frame | да или нет | true или false |
Поля draft: true и draft_task_id в одном запросе не принимаются.
Черновик годится 7 дней со дня создания.
Второй запрос отклоняется сразу, без удержания кредитов, если задачи с таким номером на аккаунте нет, она создана без draft: true, ещё не закончилась, закончилась отказом или черновику больше 7 дней.
Оплата черновика и второго запроса
Черновик считается как обычный ролик в 480p: ставки те же, ролик на входе учитывается как обычно.
Второй запрос считается по ставке 1080p без ролика на входе, на длительность черновика — даже если в черновике на входе был ролик.
| Длительность в запросе черновика | Черновик | Второй запрос |
|---|---|---|
| Число от 4 до 30 | 480p на эту длительность | 1080p на эту же длительность |
| Не задана | Удерживается сумма за 30 секунд в 480p, списывается по длине готового ролика | 1080p на длину готового черновика |
Пример вызова
# 1. Поставить задачу — в ответе придёт её номер
TASK=$(curl -s https://api.gen202.com/api/v1/jobs/createTask \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2-5",
"input": {
"prompt": "Ginger cat in a white spacesuit floats in zero gravity above Earth. It slowly turns its head toward the camera, front paws drifting; sunlight glints across the helmet visor, the blue planet reflected in the glass. The camera eases backwards, revealing a solar panel at the edge of frame. Cinematic, soft rim light, shallow depth of field.",
"aspect_ratio": "1:1",
"resolution": "720p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
}' | jq -r '.data.taskId')
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while true; do
RECORD=$(curl -s "https://api.gen202.com/api/v1/jobs/recordInfo?taskId=$TASK" \
-H "Authorization: Bearer sk-ваш-ключ")
STATE=$(echo "$RECORD" | jq -r '.data.state')
case "$STATE" in success|fail) break;; esac
sleep 3
done
# 3. Забрать результат. Ссылка на файл лежит в resultJson — это строка JSON
# внутри JSON, поэтому её разбирают вторым разбором (fromjson)
echo "$RECORD" | jq -r '.data |
if .state == "fail"
then "отказ \(.failCode): \(.failMsg)"
else .resultJson | fromjson | .resultUrls[0]
end'
import json
import time
import requests
headers = {"Authorization": "Bearer sk-ваш-ключ"}
# 1. Поставить задачу — в ответе придёт её номер
created = requests.post(
"https://api.gen202.com/api/v1/jobs/createTask",
headers=headers,
json={
"model": "seedance/2-5",
"input": {
"prompt": "Ginger cat in a white spacesuit floats in zero gravity above Earth. It slowly turns its head toward the camera, front paws drifting; sunlight glints across the helmet visor, the blue planet reflected in the glass. The camera eases backwards, revealing a solar panel at the edge of frame. Cinematic, soft rim light, shallow depth of field.",
"aspect_ratio": "1:1",
"resolution": "720p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
},
).json()
task_id = created["data"]["taskId"]
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while True:
task = requests.get(
"https://api.gen202.com/api/v1/jobs/recordInfo",
headers=headers,
params={"taskId": task_id},
).json()["data"]
if task["state"] in ("success", "fail"):
break
time.sleep(3)
# 3. Разобрать итог. У неудачи причина в failCode и failMsg
if task["state"] == "fail":
raise SystemExit("отказ " + task["failCode"] + ": " + task["failMsg"])
# resultJson — строка JSON внутри JSON, поэтому разбор второй
result = json.loads(task["resultJson"])
print(result["resultUrls"][0])
print("списано кредитов:", task["creditsConsumed"])
Пример проходит весь путь: ставит задачу, повторяет запрос состояния раз в
3 секунды, пока задача не закончится, и разбирает ответ до ссылки
на файл. Разборов два, потому что поле resultJson — строка JSON
внутри JSON. В теле первого запроса стоят обязательные поля модели и значения из её
перечислений, поэтому он проходит проверку шлюза как есть.
Подставить остаётся только свой ключ.
Пример на оболочке разбирает ответ через jq; на Python своего
ничего не нужно, кроме requests.
Ответ, когда задача готова
{
"code": 200,
"msg": "success",
"data": {
"taskId": "cm8r4t0vk0001s60p2xq7f9ab",
"model": "seedance/2-5",
"state": "success",
"resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
"failCode": "",
"failMsg": ""
}
}
Ссылка на файл лежит в resultJson — это строка, внутри которой ещё
один JSON, поэтому разбирать её нужно вторым разбором. Пока задача не завершилась, там пустая
строка, а в state — waiting,
queuing или generating. В настоящем ответе
есть ещё поле creditsConsumed со списанием; здесь его нет намеренно —
сумма зависит от запрошенного варианта, а цены живут в
каталоге. Все поля записи перечислены в разделе
Формат ответа.
Общее для всех моделей: Как устроена задача — чем отправить и как дождаться · Формат ответа — где в ответе ссылка на файл · Загрузка своих файлов — как получить ссылку на свою картинку · Отказы — что означает отказ
Seedance 2.0
Открыть страницу моделиseedance/2
Поля запроса
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| model | текст | обязательное | seedance/2 |
| input | объект | обязательное | Параметры генерации — поля из таблицы ниже |
Поля input
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| prompt | текст | обязательное | от 3 до 20 000 символов |
| first_frame_url | ссылка | опц. | одна ссылка на изображение |
| last_frame_url | ссылка | опц. | одна ссылка на изображение |
| reference_image_urls | список ссылок | опц. | до 9 ссылок на изображение |
| reference_video_urls | список ссылок | опц. | до 3 ссылок на видео |
| reference_audio_urls | список ссылок | опц. | до 3 ссылок на аудио |
| return_last_frame | да или нет | опц. | true или false |
| generate_audio | да или нет | опц. | true или false |
| resolution | значение из списка | опц. | 480p · 720p · 1080p · 4k |
| aspect_ratio | значение из списка | опц. | 1:1 · 4:3 · 3:4 · 16:9 · 9:16 · 21:9 · adaptive |
| duration | целое число | опц. | целое от 4 до 15 |
| web_search | да или нет | опц. | true или false |
Пример вызова
# 1. Поставить задачу — в ответе придёт её номер
TASK=$(curl -s https://api.gen202.com/api/v1/jobs/createTask \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2",
"input": {
"prompt": "Ginger cat in a white spacesuit floats in zero gravity above Earth. It slowly turns its head toward the camera, front paws drifting; sunlight glints across the helmet visor, the blue planet reflected in the glass. The camera eases backwards, revealing a solar panel at the edge of frame. Cinematic, soft rim light, shallow depth of field.",
"aspect_ratio": "1:1",
"resolution": "720p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
}' | jq -r '.data.taskId')
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while true; do
RECORD=$(curl -s "https://api.gen202.com/api/v1/jobs/recordInfo?taskId=$TASK" \
-H "Authorization: Bearer sk-ваш-ключ")
STATE=$(echo "$RECORD" | jq -r '.data.state')
case "$STATE" in success|fail) break;; esac
sleep 3
done
# 3. Забрать результат. Ссылка на файл лежит в resultJson — это строка JSON
# внутри JSON, поэтому её разбирают вторым разбором (fromjson)
echo "$RECORD" | jq -r '.data |
if .state == "fail"
then "отказ \(.failCode): \(.failMsg)"
else .resultJson | fromjson | .resultUrls[0]
end'
import json
import time
import requests
headers = {"Authorization": "Bearer sk-ваш-ключ"}
# 1. Поставить задачу — в ответе придёт её номер
created = requests.post(
"https://api.gen202.com/api/v1/jobs/createTask",
headers=headers,
json={
"model": "seedance/2",
"input": {
"prompt": "Ginger cat in a white spacesuit floats in zero gravity above Earth. It slowly turns its head toward the camera, front paws drifting; sunlight glints across the helmet visor, the blue planet reflected in the glass. The camera eases backwards, revealing a solar panel at the edge of frame. Cinematic, soft rim light, shallow depth of field.",
"aspect_ratio": "1:1",
"resolution": "720p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
},
).json()
task_id = created["data"]["taskId"]
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while True:
task = requests.get(
"https://api.gen202.com/api/v1/jobs/recordInfo",
headers=headers,
params={"taskId": task_id},
).json()["data"]
if task["state"] in ("success", "fail"):
break
time.sleep(3)
# 3. Разобрать итог. У неудачи причина в failCode и failMsg
if task["state"] == "fail":
raise SystemExit("отказ " + task["failCode"] + ": " + task["failMsg"])
# resultJson — строка JSON внутри JSON, поэтому разбор второй
result = json.loads(task["resultJson"])
print(result["resultUrls"][0])
print("списано кредитов:", task["creditsConsumed"])
Пример проходит весь путь: ставит задачу, повторяет запрос состояния раз в
3 секунды, пока задача не закончится, и разбирает ответ до ссылки
на файл. Разборов два, потому что поле resultJson — строка JSON
внутри JSON. В теле первого запроса стоят обязательные поля модели и значения из её
перечислений, поэтому он проходит проверку шлюза как есть.
Подставить остаётся только свой ключ.
Пример на оболочке разбирает ответ через jq; на Python своего
ничего не нужно, кроме requests.
Ответ, когда задача готова
{
"code": 200,
"msg": "success",
"data": {
"taskId": "cm8r4t0vk0001s60p2xq7f9ab",
"model": "seedance/2",
"state": "success",
"resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
"failCode": "",
"failMsg": ""
}
}
Ссылка на файл лежит в resultJson — это строка, внутри которой ещё
один JSON, поэтому разбирать её нужно вторым разбором. Пока задача не завершилась, там пустая
строка, а в state — waiting,
queuing или generating. В настоящем ответе
есть ещё поле creditsConsumed со списанием; здесь его нет намеренно —
сумма зависит от запрошенного варианта, а цены живут в
каталоге. Все поля записи перечислены в разделе
Формат ответа.
Общее для всех моделей: Как устроена задача — чем отправить и как дождаться · Формат ответа — где в ответе ссылка на файл · Загрузка своих файлов — как получить ссылку на свою картинку · Отказы — что означает отказ
Seedance 2.0 Fast
Открыть страницу моделиseedance/2-fast
Поля запроса
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| model | текст | обязательное | seedance/2-fast |
| input | объект | обязательное | Параметры генерации — поля из таблицы ниже |
Поля input
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| prompt | текст | обязательное | от 3 до 20 000 символов |
| first_frame_url | ссылка | опц. | одна ссылка на изображение |
| last_frame_url | ссылка | опц. | одна ссылка на изображение |
| reference_image_urls | список ссылок | опц. | до 9 ссылок на изображение |
| reference_video_urls | список ссылок | опц. | до 3 ссылок на видео |
| reference_audio_urls | список ссылок | опц. | до 3 ссылок на аудио |
| return_last_frame | да или нет | опц. | true или false |
| generate_audio | да или нет | опц. | true или false |
| resolution | значение из списка | опц. | 480p · 720p |
| aspect_ratio | значение из списка | опц. | 1:1 · 4:3 · 3:4 · 16:9 · 9:16 · 21:9 · adaptive |
| duration | целое число | опц. | целое от 4 до 15 |
| web_search | да или нет | опц. | true или false |
Пример вызова
# 1. Поставить задачу — в ответе придёт её номер
TASK=$(curl -s https://api.gen202.com/api/v1/jobs/createTask \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2-fast",
"input": {
"prompt": "The ginger cat in a white spacesuit from the reference image sits on a snowy mountain peak at dawn, snowflakes drift past. Cinematic, cold blue light.",
"aspect_ratio": "1:1",
"resolution": "480p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
}' | jq -r '.data.taskId')
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while true; do
RECORD=$(curl -s "https://api.gen202.com/api/v1/jobs/recordInfo?taskId=$TASK" \
-H "Authorization: Bearer sk-ваш-ключ")
STATE=$(echo "$RECORD" | jq -r '.data.state')
case "$STATE" in success|fail) break;; esac
sleep 3
done
# 3. Забрать результат. Ссылка на файл лежит в resultJson — это строка JSON
# внутри JSON, поэтому её разбирают вторым разбором (fromjson)
echo "$RECORD" | jq -r '.data |
if .state == "fail"
then "отказ \(.failCode): \(.failMsg)"
else .resultJson | fromjson | .resultUrls[0]
end'
import json
import time
import requests
headers = {"Authorization": "Bearer sk-ваш-ключ"}
# 1. Поставить задачу — в ответе придёт её номер
created = requests.post(
"https://api.gen202.com/api/v1/jobs/createTask",
headers=headers,
json={
"model": "seedance/2-fast",
"input": {
"prompt": "The ginger cat in a white spacesuit from the reference image sits on a snowy mountain peak at dawn, snowflakes drift past. Cinematic, cold blue light.",
"aspect_ratio": "1:1",
"resolution": "480p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
},
).json()
task_id = created["data"]["taskId"]
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while True:
task = requests.get(
"https://api.gen202.com/api/v1/jobs/recordInfo",
headers=headers,
params={"taskId": task_id},
).json()["data"]
if task["state"] in ("success", "fail"):
break
time.sleep(3)
# 3. Разобрать итог. У неудачи причина в failCode и failMsg
if task["state"] == "fail":
raise SystemExit("отказ " + task["failCode"] + ": " + task["failMsg"])
# resultJson — строка JSON внутри JSON, поэтому разбор второй
result = json.loads(task["resultJson"])
print(result["resultUrls"][0])
print("списано кредитов:", task["creditsConsumed"])
Пример проходит весь путь: ставит задачу, повторяет запрос состояния раз в
3 секунды, пока задача не закончится, и разбирает ответ до ссылки
на файл. Разборов два, потому что поле resultJson — строка JSON
внутри JSON. В теле первого запроса стоят обязательные поля модели и значения из её
перечислений, поэтому он проходит проверку шлюза как есть.
Подставить остаётся только свой ключ.
Пример на оболочке разбирает ответ через jq; на Python своего
ничего не нужно, кроме requests.
Ответ, когда задача готова
{
"code": 200,
"msg": "success",
"data": {
"taskId": "cm8r4t0vk0001s60p2xq7f9ab",
"model": "seedance/2-fast",
"state": "success",
"resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
"failCode": "",
"failMsg": ""
}
}
Ссылка на файл лежит в resultJson — это строка, внутри которой ещё
один JSON, поэтому разбирать её нужно вторым разбором. Пока задача не завершилась, там пустая
строка, а в state — waiting,
queuing или generating. В настоящем ответе
есть ещё поле creditsConsumed со списанием; здесь его нет намеренно —
сумма зависит от запрошенного варианта, а цены живут в
каталоге. Все поля записи перечислены в разделе
Формат ответа.
Общее для всех моделей: Как устроена задача — чем отправить и как дождаться · Формат ответа — где в ответе ссылка на файл · Загрузка своих файлов — как получить ссылку на свою картинку · Отказы — что означает отказ
Seedance 2.0 Mini
Открыть страницу моделиseedance/2-mini
Поля запроса
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| model | текст | обязательное | seedance/2-mini |
| input | объект | обязательное | Параметры генерации — поля из таблицы ниже |
Поля input
| Поле | Тип | Обяз. | Допустимые значения |
|---|---|---|---|
| prompt | текст | обязательное | от 3 до 20 000 символов |
| first_frame_url | ссылка | опц. | одна ссылка на изображение |
| last_frame_url | ссылка | опц. | одна ссылка на изображение |
| reference_image_urls | список ссылок | опц. | до 9 ссылок на изображение |
| reference_video_urls | список ссылок | опц. | до 3 ссылок на видео |
| reference_audio_urls | список ссылок | опц. | до 3 ссылок на аудио |
| generate_audio | да или нет | опц. | true или false |
| resolution | значение из списка | опц. | 480p · 720p |
| aspect_ratio | значение из списка | опц. | 1:1 · 4:3 · 3:4 · 16:9 · 9:16 · 21:9 · adaptive |
| duration | целое число | опц. | целое от 4 до 15 |
| web_search | да или нет | опц. | true или false |
Пример вызова
# 1. Поставить задачу — в ответе придёт её номер
TASK=$(curl -s https://api.gen202.com/api/v1/jobs/createTask \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance/2-mini",
"input": {
"prompt": "The ginger cat in a white spacesuit from the reference image walks along a sandy beach at sunset, waves roll in behind it. Cinematic, warm light.",
"aspect_ratio": "1:1",
"resolution": "480p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
}' | jq -r '.data.taskId')
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while true; do
RECORD=$(curl -s "https://api.gen202.com/api/v1/jobs/recordInfo?taskId=$TASK" \
-H "Authorization: Bearer sk-ваш-ключ")
STATE=$(echo "$RECORD" | jq -r '.data.state')
case "$STATE" in success|fail) break;; esac
sleep 3
done
# 3. Забрать результат. Ссылка на файл лежит в resultJson — это строка JSON
# внутри JSON, поэтому её разбирают вторым разбором (fromjson)
echo "$RECORD" | jq -r '.data |
if .state == "fail"
then "отказ \(.failCode): \(.failMsg)"
else .resultJson | fromjson | .resultUrls[0]
end'
import json
import time
import requests
headers = {"Authorization": "Bearer sk-ваш-ключ"}
# 1. Поставить задачу — в ответе придёт её номер
created = requests.post(
"https://api.gen202.com/api/v1/jobs/createTask",
headers=headers,
json={
"model": "seedance/2-mini",
"input": {
"prompt": "The ginger cat in a white spacesuit from the reference image walks along a sandy beach at sunset, waves roll in behind it. Cinematic, warm light.",
"aspect_ratio": "1:1",
"resolution": "480p",
"duration": 4,
"reference_image_urls": [
"https://gen202.com/assets/sample-nano-banana-pro.jpg"
]
}
},
).json()
task_id = created["data"]["taskId"]
# 2. Спрашивать состояние, пока задача не закончится: waiting, queuing и
# generating означают «работа идёт», success и fail — окончательные
while True:
task = requests.get(
"https://api.gen202.com/api/v1/jobs/recordInfo",
headers=headers,
params={"taskId": task_id},
).json()["data"]
if task["state"] in ("success", "fail"):
break
time.sleep(3)
# 3. Разобрать итог. У неудачи причина в failCode и failMsg
if task["state"] == "fail":
raise SystemExit("отказ " + task["failCode"] + ": " + task["failMsg"])
# resultJson — строка JSON внутри JSON, поэтому разбор второй
result = json.loads(task["resultJson"])
print(result["resultUrls"][0])
print("списано кредитов:", task["creditsConsumed"])
Пример проходит весь путь: ставит задачу, повторяет запрос состояния раз в
3 секунды, пока задача не закончится, и разбирает ответ до ссылки
на файл. Разборов два, потому что поле resultJson — строка JSON
внутри JSON. В теле первого запроса стоят обязательные поля модели и значения из её
перечислений, поэтому он проходит проверку шлюза как есть.
Подставить остаётся только свой ключ.
Пример на оболочке разбирает ответ через jq; на Python своего
ничего не нужно, кроме requests.
Ответ, когда задача готова
{
"code": 200,
"msg": "success",
"data": {
"taskId": "cm8r4t0vk0001s60p2xq7f9ab",
"model": "seedance/2-mini",
"state": "success",
"resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
"failCode": "",
"failMsg": ""
}
}
Ссылка на файл лежит в resultJson — это строка, внутри которой ещё
один JSON, поэтому разбирать её нужно вторым разбором. Пока задача не завершилась, там пустая
строка, а в state — waiting,
queuing или generating. В настоящем ответе
есть ещё поле creditsConsumed со списанием; здесь его нет намеренно —
сумма зависит от запрошенного варианта, а цены живут в
каталоге. Все поля записи перечислены в разделе
Формат ответа.
Общее для всех моделей: Как устроена задача — чем отправить и как дождаться · Формат ответа — где в ответе ссылка на файл · Загрузка своих файлов — как получить ссылку на свою картинку · Отказы — что означает отказ