HiAPI
Блог

Руководство

Вызов API преобразования текста в видео HappyHorse 1.1 через HiAPI: рабочее руководство с curl + Python

Jun 27, 2026
Вызов API преобразования текста в видео HappyHorse 1.1 через HiAPI: рабочее руководство с curl + Python
Модель
happyhorse-1.1

HappyHorse 1.1 — это модель преобразования текста в видео от Alibaba: поддерживает видеофрагменты 720p / 1080p длительностью 3–15 секунд, генерирует нативное аудио за один вызов (отдельный этап добавления музыки не требуется). HiAPI предоставляет эту модель через ту же унифицированную асинхронную конечную точку, что и все остальные генеративные модели, поэтому если вы уже вызывали модели изображений на /v1/tasks, единственное, что меняется, — это id модели и несколько полей input.

На этой странице содержится минимум, необходимый для рабочей интеграции: точная схема, готовый к копированию curl, клиент опроса на Python и шаблон callback для продакшена. Кроме того, здесь особо отмечены две неочевидные вещи, которые модель не принимает (флаг audio и seed), чтобы вы не потратили запрос впустую из-за ошибки 400.

Предварительные требования. Получите ключ в консоли HiAPI и экспортируйте его как HIAPI_API_KEY. Каждый запрос аутентифицируется через Authorization: Bearer sk-…; для повторения см. Authentication.

Конечная точка и структура запроса

Всё проходит через одну конечную точку:

POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json

Тело запроса содержит три ключа верхнего уровня:

  • model — happyhorse-1.1/text-to-video (буквальный id модели — косую черту нужно сохранять).
  • input — поля, специфичные для модели. Для HappyHorse 1.1 T2V:
    • prompt (строка, обязательно) — описывает видеофрагмент.
    • resolution (720p | 1080p, по умолчанию 1080p).
    • aspect_ratio (16:9 | 9:16 | 3:4 | 4:3 | 4:5 | 5:4 | 1:1 | 9:21 | 21:9, по умолчанию 16:9).
    • duration (целое число, 3–15, по умолчанию 5). Стоимость растёт с увеличением количества секунд.
  • callback (необязательно, объект) — HTTPS-эндпоинт callback.url + callback.when: "final". HiAPI отправит на этот адрес ровно один раз итоговый результат для каждой задачи.

Две вещи, которые кажутся доступными, но на самом деле недоступны:

  • ❌ Нет поля audio. Аудио генерируется нативно вместе с видео; флага нет. Отправка "audio": true вернёт additional properties 'audio' not allowed.
  • ❌ Нет поля seed. Также возвращается 400. Если вам нужна детерминированность пакета, сгенерируйте несколько версий и выберите — рычага настройки seed нет.

Минимальное допустимое тело запроса:

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A golden retriever running on a beach, slow motion, gentle waves, warm sunset tones",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  }
}

Минимальный рабочий пример: curl

Создание задачи — ответ возвращается сразу и содержит только taskId:

curl -sS -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1/text-to-video",
    "input": {
      "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
      "resolution": "1080p",
      "aspect_ratio": "16:9",
      "duration": 5
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KW3..."},"message":"success"}

Затем опрашивайте до достижения терминального состояния:

TASK_ID=tk-hiapi-01KW3...

curl -sS "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"
# while .data.status is "handling", sleep a few seconds and retry.
# On success:
# {
#   "code": 200,
#   "data": {
#     "status": "success",
#     "model": "happyhorse-1.1/text-to-video",
#     "output": [
#       {"type":"video","url":"https://temp.hiapi.ai/.../...-0.mp4","expireAt":1783130616}
#     ],
#     ...
#   }
# }

URL mp4-файла является временным (expireAt — это Unix-временная метка примерно через 7 дней). Скачайте и сохраните файл сразу после успешного завершения задачи — не используйте горячие ссылки. Если вы предпочитаете, чтобы HiAPI управлял долгосрочным хранением, см. документацию Output Storage о том, как перевести вывод из временного хранилища в постоянное.

Python: компактный клиент production-уровня

Настоящему клиенту нужны три вещи: create_task, возвращающий id, wait_task с опросом по дедлайну и шаг загрузки. В этом скелете есть все три, и он близок к отправной точке страницы Python SDK HiAPI — держите его компактным и расширяйте из него.

# pip install requests
import os, time, json, requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}


def create_task(prompt: str, *, resolution="1080p", aspect_ratio="16:9", duration=5) -> str:
    body = {
        "model": "happyhorse-1.1/text-to-video",
        "input": {
            "prompt": prompt,
            "resolution": resolution,
            "aspect_ratio": aspect_ratio,
            "duration": duration,
        },
    }
    r = requests.post(API_BASE, headers={**HEADERS, "Content-Type": "application/json"},
                      data=json.dumps(body), timeout=60)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 200:
        raise RuntimeError(f"create failed: {data}")
    return data["data"]["taskId"]


def wait_task(task_id: str, *, timeout_s: int = 600, poll: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task {task_id} failed: {task.get('error')}")
        time.sleep(poll)
    raise TimeoutError(f"task {task_id} did not finish within {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 << 14):
                f.write(chunk)


if __name__ == "__main__":
    task_id = create_task(
        "A neon street at night after rain, reflections on the ground, "
        "cyberpunk mood, slow pan",
        resolution="720p", aspect_ratio="9:16", duration=5,
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    download(url, "out.mp4")
    print("saved out.mp4")

Несколько замечаний для продакшена:

  • Поле статуса. Любое значение, кроме success или fail, считайте выполненным (платформа сейчас использует handling).
  • raise_for_status недостаточно. Для некоторых ошибок валидации HiAPI возвращает HTTP 200, но code не равен 200 — обязательно проверяйте также data["code"]. Для новой интеграции чаще всего встречается 401 permission_denied, что означает неверный или отсутствующий bearer token — повторно экспортируйте HIAPI_API_KEY и проверьте в консоли.

Продакшен: callback предпочтительнее опроса

Для любого сценария за пределами быстрого старта дайте HiAPI webhook, чтобы он вызывал вас по завершении задачи:

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  },
  "callback": {
    "url": "https://your-domain.com/hiapi/callback",
    "when": "final"
  }
}

Убедитесь, что ваш обработчик callback делает следующее:

  • Дедупликация по taskId. success и fail — оба терминальные состояния; ваш сервис должен считать два получения одного и того же taskId пустой операцией (идемпотентная запись с ключом taskId).
  • Быстрый ответ 2xx. Поместите тяжёлую работу (загрузку mp4, сохранение, уведомление пользователя) в очередь. Обработчик webhook должен подтверждать за несколько секунд.
  • Сохраняйте GET /v1/tasks/:id как резерв. Если webhook потерян (деплой, сетевые сбои), периодическая задача сверки, которая выбирает зависшие задачи по id и применяет тот же обработчик, — самая простая страховка.

Если выбирать один путь: опрос подходит для одноразовых скриптов и локальной отладки, а везде, где есть реальный трафик, следует использовать callback.

Выбор правильных параметров (resolution × aspect_ratio × duration)

Требование resolution aspect_ratio duration
Вертикальный короткий ролик для соцсетей, минимальная стоимость 720p 9:16 5
Квадратный превью / циклическая миниатюра 720p 1:1 3
Горизонтальный сюжетный / рекламный кадр 1080p 16:9 5–8
Широкоэкранный фрагмент для главного визуала 1080p 21:9 8–12

Стоимость растёт с разрешением и длительностью — точные цены за секунду см. в HiAPI定价. Если вы не уверены в правильном значении, не указывайте его: resolution по умолчанию 1080p, aspect_ratio по умолчанию 16:9, duration по умолчанию 5.

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

Есть ли у преобразования текста в видео HappyHorse 1.1 параметр seed? Нет. API отклоняет seed с ошибкой additional properties 'seed' not allowed. Если вам нужно несколько вариантов для выбора, отправьте несколько задач с одним и тем же prompt — разные запуски естественно дадут различия.

Как включить или отключить аудио? Никак — HappyHorse 1.1 генерирует звуковую дорожку нативно в том же вызове. В схеме нет флага audio; отправка его вернёт 400. Если вам нужен фрагмент без звука, удалите аудио на постобработке.

Какие допустимы значения длительности? Целое число от 3 до 15 (секунд). Любое значение вне этого диапазона вернёт duration: minimum: got 0, want 3 или duration: maximum: got 20, want 15. Дробные значения также отклоняются (тип поля — целое число).

Какие соотношения сторон поддерживаются? Девять: 16:9, 9:16, 3:4, 4:3, 4:5, 5:4, 1:1, 9:21, 21:9. По умолчанию 16:9.

Как долго output[].url остаётся действительным? Около недели — ответ содержит Unix-временную метку expireAt. Скачайте mp4 сразу и переразместите (S3, R2, ваш CDN) или переведите его в постоянное хранилище через Output Storage API.

А преобразование изображения в видео? У HappyHorse 1.1 есть вариант I2V на той же конечной точке — см. HappyHorse 1.1 I2V. Та же аутентификация, тот же асинхронный жизненный цикл, другая схема input.

Где находится полный справочник по асинхронному API? Оболочка запроса описана в Create Task, эндпоинт опроса — в Get Task Detail, каноническая схема входных данных — на странице модели HappyHorse 1.1 T2V. Если вы начинаете с нуля, Quickstart проведёт вас через первый вызов от начала до конца.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API