Создаёт видео по референсам, изображению или тексту, редактирует и продлевает ролики со звуком. Цена за секунду: 720p — 24 ₽, 1080p — 36 ₽; редактирование — 28 ₽ и 42 ₽ соответственно.
Общая документация Public API · API-ключ можно создать в настройках аккаунта
Kling 4.0 позволяет собрать ролик по описанию и референсам, оживить кадр, изменить готовое видео или добавить к нему продолжение. Для каждой задачи выбирайте свой тип генерации и передавайте только его параметры. Выполнение асинхронное.
Отправьте POST https://bratuha.ru/api/v1/operations с заголовком Authorization: Bearer brth_ваш_ключ и JSON. Полученный id сохраните для проверки результата.
Пять типов генерации: reference - по референсам, image - из изображения, text - из текста, edit - редактирование, extend - продление.
{
"tool": "kling-4-0",
"input": {
"generation_type": "text",
"prompt": "Бумажный кораблик плывёт по луже после дождя; низкая камера следует за ним, слышны капли.",
"resolution": "720p",
"duration": 5,
"text_aspect_ratio": "16:9"
}
}
tool содержит kling-4-0, а input - настройки выбранного режима. У каждого нового запуска должен быть свой UUID в заголовке Idempotency-Key. Повтор того же запроса с тем же ключом в течение 24 часов возвращает исходную операцию. Необязательный max_price на верхнем уровне ограничивает допустимое списание в рублях.
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
generation_type | string | Да | Тип генерации: reference, image, text, edit, extend. Без значения выбирается reference. |
prompt | string | Кроме image | Задание для референсов, текста, правки и продления. В референсах доступны @Image1, @Video1, @Audio1; в правке @Video1 обозначает исходное видео. Нумерация начинается с 1 и совпадает с порядком файлов. |
image_prompt | string | Нет | Задание в режиме image; можно оставить пустым. |
images | string[] | Нет | До 10 URL JPG/PNG для reference и edit. |
videos | string[] | Нет | До 5 URL MP4 в reference, суммарная длительность до 30 секунд. |
audios | string[] | Нет | До 3 URL MP3/WAV для reference. Каждый файл должен длиться 5–30 секунд; проверка выполняется до списания. Теги @Audio1, @Audio2, @Audio3 соответствуют порядку массива. |
image | string | В image | URL первого кадра, JPG/PNG. |
use_last_image | boolean | Нет | Включает конечный кадр в image и extend. Исходное значение false. |
last_image | string | При use_last_image=true | URL конечного кадра JPG/PNG в image и extend. |
keyframes | string[] | Нет | Промежуточные кадры JPG/PNG по порядку в image. До 9 без конечного кадра, до 8 с ним; общее число изображений максимум 10. |
Обязательность зависит от режима. Для параметров с исходным значением можно не передавать значение, если оно подходит. Файлы передаются доступными HTTP/HTTPS-ссылками; данные файла в JSON не вставляются.
Для совместимости принимаются прежние audio_1, audio_2, audio_3: заполненные поля объединяются в этом порядке. Если audios передан, он имеет приоритет, в том числе пустой массив []. Не передавайте оба формата в новых интеграциях.
Замените примерные ссылки на собственные доступные файлы.
cURL:
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "kling-4-0",
"input": {
"generation_type": "reference",
"prompt": "Керамический чайник из @Image1 стоит у окна; камера плавно приближается, слышен дождь.",
"images": [
"https://example.com/teapot.png"
],
"resolution": "720p",
"duration": 5,
"aspect_ratio": "16:9"
}
}'
JavaScript / TypeScript:
const response = await fetch("https://bratuha.ru/api/v1/operations", {
method: "POST",
headers: {
Authorization: "Bearer brth_ваш_ключ",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"tool": "kling-4-0",
"input": {
"generation_type": "reference",
"prompt": "Керамический чайник из @Image1 стоит у окна; камера плавно приближается, слышен дождь.",
"images": [
"https://example.com/teapot.png"
],
"resolution": "720p",
"duration": 5,
"aspect_ratio": "16:9"
}
}),
});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data));
console.log(data.id);
Python:
import json
import uuid
import requests
body = json.loads(r'''{
"tool": "kling-4-0",
"input": {
"generation_type": "reference",
"prompt": "Керамический чайник из @Image1 стоит у окна; камера плавно приближается, слышен дождь.",
"images": [
"https://example.com/teapot.png"
],
"resolution": "720p",
"duration": 5,
"aspect_ratio": "16:9"
}
}''')
response = requests.post(
"https://bratuha.ru/api/v1/operations",
headers={"Authorization": "Bearer brth_ваш_ключ",
"Idempotency-Key": str(uuid.uuid4())},
json=body,
timeout=60,
)
response.raise_for_status()
print(response.json()["id"])
cURL:
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "kling-4-0",
"input": {
"generation_type": "image",
"image": "https://example.com/first.png",
"image_prompt": "Лёгкий ветер шевелит листья, камера медленно поднимается.",
"use_last_image": true,
"last_image": "https://example.com/last.png",
"resolution": "720p",
"duration": 5,
"aspect_ratio": "auto"
}
}'
JavaScript / TypeScript:
const response = await fetch("https://bratuha.ru/api/v1/operations", {
method: "POST",
headers: {
Authorization: "Bearer brth_ваш_ключ",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"tool": "kling-4-0",
"input": {
"generation_type": "image",
"image": "https://example.com/first.png",
"image_prompt": "Лёгкий ветер шевелит листья, камера медленно поднимается.",
"use_last_image": true,
"last_image": "https://example.com/last.png",
"resolution": "720p",
"duration": 5,
"aspect_ratio": "auto"
}
}),
});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data));
console.log(data.id);
Python:
import json
import uuid
import requests
body = json.loads(r'''{
"tool": "kling-4-0",
"input": {
"generation_type": "image",
"image": "https://example.com/first.png",
"image_prompt": "Лёгкий ветер шевелит листья, камера медленно поднимается.",
"use_last_image": true,
"last_image": "https://example.com/last.png",
"resolution": "720p",
"duration": 5,
"aspect_ratio": "auto"
}
}''')
response = requests.post(
"https://bratuha.ru/api/v1/operations",
headers={"Authorization": "Bearer brth_ваш_ключ",
"Idempotency-Key": str(uuid.uuid4())},
json=body,
timeout=60,
)
response.raise_for_status()
print(response.json()["id"])
cURL:
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "kling-4-0",
"input": {
"generation_type": "text",
"prompt": "Бумажный кораблик плывёт по луже после дождя; низкая камера следует за ним, слышны капли.",
"resolution": "720p",
"duration": 5,
"text_aspect_ratio": "16:9"
}
}'
JavaScript / TypeScript:
const response = await fetch("https://bratuha.ru/api/v1/operations", {
method: "POST",
headers: {
Authorization: "Bearer brth_ваш_ключ",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"tool": "kling-4-0",
"input": {
"generation_type": "text",
"prompt": "Бумажный кораблик плывёт по луже после дождя; низкая камера следует за ним, слышны капли.",
"resolution": "720p",
"duration": 5,
"text_aspect_ratio": "16:9"
}
}),
});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data));
console.log(data.id);
Python:
import json
import uuid
import requests
body = json.loads(r'''{
"tool": "kling-4-0",
"input": {
"generation_type": "text",
"prompt": "Бумажный кораблик плывёт по луже после дождя; низкая камера следует за ним, слышны капли.",
"resolution": "720p",
"duration": 5,
"text_aspect_ratio": "16:9"
}
}''')
response = requests.post(
"https://bratuha.ru/api/v1/operations",
headers={"Authorization": "Bearer brth_ваш_ключ",
"Idempotency-Key": str(uuid.uuid4())},
json=body,
timeout=60,
)
response.raise_for_status()
print(response.json()["id"])
cURL:
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "kling-4-0",
"input": {
"generation_type": "edit",
"edit_video": "https://example.com/clip.mp4",
"prompt": "В @Video1 замени солнечный день на снежный вечер, сохрани движение камеры и предметов.",
"edit_duration_mode": "custom",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "auto",
"edit_generate_sound": false
}
}'
JavaScript / TypeScript:
const response = await fetch("https://bratuha.ru/api/v1/operations", {
method: "POST",
headers: {
Authorization: "Bearer brth_ваш_ключ",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"tool": "kling-4-0",
"input": {
"generation_type": "edit",
"edit_video": "https://example.com/clip.mp4",
"prompt": "В @Video1 замени солнечный день на снежный вечер, сохрани движение камеры и предметов.",
"edit_duration_mode": "custom",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "auto",
"edit_generate_sound": false
}
}),
});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data));
console.log(data.id);
Python:
import json
import uuid
import requests
body = json.loads(r'''{
"tool": "kling-4-0",
"input": {
"generation_type": "edit",
"edit_video": "https://example.com/clip.mp4",
"prompt": "В @Video1 замени солнечный день на снежный вечер, сохрани движение камеры и предметов.",
"edit_duration_mode": "custom",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "auto",
"edit_generate_sound": false
}
}''')
response = requests.post(
"https://bratuha.ru/api/v1/operations",
headers={"Authorization": "Bearer brth_ваш_ключ",
"Idempotency-Key": str(uuid.uuid4())},
json=body,
timeout=60,
)
response.raise_for_status()
print(response.json()["id"])
cURL:
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "kling-4-0",
"input": {
"generation_type": "extend",
"extend_video": "https://example.com/clip.mp4",
"prompt": "Продолжи движение камеры: кораблик проплывает под опавшим листом, звук воды сохраняет настроение.",
"duration": 5,
"resolution": "720p"
}
}'
JavaScript / TypeScript:
const response = await fetch("https://bratuha.ru/api/v1/operations", {
method: "POST",
headers: {
Authorization: "Bearer brth_ваш_ключ",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"tool": "kling-4-0",
"input": {
"generation_type": "extend",
"extend_video": "https://example.com/clip.mp4",
"prompt": "Продолжи движение камеры: кораблик проплывает под опавшим листом, звук воды сохраняет настроение.",
"duration": 5,
"resolution": "720p"
}
}),
});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data));
console.log(data.id);
Python:
import json
import uuid
import requests
body = json.loads(r'''{
"tool": "kling-4-0",
"input": {
"generation_type": "extend",
"extend_video": "https://example.com/clip.mp4",
"prompt": "Продолжи движение камеры: кораблик проплывает под опавшим листом, звук воды сохраняет настроение.",
"duration": 5,
"resolution": "720p"
}
}''')
response = requests.post(
"https://bratuha.ru/api/v1/operations",
headers={"Authorization": "Bearer brth_ваш_ключ",
"Idempotency-Key": str(uuid.uuid4())},
json=body,
timeout=60,
)
response.raise_for_status()
print(response.json()["id"])
Для редактирования с длиной исходного видео передайте edit_duration_mode: "auto" и опустите duration. Для генерации только по первому кадру опустите last_image и keyframes, оставьте use_last_image: false.
После создания ролика на 5 секунд в 720p (кроме редактирования):
{"id":"123e4567-e89b-42d3-a456-426614174000","status":"queued","tool":"kling-4-0","cost":120,"balance_after":880,"created_at":"2026-10-22T06:00:00Z"}
После завершения:
{"id":"123e4567-e89b-42d3-a456-426614174000","status":"completed","tool":"kling-4-0","cost":120,"created_at":"2026-10-22T06:00:00Z","completed_at":"2026-10-22T06:05:00Z","result":{"type":"video","urls":["https://storage.bratuha.ru/results/example.mp4"]},"error_message":null}
Значения идентификаторов, баланса, времени и адреса результата в этих ответах приведены для примера. Время готовности зависит от задания. При failed читайте error_message.
Запрашивайте GET /api/v1/operations/{id} по сохранённому идентификатору, например каждые 5-10 секунд:
curl -H "Authorization: Bearer brth_ваш_ключ" \
https://bratuha.ru/api/v1/operations/123e4567-e89b-42d3-a456-426614174000
При queued и processing продолжайте ожидание. При completed прочитайте результат; при failed или cancelled остановите опрос. Новый POST создаёт новую платную операцию, он не проверяет статус старой.
Готовое видео находится в result: type равен video, а urls содержит ссылки для скачивания. В режиме продления результат объединяет исходный ролик и новый фрагмент. Сохраняйте нужные файлы у себя после завершения операции.
Цена равна ставке за секунду, умноженной на длительность результата. Для продления учитывается только добавляемый фрагмент.
| Тип генерации | 720p | 1080p |
|---|---|---|
| По референсам, из изображения, из текста, продление | 24 ₽/сек. | 36 ₽/сек. |
| Редактирование | 28 ₽/сек. | 42 ₽/сек. |
Например, 5 секунд в 720p стоят 120 ₽, а редактирование на 5 секунд в 720p - 140 ₽. Минимальная выбранная длительность - 3 секунды. В автоматическом редактировании длина исходника ограничивается 30 секундами ; для оплаты используется замер сервера в целых секундах. Вариант сохранения звука ставку не меняет.
image первый кадр, конечный кадр и промежуточные кадры вместе не должны превышать 10 файлов.@Image1, @Video1, @Audio1. Не ссылайтесь на отсутствующий файл. Файлы разных типов нумеруются отдельно.image используйте image_prompt, в остальных - prompt.reference_keep_sound имеет смысл только при загруженном видео-референсе; в редактировании звук исходника сохраняется, пока edit_generate_sound выключен.edit_video | string | В edit | URL исходного MP4 от 3 секунд. Если ролик длиннее 30 секунд, используется начало до 30 секунд. |
extend_video | string | В extend | URL исходного MP4, к которому нужно добавить продолжение. |
resolution | string | Да | 720p или 1080p; если не передано, 720p. |
edit_duration_mode | string | Для edit | auto - как у исходника, максимум 30 секунд; custom - по полю duration. Если не передано, auto. |
duration | integer | Кроме edit с auto | Целое число от 3 до 30, исходное значение 5. В extend это длина добавляемого фрагмента. В edit учитывается только при edit_duration_mode="custom". |
aspect_ratio | string | Для reference, image, edit | auto, 16:9, 9:16, 1:1, 21:9. Если не передано, auto: пропорции по исходным материалам. |
text_aspect_ratio | string | Для text | 16:9, 9:16, 1:1, 21:9; если не передано, 16:9. |
reference_keep_sound | boolean | Нет | Сохранить звук видео-референсов. Только reference с непустым videos, исходное значение false. |
edit_generate_sound | boolean | Нет | Только edit: создать новый звук вместо исходного. По умолчанию false, исходный звук сохраняется. |