Руководство
Happyhorse API для видео из изображения: рабочие примеры curl и Python (hiapi)
Вы хотите превратить статичное изображение в связный короткий видеоролик прямо из своего кода. Модель happyhorse-1.1/image-to-video на hiapi делает именно это: передайте URL изображения и необязательный промпт движения, и через несколько секунд вы получите MP4 в разрешении 720p или 1080p. Это руководство — самый короткий рабочий путь: настоящие тела запросов, настоящие сообщения об ошибках, на curl и Python — чтобы вы могли запуститься сегодня, а не бороться с именами полей.
Что нужно подготовить перед началом
- Ключ API hiapi. Получите его в консоли hiapi — он выглядит как
sk-...и передаётся в заголовкеAuthorization: Bearer .... - Доступный URL изображения (публичный HTTPS). Локальные файлы не подходят; модель сама загружает этот URL.
- Намерение движения, выраженное текстом (необязательно, но рекомендуется). Чем чётче глаголы, тем лучше эффект движения.
Модель тарифицируется по секундам видео, цены указаны на странице тарифов hiapi; остальной каталог моделей — в hiapi models — загляните в оба места, прежде чем наращивать объёмы.
Минимальный рабочий запрос (curl)
Каждое видео на hiapi проходит через асинхронную конечную точку /v1/tasks: сначала вы отправляете POST-запрос на создание, получаете taskId, а затем либо опрашиваете GET /v1/tasks/{taskId}, либо принимаете обратный вызов по завершении.
Создание задачи:
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1/image-to-video",
"input": {
"image_urls": ["https://example.com/your-still.jpg"],
"prompt": "the cat slowly turns its head toward the camera and blinks",
"resolution": "1080p",
"duration": 5
}
}'
Успешный ответ выглядит так:
{
"code": 200,
"data": { "taskId": "tk-hiapi-01KW3D..." },
"message": "success"
}
Теперь опрашивайте результат (раз в 5 секунд достаточно — большинство клипов готовы в течение двух минут):
curl "https://api.hiapi.ai/v1/tasks/tk-hiapi-01KW3D..." \
-H "Authorization: Bearer sk-your-key"
Пока идёт работа, вы получите "status": "handling". По завершении вы получите:
{
"code": 200,
"data": {
"status": "success",
"model": "happyhorse-1.1/image-to-video",
"output": [
{
"type": "video",
"url": "https://temp.hiapi.ai/.../01KW....mp4",
"expireAt": 1783131245
}
],
"taskId": "tk-hiapi-01KW3D..."
}
}
Этот url — то, что нужно скачать, и скачать следует сразу, потому что expireAt — это Unix-временная метка, отмечающая, когда временное хранилище удалит файл.
Python: опрос до успеха
Это полный, рабочий скрипт — подставьте свой ключ и URL изображения.
import os
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_KEY"] # sk-...
def create_video(image_url: str, prompt: str, duration: int = 5,
resolution: str = "1080p") -> str:
"""Submit an image-to-video task. Returns the taskId."""
r = requests.post(
API,
headers={"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"},
json={
"model": "happyhorse-1.1/image-to-video",
"input": {
"image_urls": [image_url], # exactly one URL
"prompt": prompt, # optional
"resolution": resolution, # "720p" or "1080p"
"duration": duration, # int, 3..15
},
},
timeout=60,
)
body = r.json()
if body.get("code") != 200:
raise RuntimeError(f"create failed: {body}")
return body["data"]["taskId"]
def wait_for_video(task_id: str, timeout_s: int = 600,
poll_s: int = 5) -> str:
"""Block until the task succeeds, fails, or times out. Returns the MP4 URL."""
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(
f"{API}/{task_id}",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
task = r.json().get("data") or {}
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"task failed: {task.get('error')}")
time.sleep(poll_s)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
def download(url: str, path: str) -> None:
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 16):
f.write(chunk)
if __name__ == "__main__":
task_id = create_video(
image_url="https://example.com/your-still.jpg",
prompt="the dancer spins once and ends in a pose",
duration=5,
resolution="1080p",
)
print("submitted:", task_id)
mp4_url = wait_for_video(task_id)
download(mp4_url, "out.mp4")
print("saved out.mp4")
Всё вместе — около 50 строк, и это весь готовый к продакшену интерфейс: без SDK, без очередей в фоне, без протокола стриминга. Запустите через HIAPI_KEY=sk-... python video.py.
Продакшен: обратный вызов вместо опроса
Опрос нормально подходит для разовых задач и тестов. Для серверной нагрузки вы хотите, чтобы платформа сама вызывала вас, когда клип готов, — это избавляет от цикла, масштабируется без лишней работы, а поток запросов возвращается немедленно.
Добавьте объект callback на корневом уровне тела запроса (не внутри input):
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1/image-to-video",
"input": {
"image_urls": ["https://example.com/still.jpg"],
"prompt": "slow zoom out from the subject",
"resolution": "1080p",
"duration": 6
},
"callback": {
"url": "https://your-app.example.com/webhooks/hiapi",
"when": "final"
}
}'
Когда задача достигает терминального состояния, hiapi отправит POST на ваш URL тот же объект задачи, который вы могли бы получить опросом (status, output[].url, error и т. д.). when: "final" означает, что вы получите обратный вызов только об успехе или неудаче — без шума о прогрессе.
Несколько правил, которые сэкономят реальное время отладки:
- Сделайте webhook идемпотентным. Один и тот же
taskIdможет прийти дважды (сетевые повторы — это реальность). Перед обработкой проверьте эту задачу в базе данных. - Переразместите MP4 внутри обработчика. URL, который выдаёт hiapi, указывает на временное хранилище с полем
expireAt; при первом получении сразу перелейте файл в свой bucket, иначе потеряете его. - Подтверждайте быстро. Быстро верните
2xx, а тяжёлую работу выполняйте асинхронно. Медленные webhook рискуют повторами. - Используйте опрос как подстраховку. Оберните
taskIdв отложенную задачу и опросите через 10 минут на случай потери webhook. Если вы сталкиваетесь с этим постоянно, посмотрите причины, по которым обратный вызов задачи hiapi может не срабатывать, чтобы узнать типичные причины.
Сообщения об ошибках, которые вы встретите
Это точные строки, возвращаемые API; сопоставлять их в коде надёжнее, чем угадывать.
| Ситуация | HTTP | Форма тела ответа |
|---|---|---|
| Неверный или отозванный ключ | 401 | {"error":{"code":"permission_denied","message":"This API key cannot use the selected model...","type":"hiapi_error"}} |
| Отсутствует обязательное поле | 400 | {"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: image_urls: missing required field \"image_urls\""} |
resolution недопустим |
400 | ... resolution: value must be one of '720p', '1080p' |
| Длительность вне диапазона | 400 | ... duration: minimum: got 2, want 3 / duration: maximum: got 30, want 15 |
Неверная длина image_urls |
400 | ... image_urls: maxItems: got 2, want 1 (или minItems: got 0, want 1) |
Неизвестное поле на корневом уровне или внутри input |
400 | ... additional properties 'identity_preserving' not allowed |
| Сама задача завершилась неудачей после отправки | 200 (GET задачи) и data.status == "fail" вместе с data.error.{code,message} |
Ошибки аутентификации и валидации означают, что повторять не нужно; все остальные случаи (5xx платформы, сетевые таймауты при опросе, временный task fail с кодом, допускающим повтор) подходят для повторных попыток с небольшой задержкой.
Настройка вывода
Реально влияют четыре параметра — всё остальное (seed, aspect_ratio, fps, cfg_scale, negative_prompt) сейчас отклоняется как неизвестные поля. Оставайтесь в этом наборе:
image_urls— один HTTPS URL. Соотношение сторон и композиция вывода следуют за этим изображением.prompt— краткое описание движения ("she smiles and tilts her head"). Кинематографичные промпты, движимые глаголами, побеждают списки прилагательных.resolution—"720p"для прототипирования и миниатюр,"1080p"для сдачи.duration— целое число секунд от3до15. Длинные клипы стоят больше времени и денег; выбирайте минимальную длительность, которая рассказывает историю.
Для проектов, которым нужны начальный и конечный кадры, см. happyhorse-1.1 reference-to-video. Для чистого текст-в-видео без исходного изображения есть happyhorse-1.1 text-to-video — второе руководство. Просматривайте остальное в hiapi models catalogue или в разделе рецептов блога.
FAQ
Можно ли передать два изображения, чтобы задать первый и последний кадры?
На happyhorse-1.1/image-to-video — нет, image_urls принимает не более одного элемента (maxItems: 1). Если это нужно, используйте happyhorse-1.1/reference-to-video или создайте решение на основе happyhorse-1.1 reference-to-video.
Какое разрешение у MP4, который я фактически получу?
Вывод следует соотношению сторон входного изображения и заданному вами флагу resolution. "1080p" даёт более высокий из двух; "720p" быстрее и дешевле для тестов.
Почему мой ключ работает на других моделях, а здесь я получаю 401 permission_denied?
Некоторые модели ограничены по ключу. Проверьте страницу модели в консоли hiapi — если happyhorse-1.1/image-to-video нет в вашем списке разрешённых, сгенерируйте новый ключ или обратитесь в поддержку, указав request_id из ошибки.
Есть ли потоковый/SSE-ответ? Нет. Каждая видеомодель использует асинхронный шаблон задач из этой статьи. Выбирайте опрос или обратный вызов в зависимости от того, контролируете ли вы сервер.
Где увидеть фактическую стоимость каждого клипа?
На странице тарифов hiapi. Стоимость считается по секундам видео, поэтому переданный вами duration напрямую определяет затраты — держите клипы для разработки и тестов на duration: 3, чтобы экономить бюджет.
URL вывода перестаёт работать через день.
Это ожидаемое поведение — URL указывает на временное хранилище, а ответ содержит Unix-временную метку expireAt. Всегда скачивайте MP4 в момент успешного завершения задачи (или транслируйте его через свой CDN).
Похожие статьи
Все статьи →-
Руководство
Как вызвать hailuo-2.3-fast/image-to-video через HiAPI API: практика с curl и Python
Первый рабочий запрос к быстрому и недорогому уровню генерации видео по изображению — от ID модели до загрузки MP4
-
Руководство
Как вызывать hailuo-2.3/text-to-video через API HiAPI: curl, Python и рабочие примеры запросов
-
Руководство
Использование Kandinsky 6.0 Pro для преобразования текста в видео на HiAPI: руководство по curl и Python
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата