Руководство
Как вызывать hailuo-2.3/text-to-video через API HiAPI: curl, Python и рабочие примеры запросов
Что делает эндпоинт hailuo-2.3/text-to-video
Если у вас есть текстовый промпт и вы хотите на его основе сгенерировать короткий видеоклип, hailuo-2.3/text-to-video — это нужный вам эндпоинт. Он принимает промпт на естественном языке, описывающий сцену, субъект и желаемое движение, а затем возвращает сгенерированный видеоклип. Модель оптимизирована для коротких выходных фрагментов, поэтому она лучше всего работает, когда вы просите компактный, самодостаточный момент, а не длинное повествование.
На HiAPI вызов следует той же схеме, что и другие асинхронные эндпоинты генерации: вы отправляете запрос, сервис принимает задачу, а затем вы опрашиваете до готовности результата. Это значит, что эндпоинт отлично подходит для серверных пайплайнов — контентных инструментов, генераторов прототипов, пакетных задач или любых сценариев, где нужно получить несколько секунд видео по требованию без человека, сидящего за видеоредактором.
Запрос содержит промпт и несколько параметров управления генерацией; ответ содержит идентификатор задачи, а затем URL готового видео. Вам не нужно управлять GPU или весами модели — HiAPI берёт на себя вычисления и возвращает ссылку на результат. Если вы уже использовали другие API преобразования текста в видео, общая форма покажется знакомой, но стиль промптов hailuo-2.3 больше вознаграждает размышления о физике движения, а не только визуальное описание (подробнее ниже).
Предварительные требования и учётные данные API
Перед первым вызовом убедитесь, что у вас есть три вещи:
- API-ключ из вашей учётной записи HiAPI. Обращайтесь с ним как с паролем: не добавляйте в систему контроля версий, загружайте из переменной окружения и ротируйте при утечке.
- HTTP-клиент. Для примеров в shell достаточно
curl. Для примеров на Python нужны Python 3.8+ и библиотекаrequests(pip install requests). - Базовый URL API HiAPI. Все запросы отправляются на хост API HiAPI, путь эндпоинта —
hailuo-2.3/text-to-video. Вы аутентифицируетесь, отправляя bearer token в заголовкеAuthorization.
Задайте ключ в переменной окружения, чтобы он не попадал в ваш код:
export HIAPI_API_KEY="your_api_key_here"
В Python вы читаете его через os.environ["HIAPI_API_KEY"]. В curl вы ссылаетесь на ту же переменную как $HIAPI_API_KEY.
Ещё одно решение нужно принять заранее: где будут храниться сгенерированные видео. API возвращает URL результата, и этот URL следует своевременно получить и сохранить в ваш собственный бакет или файловую систему — не стройте пайплайн, который предполагает, что этот URL является постоянным активом.
Рабочий запрос с curl
Ниже приведён полный вызов curl для отправки задачи преобразования текста в видео. Замените промпт своим описанием сцены. Тело запроса — JSON, ключевые поля — промпт и параметры генерации, управляющие длительностью и формой вывода.
curl -X POST "https://api.hiapi.ai/v1/hailuo-2.3/text-to-video" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "стеклянный шарик скатывается по деревянному склону, ускоряется и падает на каменную поверхность, отскакивает дважды и останавливается",
"duration": 6
}'
Успешная отправка возвращает JSON-объект с идентификатором задачи. Примерно такой:
{
"id": "job_abc123",
"status": "queued"
}
Ключевая часть — id. Генерация не завершается синхронно — эндпоинт ставит задачу в очередь и сразу возвращает ответ. Сохраните id; вы будете использовать его для опроса статуса и в итоге получения URL видео.
Если вы получаете ошибку аутентификации, проверьте, экспортирован ли ключ в той же сессии shell. Если вы получаете ошибку валидации, проверьте правильность формата тела JSON и наличие промпта. Ответ 429 означает, что вы отправляете запросы слишком быстро, и следует выполнить откат — подробнее в разделе о производственной среде.
Тот же вызов на Python
Версия на Python делает то же самое, но обёрнута в переиспользуемую функцию, которую удобно встроить в пайплайн. Она отправляет задачу и возвращает идентификатор задачи.
import os
import requests
HIAPI_BASE = "https://api.hiapi.ai/v1"
def submit_text_to_video(prompt: str, duration: int = 6) -> str:
"""Отправляет задачу hailuo-2.3/text-to-video и возвращает её id."""
api_key = os.environ["HIAPI_API_KEY"]
response = requests.post(
f"{HIAPI_BASE}/hailuo-2.3/text-to-video",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json={"prompt": prompt, "duration": duration},
timeout=30,
)
response.raise_for_status()
data = response.json()
return data["id"]
if __name__ == "__main__":
job_id = submit_text_to_video(
"стеклянный шарик скатывается по деревянному склону, ускоряется и падает на каменную поверхность, отскакивает дважды и останавливается"
)
print("submitted job:", job_id)
Несколько деталей стоит сохранить:
raise_for_status()превращает ответы, отличные от 2xx, в исключение — именно такое поведение нужно в пайплайне. Лучше громко упасть на этапе отправки, чем опрашивать задачу, которая так и не была создана.- Таймаут запроса отправки намеренно короткий. Отправка должна быть быстрой; долгое ожидание происходит на этапе опроса, а не здесь.
- Параметр
durationвынесен отдельно, чтобы вызывающий код мог запрашивать более короткий или длинный клип без дублирования логики построения запроса.
Как только функция вернулась, у вас есть всё необходимое для продолжения опроса статуса.
Написание промптов с физикой движения для 6-10-секундных клипов
Короткие клипы не прощают ошибок. За шесть-десять секунд вы не сможете создать персонажа, построить мир и завершить сюжет — поэтому самые эффективные промпты описывают одно непрерывное действие с ясными физическими последствиями. Представляйте промпт как описание одного момента съёмки, а не как историю.
Начинайте с субъекта и действия
Начните с того, что движется и что оно делает. «стеклянный шарик скатывается по деревянному склону» сразу даёт модели субъект, материал и направление движения. Расплывчатое начало вроде «красивая сцена» ничего не даёт, что можно анимировать.
Описывайте силы, а не только внешний вид
Промпт физики движения означает называние действующих сил: гравитации, трения, импульса, веса, упругости. Слова вроде катиться, ускоряться, отскакивать, останавливаться, раскачиваться, опрокидываться, разбрызгиваться, разрываться подразумевают физическую модель. Для отскакивающего объекта укажите, сколько раз он отскочит и где в итоге остановится. Для падающего объекта укажите, на что он падает и разбивается ли он, вминается или отскакивает.
Делайте камеру явной и простой
Фиксированная камера или одно медленное движение камеры обычно достаточно для короткого клипа. Если и камера, и субъект делают сложные вещи, клип становится хаотичным, и движение выглядит как шум. Указывайте тип камеры только тогда, когда он важен для действия — крупный план, широкий план, следящая камера.
Стройте дугу события
Полезный шаблон для 6–10-секундного клипа: завязка → действие → последствие. Шарик на вершине склона; он катится вниз и ускоряется; он падает, отскакивает дважды и останавливается. Эта дуга даёт модели начало, середину и конец, все в пределах длины клипа. Избегайте требования нескольких несвязанных действий; одно хорошо описанное физическое событие читается гораздо лучше, чем три недоделанных.
Наконец, делайте промпт конкретным. Материалы, освещение и текстуры поверхностей помогают модели обосновать движение — шарик на дереве ведёт себя иначе, чем шарик на льду, и указание этого направляет результат.
Обработка асинхронных задач через опрос
Генерация занимает время, поэтому эндпоинт асинхронный. После отправки задачи вы получаете id; затем вы опрашиваете эндпоинт статуса, пока задача не достигнет конечного состояния. Надёжный цикл опроса обрабатывает три вещи: интервал, таймаут и раскрытие ошибок.
import time
import requests
HIAPI_BASE = "https://api.hiapi.ai/v1"
def wait_for_video(job_id: str, api_key: str, interval: float = 3.0, max_wait: float = 600.0) -> str:
"""Опрашивает до завершения задачи и возвращает URL выходного видео."""
deadline = time.time() + max_wait
url = f"{HIAPI_BASE}/hailuo-2.3/text-to-video/{job_id}"
while time.time() < deadline:
response = requests.get(
url,
headers={"Authorization": f"Bearer {api_key}"},
timeout=30,
)
response.raise_for_status()
data = response.json()
status = data.get("status")
if status == "completed":
return data["output"]["video_url"]
if status in ("failed", "cancelled"):
raise RuntimeError(f"задача {job_id} завершилась со статусом {status}: {data.get('error')}")
time.sleep(interval)
raise TimeoutError(f"задача {job_id} не завершилась за {max_wait} секунд")
Замечания по этому циклу:
- Опрашивайте с интервалом, а не в плотном цикле. Нескольких секунд между проверками достаточно и позволяет не нагружать API.
- Всегда ограничивайте общее время ожидания. Зависшая задача не должна бесконечно подвешивать рабочий процесс. Значение
max_waitздесь довольно консервативно; корректируйте его в зависимости от длины клипа и состояния очереди. - Считайте
failedреальной веткой. Раскрывайте полезную нагрузку ошибки, а не слепо повторяйте попытку — проблемы с промптом или параметрами сами не исправятся. - Возвращайте URL видео, а не сырой ответ. Вызывающий код этой функции не должен нуждаться в знании структуры ответа.
Для более тяжёлых нагрузок разделите этапы отправки и опроса на разные рабочие процессы: один процесс ставит задачи в очередь и сохраняет ID задач, другой отвечает за опрос и загрузку. Это развязывает задержку запроса и время генерации.
Загрузка и хранение результатов
Как только опрос вернул URL видео, получите байты и запишите их в постоянное место. Делайте это своевременно: возвращённый URL — это ссылка на доставку, а не постоянное хранилище активов. Загружайте потоково, а не загружайте весь файл в память; сначала пишите во временный путь, а затем переименовывайте, чтобы частичная загрузка никогда не выглядела как завершённый файл.
import os
import tempfile
import requests
def download_video(video_url: str, dest_path: str) -> None:
"""Атомарно потоково записывает готовое видео в dest_path."""
os.makedirs(os.path.dirname(dest_path) or ".", exist_ok=True)
with requests.get(video_url, stream=True, timeout=120) as response:
response.raise_for_status()
fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(dest_path) or ".")
try:
with os.fdopen(fd, "wb") as f:
for chunk in response.iter_content(chunk_size=1 << 16):
f.write(chunk)
os.replace(tmp_path, dest_path)
except Exception:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
raise
api_key = os.environ["HIAPI_API_KEY"]
video_url = wait_for_video("job_abc123", api_key)
download_video(video_url, f"out/{'job_abc123'}.mp4")
Несколько практических решений:
- Называйте файлы по ID задачи. Это даёт вам стабильный, устойчивый к коллизиям ключ и делает привязку файла обратно к породившему его запросу тривиальной.
- Храните метаданные вместе с видео. Сохраняйте исходный промпт, длительность и временную метку в сопутствующем JSON или базе данных. Через полгода вам захочется узнать, чем был порождён тот или иной клип.
- В производственной среде загружайте в объектное хранилище. Запись на локальный диск подходит для прототипа; реальный пайплайн должен отправлять файлы в ваш бакет и записывать ключи объектов, чтобы видео выживало после перезапуска рабочих процессов.
Производственные советы и частые режимы отказа
Большинство первых интеграций спотыкается на одних и тех же местах. Вот на что обратить внимание.
Повторяйте правильные вещи
Повторяйте при временных сбоях — сетевых ошибках, таймаутах, ответах 429 и 5xx — с экспоненциальным откатом и джиттером. Не повторяйте при ошибках валидации 4xx; некорректный промпт или неверный параметр будут каждый раз терпеть неудачу одинаково. Если сама задача генерации не удалась, раскройте ошибку и осознанно решите, стоит ли отправлять повторно.
Разделяйте отправку и опрос
В производственной среде отправка и опрос должны быть разными шагами, обычно в разных процессах. Сразу после успешной отправки сохраните ID задачи в очередь или базу данных. Если рабочий процесс упадёт, вы сможете возобновить опрос, а не потерять задачу.
Задавайте таймауты везде
Запрос отправки, опрос статуса и загрузка файла должны иметь каждый свой таймаут. Отсутствие таймаута на этапе загрузки — классическая причина зависания рабочих процессов.
Держите промпты в пределах сильных сторон модели
В диапазоне шести-десяти секунд запрашивайте одно физически правдоподобное действие. Когда промпт требует слишком многого, вы получаете хаотичный клип с мутным движением. Если качество результата нестабильно, сначала сократите промпт и упростите действие, а уже потом думайте об изменении параметров.
Правильно обращайтесь с учётными данными
Загружайте API-ключи из переменных окружения или менеджера секретов, никогда из закоммиченных файлов. Используйте разные ключи для каждого окружения, чтобы утёкший ключ разработки не мог добраться до производственной среды.
Остерегайтесь допущений об истечении срока действия URL
Самая частая ошибка в производственной среде — считать возвращённый URL видео постоянной ссылкой и через месяцы напрямую отображать её в пользовательском интерфейсе. Загружайте и переразмещайте файл как часть задачи и храните собственный URL.
С этими привычками интеграция становится маленькой: отправить, опросить, загрузить, сохранить.
Похожие статьи
Все статьи →-
Руководство
Как вызвать hailuo-2.3-fast/image-to-video через HiAPI API: практика с curl и Python
Первый рабочий запрос к быстрому и недорогому уровню генерации видео по изображению — от ID модели до загрузки MP4
-
Руководство
Использование Kandinsky 6.0 Pro для преобразования текста в видео на HiAPI: руководство по curl и Python
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата
-
Руководство
Как использовать kling-4.0/text-to-video через HiAPI API: curl, Python и рабочий пример запроса
Практическое руководство для разработчиков: кинематографичные промпты, синхронный звук, асинхронный опрос и скачивание результатов