Видео
Видео делается минуты, а не секунды, поэтому вызывается так же задачей, что и изображение: постановка, опрос, ссылка на файл. Порядок один на все задачи и разобран в разделе Как устроена задача; здесь тот же вызов на примере одной модели этого вида.
Семейства
| Семейство | Что внутри | Страница |
|---|---|---|
| Kling | kling/3-0-video, kling/3-0-motion-control, kling/3-turbo-text-to-video, kling/3-turbo-image-to-video, kling/3-0-omni-text-to-video | Открыть |
| Seedance | seedance/2-5, seedance/2, seedance/2-fast, seedance/2-mini | Открыть |
| Wan | wan/3-0-video, wan/2-7-text-to-video, wan/2-7-image-to-video, wan/2-7-r2v, wan/2-7-videoedit | Открыть |
| MiniMax | minimax/h3-text-to-video, minimax/h3-image-to-video, minimax/h3-reference-to-video | Открыть |
| Gemini Omni | gemini-omni/flash-1-1 | Открыть |
| Veo | veo/3, veo/3-fast, veo/3-lite | Открыть |
Как вызывать
Ролик делается минуты, поэтому файл не приходит в ответ на запрос. Первый вызов
ставит задачу и сразу отвечает её номером, второй по этому номеру отдаёт состояние задачи, а когда
она готова — ссылку на результат. Ключ передаётся в обоих запросах заголовком
Authorization: Bearer sk-… и выпускается
в кабинете. На один ключ шлюз пропускает
30 постановок задачи и 300
запросов состояния в минуту.
Имя модели ставится в поле model тела запроса
POST /api/v1/jobs/createTask, а всё, что зависит от модели, уходит
вложенным объектом input. Ниже — готовый вызов на модели
kling/3-0-video; поля остальных моделей смотрите на странице
их семейства, тело запроса от этого не меняется.
Пример вызова
# 1. Поставить задачу — в ответе придёт её номер
TASK=$(curl -s https://api.gen202.com/api/v1/jobs/createTask \
-H "Authorization: Bearer sk-ваш-ключ" \
-H "Content-Type: application/json" \
-d '{
"model": "kling/3-0-video",
"input": {
"prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
"aspect_ratio": "16:9",
"duration": 3
}
}' | 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": "kling/3-0-video",
"input": {
"prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
"aspect_ratio": "16:9",
"duration": 3
}
},
).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": "kling/3-0-video",
"state": "success",
"resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
"failCode": "",
"failMsg": ""
}
}
Ссылка на файл лежит в resultJson — это строка, внутри которой ещё
один JSON, поэтому разбирать её нужно вторым разбором. Пока задача не завершилась, там пустая
строка, а в state — waiting,
queuing или generating. В настоящем ответе
есть ещё поле creditsConsumed со списанием; здесь его нет намеренно —
сумма зависит от запрошенного варианта, а цены живут в
каталоге. Все поля записи перечислены в разделе
Формат ответа.
Что учесть
-
Значения проверяются до обращения к поставщику. Поле не из списка модели или значение
вне перечисления возвращают
422и кредитов не стоят. -
Ждать дольше. Опрашивайте
/api/v1/jobs/recordInfoс паузой в 3 секунды. Задача на видео живёт не дольше 60 минут, после чего шлюз закрывает её сам состояниемfailи возвращает удержание целиком. - Счёт за секунды. У моделей с посекундной ценой итог зависит от длительности видео, а у моделей с видео на входе — от суммы длительностей входного и выходного. Сколько стоит секунда у каждой модели — в каталоге.
- Отказ не тарифицируется. Задача, закончившаяся отказом, не списывает кредитов: удержание возвращается на баланс целиком.