Создаёт короткие видео по текстовому описанию, из одного изображения или по набору референсов с сохранением персонажей и стиля. Цена зависит от разрешения: 720p - 18 ₽/сек., 1080p - 22 ₽/сек.
Общая документация Public API · API-ключ можно создать в настройках аккаунта
HappyHorse 1.1 снимает короткие ролики от 3 до 15 секунд сразу со звуком: фоновыми шумами, эффектами, музыкой. Сцену можно описать словами, оживить готовую картинку или дать модели до 9 референсов, чтобы в ролике сохранились нужные персонажи, предметы и стиль. Подходит для рекламных роликов, историй в соцсетях, раскадровок и анимации иллюстраций.
Основные сценарии:
happyhorse_generation_type: "text", ролик только по заданию.happyhorse_generation_type: "image", картинка становится первым кадром.happyhorse_generation_type: "reference", модель берёт внешность героев и предметов с присланных картинок.Каждый вызов создаёт асинхронную операцию. После запуска сохраните id и проверяйте статус отдельным запросом.
POST /api/v1/operationsAuthorization: Bearer brth_...id операции и стартовый статус queued.Сценарий задаёт параметр happyhorse_generation_type:
text - видео по заданию, пропорции задаёт aspect_ratio;image - видео из одной картинки (нужен image_urls), пропорции берутся из картинки;reference - видео по референсам (нужен reference_image, до 9 картинок), пропорции задаёт aspect_ratio.Во всех сценариях общие prompt, resolution и duration.
{
"tool": "happyhorse-1-1",
"input": {
"...": "..."
}
}
tool - slug нейросети, всегда "happyhorse-1-1".input - параметры запуска. Все поля передаются прямо внутри этого объекта, без дополнительной вложенности.| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
happyhorse_generation_type | enum | Да | Сценарий: text - видео из текста, image - видео из изображения, reference - видео по референсам. Если не передать, используется text. |
prompt | string | Да | Описание ролика: сцена, действие, движение камеры, стиль, звук. От 3 до 5000 символов. В режиме reference можно ссылаться на картинки по порядку: «первый референс», «второе изображение». |
image_urls | string[] (url) | Да, для image | Массив из одной ссылки на картинку для первого кадра. Только в режиме image. Форматы jpg, jpeg, png, webp, до 20 МБ, каждая сторона от 300 px, пропорции от 1:2.5 до 2.5:1. Передавайте именно массив, даже для одной картинки. |
reference_image | string[] (url) | Да, для reference | Массив ссылок на референсы, от 1 до 9 картинок. Только в режиме reference. Форматы jpg, jpeg, png, webp, каждый файл до 20 МБ, короткая сторона от 400 px, лучше чёткие картинки от 720p. |
resolution | enum | Да | Качество: 720p (быстрее и дешевле) или 1080p (детальнее). Если не указать - 720p. |
aspect_ratio | enum | Нет | Пропорции ролика: 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9. Если не указать - 16:9. Только в режимах text и reference; в режиме image пропорции повторяют картинку. |
duration | number | Да | Длительность ролика в секундах, целое число от 3 до 15. Если не указать - 5. Цена считается за каждую секунду. |
Ссылки передавайте как внешние http/https URL с расширением jpg, jpeg, png или webp. Файл должен открываться без авторизации.
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "happyhorse-1-1",
"input": {
"happyhorse_generation_type": "text",
"prompt": "Утро в маленькой пекарне: пекарь достаёт из печи горячий хлеб, пар поднимается в лучах солнца, камера медленно отъезжает. Слышно треск корочки и тихую музыку по радио",
"resolution": "720p",
"aspect_ratio": "9:16",
"duration": 5
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'happyhorse-1-1',
input: {
happyhorse_generation_type: 'text',
prompt:
'Утро в маленькой пекарне: пекарь достаёт из печи горячий хлеб, пар поднимается в лучах солнца, камера медленно отъезжает. Слышно треск корочки и тихую музыку по радио',
resolution: '720p',
aspect_ratio: '9:16',
duration: 5,
},
}),
})
const data = await response.json()
console.log(data.id, data.status)
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'happyhorse-1-1',
'input': {
'happyhorse_generation_type': 'text',
'prompt': 'Утро в маленькой пекарне: пекарь достаёт из печи горячий хлеб, пар поднимается в лучах солнца, камера медленно отъезжает. Слышно треск корочки и тихую музыку по радио',
'resolution': '720p',
'aspect_ratio': '9:16',
'duration': 5,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "happyhorse-1-1",
"input": {
"happyhorse_generation_type": "image",
"prompt": "Девушка в красном пальто улыбается и поправляет шарф, падает снег, камера медленно приближается",
"image_urls": [
"https://cdn.example.com/source-image-1.png"
],
"resolution": "720p",
"duration": 3
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'happyhorse-1-1',
input: {
happyhorse_generation_type: 'image',
prompt:
'Девушка в красном пальто улыбается и поправляет шарф, падает снег, камера медленно приближается',
image_urls: ['https://cdn.example.com/source-image-1.png'],
resolution: '720p',
duration: 3,
},
}),
})
const data = await response.json()
console.log(data.id, data.status)
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'happyhorse-1-1',
'input': {
'happyhorse_generation_type': 'image',
'prompt': 'Девушка в красном пальто улыбается и поправляет шарф, падает снег, камера медленно приближается',
'image_urls': ['https://cdn.example.com/source-image-1.png'],
'resolution': '720p',
'duration': 3,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
curl -X POST https://bratuha.ru/api/v1/operations \
-H "Authorization: Bearer brth_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"tool": "happyhorse-1-1",
"input": {
"happyhorse_generation_type": "reference",
"prompt": "Девушка с первого референса садится на велосипед со второго и уезжает по осенней улице, камера едет следом",
"reference_image": [
"https://cdn.example.com/reference-person-1.jpg",
"https://cdn.example.com/reference-bike-2.jpg"
],
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 8
}
}'
const response = await fetch('https://bratuha.ru/api/v1/operations', {
method: 'POST',
headers: {
Authorization: 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
tool: 'happyhorse-1-1',
input: {
happyhorse_generation_type: 'reference',
prompt:
'Девушка с первого референса садится на велосипед со второго и уезжает по осенней улице, камера едет следом',
reference_image: [
'https://cdn.example.com/reference-person-1.jpg',
'https://cdn.example.com/reference-bike-2.jpg',
],
resolution: '1080p',
aspect_ratio: '16:9',
duration: 8,
},
}),
})
const data = await response.json()
console.log(data.id, data.status)
import requests
response = requests.post(
'https://bratuha.ru/api/v1/operations',
headers={
'Authorization': 'Bearer brth_ваш_ключ',
'Content-Type': 'application/json',
},
json={
'tool': 'happyhorse-1-1',
'input': {
'happyhorse_generation_type': 'reference',
'prompt': 'Девушка с первого референса садится на велосипед со второго и уезжает по осенней улице, камера едет следом',
'reference_image': [
'https://cdn.example.com/reference-person-1.jpg',
'https://cdn.example.com/reference-bike-2.jpg',
],
'resolution': '1080p',
'aspect_ratio': '16:9',
'duration': 8,
},
},
timeout=30,
)
print(response.status_code)
print(response.json())
{
"id": "op_uuid-123",
"status": "queued",
"tool": "happyhorse-1-1",
"cost": 54,
"balance_after": 946,
"created_at": "2026-09-30T21:32:07.06713+00:00"
}
{
"id": "op_uuid-123",
"status": "completed",
"tool": "happyhorse-1-1",
"cost": 54,
"created_at": "2026-09-30T21:32:07.06713+00:00",
"completed_at": "2026-09-30T21:33:54.721025+00:00",
"result": {
"type": "video",
"urls": [
"https://storage.bratuha.ru/results/happyhorse-1-1/video-1.mp4"
]
},
"error_message": null
}
{
"id": "op_uuid-123",
"status": "failed",
"tool": "happyhorse-1-1",
"cost": 330,
"created_at": "2026-09-28T17:00:07.301+00:00",
"completed_at": "2026-09-28T17:00:34.780+00:00",
"result": null,
"error_message": "Ваш запрос не прошел модерацию."
}
Сохраните id из ответа на создание и проверяйте операцию по нему:
GET /api/v1/operations/{id}
curl -H "Authorization: Bearer brth_ваш_ключ" \
https://bratuha.ru/api/v1/operations/op_uuid-123
async function waitForResult(id: string) {
while (true) {
const response = await fetch(`https://bratuha.ru/api/v1/operations/${id}`, {
headers: { Authorization: 'Bearer brth_ваш_ключ' },
})
const operation = await response.json()
if (operation.status === 'completed' || operation.status === 'failed') {
return operation
}
await new Promise((resolve) => setTimeout(resolve, 10000))
}
}
Обычно ролик готов за 1,5-2 минуты: трёхсекундное видео в 720p в пробном запуске пришло через 1 минуту 48 секунд, длинные ролики на 10-15 секунд иногда занимают до 4-5 минут. Одну операцию можно опрашивать не чаще раза в секунду, разумный интервал - 10 секунд.
После завершения в result приходит одно видео:
{
"type": "video",
"urls": [
"https://storage.bratuha.ru/results/happyhorse-1-1/video-1.mp4"
]
}
type - всегда "video".urls - массив с одной ссылкой на MP4.duration: 3 файл длится около 3,16 секунды.prompt.image пропорции повторяют картинку: горизонтальный кадр в 720p дал ролик 1284x718. В режимах text и reference пропорции задаёт aspect_ratio.Цена считается за секунду ролика и зависит только от разрешения: ставка умножается на duration. Сценарий, пропорции и число референсов на цену не влияют.
| Разрешение | За секунду | 3 сек. | 5 сек. | 10 сек. | 15 сек. |
|---|---|---|---|---|---|
720p | 18 ₽ | 54 ₽ | 90 ₽ | 180 ₽ | 270 ₽ |
1080p | 22 ₽ | 66 ₽ | 110 ₽ | 220 ₽ | 330 ₽ |
Самый дешёвый запуск - 3 секунды в 720p за 54 ₽. Запрос со значениями по умолчанию (720p, 5 секунд) стоит 90 ₽. Сумма списывается при создании операции и видна в поле cost. Если операция завершилась ошибкой (failed), деньги возвращаются на баланс.
POST /api/v1/operations не идемпотентен: каждый повторный запрос создаёт новую платную операцию. Если ответ на создание потерялся, не отправляйте запрос вслепую ещё раз.queued, результат забирайте через GET /api/v1/operations/{id}.http/https URL на jpg, jpeg, png или webp. Адреса localhost и внутренних сетей не принимаются.image_urls и reference_image - всегда массивы. В image_urls ровно одна ссылка, в reference_image - до 9.image каждая сторона должна быть не меньше 300 px, иначе операция завершится ошибкой «Изображение слишком маленькое». Для референсов короткая сторона - от 400 px.duration - целое число от 3 до 15. Значение вроде 5.5 вернёт 400 validation_error.720p, а чистовик - в 1080p.