Kling 3.0 API

model: kling/3-0-video

model: kling/3-turbo-text-to-video

model: kling/3-turbo-image-to-video

Одной моделью делает и ролик по описанию, и ролик из присланного изображения. Соотношение сторон 16:9, 9:16, 1:1, на вход до 2 изображений, описание до 20 000 символов. Модель Kuaishou.

Принимает текстовое описание и возвращает готовый ролик. Разрешение 720p, 1080p, соотношение сторон 1:1, 9:16, 16:9, описание до 2 500 символов. Модель Kuaishou.

Принимает изображение и оживляет его, возвращая ролик. Разрешение 720p, 1080p, на вход до 2 изображений, описание до 2 500 символов. Модель Kuaishou.

Цена: за секунду, от 15.12 кр. ($0.0756) до 75.6 кр. ($0.378).

Цена: за секунду, 720P — 20.16 кр. ($0.1008), 1080P — 25.2 кр. ($0.126).

Цена: за секунду, 720P — 20.16 кр. ($0.1008), 1080P — 25.2 кр. ($0.126).

кр. — кредиты, покупаются за рубли.

Песочница

Input

Поля multi_prompt, kling_elements задаются структурой и доступны только через API.

Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.

Ролик собирается после входа: новому счёту начисляют 50 кредитов, и первый ролик идёт на них. Ставка у этой модели 15.12–75.6 кр. за секунду. Войдите, чтобы начать.

{
  "model": "kling/3-0-video",
  "input": {
    "prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
    "aspect_ratio": "16:9",
    "duration": 3
  }
}
Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.
Output

Нажмите «Запустить» — готовый ролик появится здесь

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

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "cm8r4t0vk0001s60p2xq7f9ab",
    "model": "kling/3-0-video",
    "state": "success",
    "resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
    "failCode": "",
    "failMsg": "",
    "creditsConsumed": 15.12
  }
}
Input

Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.

Ролик собирается после входа: новому счёту начисляют 50 кредитов, и первый ролик идёт на них. Ставка у этой модели 20.16–25.2 кр. за секунду. Войдите, чтобы начать.

{
  "model": "kling/3-turbo-text-to-video",
  "input": {
    "prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
    "duration": 3,
    "aspect_ratio": "1:1",
    "resolution": "720p"
  }
}
Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.
Output

Нажмите «Запустить» — готовый ролик появится здесь

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

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "cm8r4t0vk0001s60p2xq7f9ab",
    "model": "kling/3-turbo-text-to-video",
    "state": "success",
    "resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
    "failCode": "",
    "failMsg": "",
    "creditsConsumed": 20.16
  }
}
Input

Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.

Ролик собирается после входа: новому счёту начисляют 50 кредитов, и первый ролик идёт на них. Ставка у этой модели 20.16–25.2 кр. за секунду. Войдите, чтобы начать.

{
  "model": "kling/3-turbo-image-to-video",
  "input": {
    "prompt": "Заменить фон на вечернюю городскую улицу, свет тёплый",
    "image_urls": [
      "https://gen202.com/assets/sample-nano-banana-2.jpg"
    ],
    "duration": 3,
    "resolution": "720p"
  }
}
Столько стоит этот запуск: ставка выбранного варианта × запрошенные секунды. Столько и спишется, когда работа закончится. Считаем по полям формы: ставка варианта × запрошенные секунды. Если поле влияет на цену, а вы его не заполнили, берём самое дорогое значение. Больше 15 не бывает: duration до 15 с. Спишется фактический расход, лишнее вернётся на баланс.
Output

Нажмите «Запустить» — готовый ролик появится здесь

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

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "cm8r4t0vk0001s60p2xq7f9ab",
    "model": "kling/3-turbo-image-to-video",
    "state": "success",
    "resultJson": "{\"resultUrls\":[\"https://file.example/result.mp4\"]}",
    "failCode": "",
    "failMsg": "",
    "creditsConsumed": 20.16
  }
}

Цена Kling 3.0

Цена за секунду. Списывается фактический расход, о котором сообщил поставщик.

Вариант Наша цена Скидка Официальная
without audio-720P 15.12 кр. · $0.07567,56 ₽ −10% $0.084
without audio-1080P 20.16 кр. · $0.100810,08 ₽ −10% $0.112
with audio-720P 22.68 кр. · $0.113411,34 ₽ −10% $0.126
with audio-1080P 30.24 кр. · $0.151215,12 ₽ −10% $0.168
4K 75.6 кр. · $0.37837,8 ₽ −10% $0.42

В среднем на 10% ниже официальной цены поставщика. кр. — кредиты, покупаются за рубли.

Цена за секунду. Списывается фактический расход, о котором сообщил поставщик.

Вариант Наша цена Скидка Официальная
720P 20.16 кр. · $0.100810,08 ₽ −10% $0.112
1080P 25.2 кр. · $0.12612,6 ₽ −10% $0.14

В среднем на 10% ниже официальной цены поставщика. кр. — кредиты, покупаются за рубли.

Цена за секунду. Списывается фактический расход, о котором сообщил поставщик.

Вариант Наша цена Скидка Официальная
720P 20.16 кр. · $0.100810,08 ₽ −10% $0.112
1080P 25.2 кр. · $0.12612,6 ₽ −10% $0.14

В среднем на 10% ниже официальной цены поставщика. кр. — кредиты, покупаются за рубли.

На время работы шлюз удерживает ставку выбранного разрешения, умноженную на запрошенную длительность; больше 1134 кредита по этой модели он не удержит ни при каком запросе (duration до 15 с). Разница между удержанием и фактическим расходом возвращается на баланс тем же запросом состояния, который увидел итог.

Вызов через API

POST https://api.gen202.com/api/v1/jobs/createTask
GET https://api.gen202.com/api/v1/jobs/recordInfo?taskId=…

Ролик делается минуты, поэтому файл не приходит в ответ на запрос. Первый вызов ставит задачу и сразу отвечает её номером, второй по этому номеру отдаёт состояние задачи, а когда она готова — ссылку на результат. Ключ передаётся в обоих запросах заголовком Authorization: Bearer sk-… и выпускается в кабинете. На один ключ шлюз пропускает 30 постановок задачи и 300 запросов состояния в минуту.

Поля запроса

Значения проверяются до обращения к поставщику: поле не из списка модели или значение вне перечисления возвращают 422 и кредитов не тратят.

ПолеТипОбяз.Допустимые значения
model текст обязательное kling/3-0-video
input объект обязательное Параметры генерации — поля из таблицы ниже

Поля input

ПолеТипОбяз.Допустимые значения
prompt текст обязательное от 1 до 20 000 символов
image_urls список ссылок опц. до 2 ссылок на изображение
sound да или нет опц. true или false
duration целое число опц. целое от 3 до 15
aspect_ratio значение из списка опц. 16:9 · 9:16 · 1:1
mode значение из списка опц. std · pro · 4K
multi_shots да или нет опц. true или false
multi_prompt структура опц. структура по документации поставщика, проверяется у него
kling_elements структура опц. структура по документации поставщика, проверяется у него

Ссылка на изображение принимается только полным адресом на http или https: не длиннее 2048 символов, на общедоступном сайте, без имени и пароля перед адресом и без порта, кроме 80 и 443. Относительный путь, а также адреса внутри сети — localhost, 127.0.0.1, 10.0.0.5, 192.168.1.2 — и имена без точки шлюз отклоняет ответом 422, к поставщику не обращаясь.

Ответ

Оба запроса отвечают одним конвертом: {"code":…,"msg":…,"data":…}, где code повторяет HTTP-статус, а полезное лежит в data. Тот же конверт приходит и при отказе — разбирать две формы ответа не нужно.

/api/v1/jobs/createTask

ПолеТипЧто в нём
data.taskId строка Номер задачи. Больше в ответе ничего нет и быть не может — работа только началась.

/api/v1/jobs/recordInfo

ПолеТипЧто в нём
data.taskId строка Номер задачи — тот же, что вернул createTask.
data.model строка Имя модели в том виде, в каком его прислал клиент.
data.state строка Состояние задачи: waiting, queuing, generating, success или fail.
data.param строка Параметры, с которыми задача создана, — строкой JSON внутри JSON.
data.resultJson строка Результат строкой JSON внутри JSON: {"resultUrls":["https://…"]} — разбирается вторым разбором. До завершения задачи — пустая строка.
data.failCode строка Код неудачи из таблицы ниже. У остальных задач — пустая строка.
data.failMsg строка Причина неудачи словами. Иначе пустая строка.
data.costTime число Сколько задача заняла, миллисекунды. Пока не завершилась — null.
data.completeTime число Когда завершилась, миллисекунды эпохи Unix. Пока не завершилась — null.
data.createTime число Когда создана, миллисекунды эпохи Unix.
data.updateTime число Когда состояние менялось в последний раз, миллисекунды эпохи Unix.
data.creditsConsumed число Сколько кредитов списано. Ноль, пока задача не завершилась, и ноль у неудачной.

Состояния задачи

Состояние лежит в поле state ответа /api/v1/jobs/recordInfo. Первые три означают, что работа идёт: запрос надо повторить примерно через 3 секунды — чаще спрашивать нечего, столько же ждёт между опросами сам шлюз. Два последних состояния окончательные: после них задача не меняется.

stateЧто происходит
waiting Задача принята и стоит в очереди шлюза; поставщику она ещё не отправлена.
queuing Поставщик задачу принял и поставил в свою очередь.
generating Генерация идёт.
success Готово: ссылки на результат лежат в resultJson, в creditsConsumed — сколько списано.
fail Задача не удалась: причина в failCode и failMsg, удержанные кредиты возвращены целиком.

Опрос не бывает бесконечным: задача на видео живёт не дольше 60 минут, после чего шлюз закрывает её сам состоянием fail и возвращает удержанные кредиты целиком. Причина неудачи приходит двумя полями: failCode из таблицы ниже и failMsg словами.

failCodeЧто произошло
501 Поставщик вернул отказ: генерация не удалась.
408 Результата нет дольше крайнего срока задачи (60 минут для видео).
404 Поставщик не знает такой задачи.
429 Поставщик отбил создание задачи по своему лимиту.
500 Поломка на нашей стороне; подробности остаются в журнале шлюза.

Ссылка на готовый файл живёт 14 дней — столько его хранит поставщик. Файл, который нужен дольше, скачивайте к себе сразу после того, как задача пришла в состояние success.

Отказы

Тело отказа одно на все случаи: {"code":…,"msg":…,"data":null}. Задача, не дошедшая до результата, не тарифицируется — удержанные кредиты возвращаются целиком.

КодАдресКогда
400 /api/v1/jobs/createTask Тело запроса — не разбираемый JSON.
401 /api/v1/jobs/createTask Ключа нет в заголовке Authorization, либо он неверный или отключён.
402 /api/v1/jobs/createTask Свободных кредитов меньше, чем удерживается под задачу.
413 /api/v1/jobs/createTask Тело запроса больше 512 КиБ.
415 /api/v1/jobs/createTask Тело отправлено не как application/json или заголовок Content-Type не передан.
422 /api/v1/jobs/createTask Поле model пустое или его имени нет в каталоге, input — не объект, поле не из списка модели либо значение вне её перечисления. В сообщении перечислено, что принимается.
429 /api/v1/jobs/createTask Больше 30 запросов в минуту на один ключ либо больше 50 незавершённых задач на аккаунте.
500 /api/v1/jobs/createTask Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.
401 /api/v1/jobs/recordInfo Ключа нет в заголовке Authorization, либо он неверный или отключён.
404 /api/v1/jobs/recordInfo Задачи с таким номером нет или она создана другим аккаунтом.
422 /api/v1/jobs/recordInfo Параметр taskId не передан.
429 /api/v1/jobs/recordInfo Больше 300 запросов в минуту на один ключ.
500 /api/v1/jobs/recordInfo Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.

Пример вызова

task.sh
# 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'
task.py
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.

POST https://api.gen202.com/api/v1/jobs/createTask
GET https://api.gen202.com/api/v1/jobs/recordInfo?taskId=…

Ролик делается минуты, поэтому файл не приходит в ответ на запрос. Первый вызов ставит задачу и сразу отвечает её номером, второй по этому номеру отдаёт состояние задачи, а когда она готова — ссылку на результат. Ключ передаётся в обоих запросах заголовком Authorization: Bearer sk-… и выпускается в кабинете. На один ключ шлюз пропускает 30 постановок задачи и 300 запросов состояния в минуту.

Поля запроса

Значения проверяются до обращения к поставщику: поле не из списка модели или значение вне перечисления возвращают 422 и кредитов не тратят.

ПолеТипОбяз.Допустимые значения
model текст обязательное kling/3-turbo-text-to-video
input объект обязательное Параметры генерации — поля из таблицы ниже

Поля input

ПолеТипОбяз.Допустимые значения
prompt текст обязательное от 1 до 2 500 символов
duration целое число обязательное целое от 3 до 15
aspect_ratio значение из списка обязательное 1:1 · 9:16 · 16:9
resolution значение из списка опц. 720p · 1080p

Ответ

Оба запроса отвечают одним конвертом: {"code":…,"msg":…,"data":…}, где code повторяет HTTP-статус, а полезное лежит в data. Тот же конверт приходит и при отказе — разбирать две формы ответа не нужно.

/api/v1/jobs/createTask

ПолеТипЧто в нём
data.taskId строка Номер задачи. Больше в ответе ничего нет и быть не может — работа только началась.

/api/v1/jobs/recordInfo

ПолеТипЧто в нём
data.taskId строка Номер задачи — тот же, что вернул createTask.
data.model строка Имя модели в том виде, в каком его прислал клиент.
data.state строка Состояние задачи: waiting, queuing, generating, success или fail.
data.param строка Параметры, с которыми задача создана, — строкой JSON внутри JSON.
data.resultJson строка Результат строкой JSON внутри JSON: {"resultUrls":["https://…"]} — разбирается вторым разбором. До завершения задачи — пустая строка.
data.failCode строка Код неудачи из таблицы ниже. У остальных задач — пустая строка.
data.failMsg строка Причина неудачи словами. Иначе пустая строка.
data.costTime число Сколько задача заняла, миллисекунды. Пока не завершилась — null.
data.completeTime число Когда завершилась, миллисекунды эпохи Unix. Пока не завершилась — null.
data.createTime число Когда создана, миллисекунды эпохи Unix.
data.updateTime число Когда состояние менялось в последний раз, миллисекунды эпохи Unix.
data.creditsConsumed число Сколько кредитов списано. Ноль, пока задача не завершилась, и ноль у неудачной.

Состояния задачи

Состояние лежит в поле state ответа /api/v1/jobs/recordInfo. Первые три означают, что работа идёт: запрос надо повторить примерно через 3 секунды — чаще спрашивать нечего, столько же ждёт между опросами сам шлюз. Два последних состояния окончательные: после них задача не меняется.

stateЧто происходит
waiting Задача принята и стоит в очереди шлюза; поставщику она ещё не отправлена.
queuing Поставщик задачу принял и поставил в свою очередь.
generating Генерация идёт.
success Готово: ссылки на результат лежат в resultJson, в creditsConsumed — сколько списано.
fail Задача не удалась: причина в failCode и failMsg, удержанные кредиты возвращены целиком.

Опрос не бывает бесконечным: задача на видео живёт не дольше 60 минут, после чего шлюз закрывает её сам состоянием fail и возвращает удержанные кредиты целиком. Причина неудачи приходит двумя полями: failCode из таблицы ниже и failMsg словами.

failCodeЧто произошло
501 Поставщик вернул отказ: генерация не удалась.
408 Результата нет дольше крайнего срока задачи (60 минут для видео).
404 Поставщик не знает такой задачи.
429 Поставщик отбил создание задачи по своему лимиту.
500 Поломка на нашей стороне; подробности остаются в журнале шлюза.

Ссылка на готовый файл живёт 14 дней — столько его хранит поставщик. Файл, который нужен дольше, скачивайте к себе сразу после того, как задача пришла в состояние success.

Отказы

Тело отказа одно на все случаи: {"code":…,"msg":…,"data":null}. Задача, не дошедшая до результата, не тарифицируется — удержанные кредиты возвращаются целиком.

КодАдресКогда
400 /api/v1/jobs/createTask Тело запроса — не разбираемый JSON.
401 /api/v1/jobs/createTask Ключа нет в заголовке Authorization, либо он неверный или отключён.
402 /api/v1/jobs/createTask Свободных кредитов меньше, чем удерживается под задачу.
413 /api/v1/jobs/createTask Тело запроса больше 512 КиБ.
415 /api/v1/jobs/createTask Тело отправлено не как application/json или заголовок Content-Type не передан.
422 /api/v1/jobs/createTask Поле model пустое или его имени нет в каталоге, input — не объект, поле не из списка модели либо значение вне её перечисления. В сообщении перечислено, что принимается.
429 /api/v1/jobs/createTask Больше 30 запросов в минуту на один ключ либо больше 50 незавершённых задач на аккаунте.
500 /api/v1/jobs/createTask Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.
401 /api/v1/jobs/recordInfo Ключа нет в заголовке Authorization, либо он неверный или отключён.
404 /api/v1/jobs/recordInfo Задачи с таким номером нет или она создана другим аккаунтом.
422 /api/v1/jobs/recordInfo Параметр taskId не передан.
429 /api/v1/jobs/recordInfo Больше 300 запросов в минуту на один ключ.
500 /api/v1/jobs/recordInfo Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.

Пример вызова

task.sh
# 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-turbo-text-to-video",
    "input": {
      "prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
      "duration": 3,
      "aspect_ratio": "1:1",
      "resolution": "720p"
    }
  }' | 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'
task.py
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-turbo-text-to-video",
      "input": {
        "prompt": "Рыжий кот в скафандре на фоне Земли, мягкий свет",
        "duration": 3,
        "aspect_ratio": "1:1",
        "resolution": "720p"
      }
    },
).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.

POST https://api.gen202.com/api/v1/jobs/createTask
GET https://api.gen202.com/api/v1/jobs/recordInfo?taskId=…

Ролик делается минуты, поэтому файл не приходит в ответ на запрос. Первый вызов ставит задачу и сразу отвечает её номером, второй по этому номеру отдаёт состояние задачи, а когда она готова — ссылку на результат. Ключ передаётся в обоих запросах заголовком Authorization: Bearer sk-… и выпускается в кабинете. На один ключ шлюз пропускает 30 постановок задачи и 300 запросов состояния в минуту.

Поля запроса

Значения проверяются до обращения к поставщику: поле не из списка модели или значение вне перечисления возвращают 422 и кредитов не тратят.

ПолеТипОбяз.Допустимые значения
model текст обязательное kling/3-turbo-image-to-video
input объект обязательное Параметры генерации — поля из таблицы ниже

Поля input

ПолеТипОбяз.Допустимые значения
prompt текст обязательное от 1 до 2 500 символов
image_urls список ссылок обязательное от 1 до 2 ссылок на изображение
duration целое число обязательное целое от 3 до 15
resolution значение из списка опц. 720p · 1080p

Ссылка на изображение принимается только полным адресом на http или https: не длиннее 2048 символов, на общедоступном сайте, без имени и пароля перед адресом и без порта, кроме 80 и 443. Относительный путь, а также адреса внутри сети — localhost, 127.0.0.1, 10.0.0.5, 192.168.1.2 — и имена без точки шлюз отклоняет ответом 422, к поставщику не обращаясь.

Ответ

Оба запроса отвечают одним конвертом: {"code":…,"msg":…,"data":…}, где code повторяет HTTP-статус, а полезное лежит в data. Тот же конверт приходит и при отказе — разбирать две формы ответа не нужно.

/api/v1/jobs/createTask

ПолеТипЧто в нём
data.taskId строка Номер задачи. Больше в ответе ничего нет и быть не может — работа только началась.

/api/v1/jobs/recordInfo

ПолеТипЧто в нём
data.taskId строка Номер задачи — тот же, что вернул createTask.
data.model строка Имя модели в том виде, в каком его прислал клиент.
data.state строка Состояние задачи: waiting, queuing, generating, success или fail.
data.param строка Параметры, с которыми задача создана, — строкой JSON внутри JSON.
data.resultJson строка Результат строкой JSON внутри JSON: {"resultUrls":["https://…"]} — разбирается вторым разбором. До завершения задачи — пустая строка.
data.failCode строка Код неудачи из таблицы ниже. У остальных задач — пустая строка.
data.failMsg строка Причина неудачи словами. Иначе пустая строка.
data.costTime число Сколько задача заняла, миллисекунды. Пока не завершилась — null.
data.completeTime число Когда завершилась, миллисекунды эпохи Unix. Пока не завершилась — null.
data.createTime число Когда создана, миллисекунды эпохи Unix.
data.updateTime число Когда состояние менялось в последний раз, миллисекунды эпохи Unix.
data.creditsConsumed число Сколько кредитов списано. Ноль, пока задача не завершилась, и ноль у неудачной.

Состояния задачи

Состояние лежит в поле state ответа /api/v1/jobs/recordInfo. Первые три означают, что работа идёт: запрос надо повторить примерно через 3 секунды — чаще спрашивать нечего, столько же ждёт между опросами сам шлюз. Два последних состояния окончательные: после них задача не меняется.

stateЧто происходит
waiting Задача принята и стоит в очереди шлюза; поставщику она ещё не отправлена.
queuing Поставщик задачу принял и поставил в свою очередь.
generating Генерация идёт.
success Готово: ссылки на результат лежат в resultJson, в creditsConsumed — сколько списано.
fail Задача не удалась: причина в failCode и failMsg, удержанные кредиты возвращены целиком.

Опрос не бывает бесконечным: задача на видео живёт не дольше 60 минут, после чего шлюз закрывает её сам состоянием fail и возвращает удержанные кредиты целиком. Причина неудачи приходит двумя полями: failCode из таблицы ниже и failMsg словами.

failCodeЧто произошло
501 Поставщик вернул отказ: генерация не удалась.
408 Результата нет дольше крайнего срока задачи (60 минут для видео).
404 Поставщик не знает такой задачи.
429 Поставщик отбил создание задачи по своему лимиту.
500 Поломка на нашей стороне; подробности остаются в журнале шлюза.

Ссылка на готовый файл живёт 14 дней — столько его хранит поставщик. Файл, который нужен дольше, скачивайте к себе сразу после того, как задача пришла в состояние success.

Отказы

Тело отказа одно на все случаи: {"code":…,"msg":…,"data":null}. Задача, не дошедшая до результата, не тарифицируется — удержанные кредиты возвращаются целиком.

КодАдресКогда
400 /api/v1/jobs/createTask Тело запроса — не разбираемый JSON.
401 /api/v1/jobs/createTask Ключа нет в заголовке Authorization, либо он неверный или отключён.
402 /api/v1/jobs/createTask Свободных кредитов меньше, чем удерживается под задачу.
413 /api/v1/jobs/createTask Тело запроса больше 512 КиБ.
415 /api/v1/jobs/createTask Тело отправлено не как application/json или заголовок Content-Type не передан.
422 /api/v1/jobs/createTask Поле model пустое или его имени нет в каталоге, input — не объект, поле не из списка модели либо значение вне её перечисления. В сообщении перечислено, что принимается.
429 /api/v1/jobs/createTask Больше 30 запросов в минуту на один ключ либо больше 50 незавершённых задач на аккаунте.
500 /api/v1/jobs/createTask Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.
401 /api/v1/jobs/recordInfo Ключа нет в заголовке Authorization, либо он неверный или отключён.
404 /api/v1/jobs/recordInfo Задачи с таким номером нет или она создана другим аккаунтом.
422 /api/v1/jobs/recordInfo Параметр taskId не передан.
429 /api/v1/jobs/recordInfo Больше 300 запросов в минуту на один ключ.
500 /api/v1/jobs/recordInfo Поломка на нашей стороне. Подробности остаются в журнале шлюза и наружу не уходят.

Пример вызова

task.sh
# 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-turbo-image-to-video",
    "input": {
      "prompt": "Заменить фон на вечернюю городскую улицу, свет тёплый",
      "image_urls": [
        "https://gen202.com/assets/sample-nano-banana-2.jpg"
      ],
      "duration": 3,
      "resolution": "720p"
    }
  }' | 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'
task.py
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-turbo-image-to-video",
      "input": {
        "prompt": "Заменить фон на вечернюю городскую улицу, свет тёплый",
        "image_urls": [
          "https://gen202.com/assets/sample-nano-banana-2.jpg"
        ],
        "duration": 3,
        "resolution": "720p"
      }
    },
).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.

Остальные модели этого семейства и их поля — в разделе документации Видео.

Что делает нейросеть Kling 3.0

Kling 3.0 — нейросеть Kuaishou: она снимает видео с родным звуком, одним кадром или несколькими подряд.

Старшая запись идёт под одним именем и берёт обе работы сразу: видео из текста и видео из изображения. Кадр для второй передаётся ссылкой, и список image_urls берёт до 2 ссылок.

Kling 3.0 Turbo стоит на этой же странице двумя отдельными записями, и в поле model у них разные имена: kling/3-turbo-text-to-video и kling/3-turbo-image-to-video.

Родной звук включается флагом sound, а ролик со звуком и без него стоит в таблице цен порознь: строки на то и другое разные.

Кадры многокадрового ролика и закреплённые элементы приходят своими полями — multi_prompt и kling_elements. Как устроено каждое из них, разбирает поставщик, а не наш шлюз; остальные поля перечислены в разделе «Kling».

Как пользоваться Kling 3.0 бесплатно и можно ли её скачать

У Kling 3.0 платят по расходу: с баланса уходит ставка за каждую секунду готового ролика, а поднимают её разрешение и звук. Новому счёту при первом входе начисляют приветственные кредиты, и первый ролик снимают на них. Ежемесячного платежа нет, а задача, закончившаяся отказом, возвращает удержание на баланс целиком.

Сама модель работает на стороне Kuaishou и запускается по сети, поэтому у себя разворачивать нечего. Через нас забирают результат: готовый ролик из песочницы приходит файлом mp4.

Официальный сайт Kling 3.0 принадлежит Kuaishou, а мы — независимый продавец доступа к его моделям. Имена полей и допустимые значения при этом взяты у разработчика: их видно в таблице выше.

Порядок работы одинаков у всех трёх записей страницы, и меняются в нём только значения полей.

  1. Соберите описание кадра. Поле prompt принимает сцену целиком: героя, его действие, обстановку вокруг и движение камеры.
  2. Приложите исходный кадр. Ссылку на картинку кладут в поле image_urls, и тогда ролик отталкивается от неё, а не сочиняется с нуля.
  3. Выберите разрешение и длительность. Разрешение у старшей записи выбирает поле mode, у Kling 3.0 Turbo — поле resolution, а секунды ставят в duration.
  4. Решите, нужен ли родной звук. Флаг sound добавляет к картинке звуковую дорожку, и от него же зависит строка цены.
  5. Разложите рассказ по кадрам. Флаг multi_shots отдаёт переходы между планами модели, а поле multi_prompt описывает каждый план по отдельности.

Чем Kling 3.0 Turbo отличается от Kling 3.0

Разницу между записями Kuaishou свёл в свою таблицу возможностей, и видна она прямо в полях запроса.

ЧтоKling 3.0Kling 3.0 Turbo
Разрешенияполе mode: std, pro и 4Kполе resolution: 720p и 1080p
Кадры на входепервый и последнийпервый
Закрепление элементовполе kling_elements
Перенос движения с готового роликаесть
Многокадровый рассказестьесть
Родной звукестьесть
Обязательные поляpromptKling 3.0 Turbo text-to-video — prompt, duration и aspect_ratio; Kling 3.0 Turbo image-to-video — prompt, image_urls и duration

Многокадровый рассказ и родной звук Kuaishou называет общими для обеих записей, а 4K, последний кадр и закрепление элементов оставил старшей.

Какой длины и в каком разрешении выходит ролик Kling 3.0

Ролик выходит от 3 до 15 секунд, и вилка эта общая для старшей записи и для обоих Turbo.

Разрешение у Kling 3.0 выбирают режимом: Kling 3.0 pro — это 1080p, std — 720p, а 4K назван прямо. У Turbo выбор из двух: 720p и 1080p.

Форм кадра у старшей записи 3: 16:9, 9:16, 1:1.

Что Kuaishou заложил в Kling 3.0

Модель собрана единым обучением на двух прошлых — VIDEO O1 и VIDEO 2.6. От них ей достались звук и удержание облика, а предел длительности при этом подняли.

С включённым многокадровым режимом переходы между кадрами модель планирует сама. С выключенным выходит один кадр без склеек.

Элемент — это закреплённый персонаж или предмет, и заводят его двумя способами. Первый: прислать ролик с ним, откуда сама модель вытащит внешность и голос. Второй: прислать несколько его снимков.

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

Чего Kuaishou не обещает от Kling 3.0 Turbo

Из двух кадров Turbo принимает только первый: связки «первый и последний» и «только последний» названы пока не сделанными.

Родное 4K объявлено для Kling 3.0, и работы, где оно есть, — это видео из текста и видео из изображения.

Перенос движения и мимики с готового ролика вынесен отдельной записью каталога: за ним идут на Kling 3.0 Motion Control.

Что чаще всего идёт не так в Kling 3.0 и как это обходят

Ниже — то, что видно на съёмке и о чём документация молчит: места, где ролик выходит не тем, и обходы, которые для них нашли.

  • К концу длинного ролика речь расходится с губами: герой замолкает раньше, чем договорил. Реплики поэтому ставят в начало, а последние планы делают без слов.
  • Много реплик в одном описании модель старается уместить целиком и торопится. Разговор надёжнее разложить по нескольким коротким планам.
  • Модель договаривает за автора: в кадре появляются лишний человек, лишняя сцена или надпись, которых не просили. Иногда герой заговаривает сам собой — тогда в описании прямо пишут, что он молчит.
  • Закреплённый элемент и многокадровый рассказ спорят между собой: элемент держит облик героя, а заказанная смена планов при этом выполняется не вся.
  • Подробное описание, собранное чат-ботом, модель понимает слишком буквально: от слова «стоит» герой замирает совсем. Короткое описание одного действия срабатывает точнее.
  • Движение камеры уходит не туда: вместо камеры едет предмет или кадр начинает мелко трястись. Помогает прямое указание, что предмет остаётся на месте.
  • Когда заданы и первый кадр, и последний, действие между ними выполняется хуже. Тот же замысел выходит лучше с одного кадра и многокадрового режима.
  • На общем плане лицо героя расползается, а люди на дальнем плане движутся одинаково и дёргано. Крупность плана поэтому выбирают под лицо, а массовку оставляют спокойной.
  • Звук сцены иногда не сходится с картинкой: за закрытой дверью слышна улица. Такой ролик переснимают, а не правят описанием.
  • Годный ролик редко выходит с первой попытки. Сломавшийся план переснимают отдельно или вырезают при монтаже, а не переделывают всё целиком.

Общий порядок из этого складывается такой: одно действие на план, короткое описание и проверка замысла на низком разрешении, где секунда стоит меньше.

Канал Kling AI — представление модели от 4 февраля 2026 года: пятнадцатисекундные ролики, несколько кадров подряд, встроенный звук. Идёт около двух минут.

Частые вопросы

Как вызвать Kling 3.0 через API из России?
Запрос уходит на api.gen202.com, и это адрес GEN202, а не адрес Kuaishou: обращения за границу в вызове Kling 3.0 нет, поэтому VPN не требуется. В поле model уходит идентификатор выбранного варианта: 3.0 (kling/3-0-video), turbo · текст в видео (kling/3-turbo-text-to-video), turbo · картинка в видео (kling/3-turbo-image-to-video). Порядок вызова Kling 3.0 с примерами кода разобран в документации.
Сколько стоит Kling 3.0
Цена за секунду Kling 3.0 — от 15.12 кр. до 75.6 кр. У Kling 3.0 списывается фактический расход, а задача, завершившаяся ошибкой, не тарифицируется вовсе.
Нужны ли VPN и иностранная карта для Kling 3.0
Ни то, ни другое: обращение к Kling 3.0 идёт на наш адрес, а расчёты с Kuaishou ведём мы, поэтому договариваться с ним клиенту не о чем. Оплата рублями с карты российского банка.
Что Kling 3.0 принимает на вход
Обязательные поля запроса к Kling 3.0: 3.0 — prompt — от 1 до 20 000 символов. Turbo · текст в видео — prompt — от 1 до 2 500 символов; duration — целое от 3 до 15; aspect_ratio — 1:1 · 9:16 · 16:9. Turbo · картинка в видео — prompt — от 1 до 2 500 символов; image_urls — от 1 до 2 ссылок на изображение; duration — целое от 3 до 15. Остальные поля необязательны.
Как подключить Kling 3.0 API и сделать первый вызов
Войти на сайт и выпустить ключ в кабинете: при первом входе начисляется 50 кредитов, и этот же ключ открывает Kling 3.0 вместе с остальным каталогом. Собственного ключа Kuaishou и договора с ним для вызова Kling 3.0 не нужно.