Руководство
Создавайте мультимодельные AI-приложения на hiapi через единый унифицированный API
- Модель
- seedance-2.5
Что вы построите
Большинство команд в итоге обращаются к трём-четырём разным AI-провайдерам для одного продукта: модель текст-в-изображение для миниатюр, модель текст-в-видео для коротких роликов для соцсетей, а может быть и TTS-модель для озвучки. У каждого провайдера свой SDK, своя схема аутентификации, своя логика опроса. hiapi сводит всё это к одной схеме эндпоинтов: POST /v1/tasks создаёт задачу, GET /v1/tasks/:id опрашивает задачу, и это применимо к каждой модели генерации на платформе.
В этом руководстве показана эта схема интеграции на трёх реальных, работающих сейчас моделях — z-image (текст-в-изображение), qwen-image-2.0 (текст-в-изображение, другая схема) и seedance-2.5 (текст-в-видео) — чтобы вы ясно увидели, где API полностью совпадает, а где отличается только объект input каждой модели.
Предварительные требования
- API-ключ hiapi, полученный в консоли
curlили любой HTTP-клиент, умеющий отправлять JSON- SDK не нужен — каждый пример ниже это чистый HTTP-вызов
Каждому запросу нужен один заголовок:
Authorization: Bearer <your-api-key>
При недействительном или отсутствующем ключе возвращается ошибка класса 401 ещё до обращения к какой-либо модели:
{
"error": {
"code": "permission_denied",
"message": "invalid api key",
"request_id": "req_...",
"type": "hiapi_error"
}
}
Бесключевого или анонимного режима нет — каждый вызов /v1/tasks должен нести действующий bearer-токен. О ротации ключей и областях действия см. Аутентификация.
Минимальный рабочий пример
1. Создание задачи
Структура вызова создания всегда одинакова: идентификатор model и объект input, специфичный для модели. Вот создание задачи изображения через z-image:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image",
"input": {
"prompt": "a minimalist workspace, soft morning light, isometric illustration",
"aspect_ratio": "16:9"
}
}'
Ответ возвращается сразу — генерация идёт асинхронно:
{
"code": 200,
"message": "ok",
"data": {
"taskId": "tk-hiapi-xxxxxxxxxxxx",
"status": "queued"
}
}
Теперь та же схема с qwen-image-2.0. Тот же эндпоинт, та же внешняя структура — отличается только input (эта модель принимает строку size, а не aspect_ratio):
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-image-2.0",
"input": {
"prompt": "a minimalist workspace, soft morning light, isometric illustration",
"size": "2048*2048"
}
}'
И создание видеозадачи через seedance-2.5/text-to-video — всё та же внешняя структура, но теперь с duration и более широким перечислением aspect_ratio:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5/text-to-video",
"input": {
"prompt": "a paper airplane gliding through a sunlit office, slow motion",
"duration": 5,
"aspect_ratio": "16:9"
}
}'
В этом и суть: внешняя структура задачи никогда не меняется, меняется только input. Каждая модель на hiapi документирует свою схему input на странице модели — обязательно проверяйте схему конкретной модели перед построением новой интеграции, потому что поля вроде aspect_ratio, size и duration не взаимозаменяемы между моделями.
2. Опрос результата
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxxxxxxxxxx \
-H "Authorization: Bearer $HIAPI_API_KEY"
status последовательно проходит queued → handling → archiving, а затем переходит в терминальное состояние success или fail. При успехе data.output — это массив: большинство моделей изображений/видео возвращают одну запись, но одна задача может вернуть несколько типов вывода (например, видеомодель возвращает и video, и thumbnail):
{
"code": 200,
"message": "ok",
"data": {
"taskId": "tk-hiapi-xxxxxxxxxxxx",
"status": "success",
"output": [
{ "type": "image", "url": "https://...", "expireAt": "2026-10-09T00:00:00Z" }
]
}
}
expireAt важен — URL вывода по умолчанию временные. Скачивайте байты сразу после завершения задачи (или перезагружайте в собственное хранилище). Если нужно более долгое хранение файлов платформой, задайте при создании storage: "persistent" или повысьте уровень позже — см. Хранилище.
При неудаче вы получите объект error вместо output:
{
"code": 200,
"message": "ok",
"data": {
"taskId": "tk-hiapi-xxxxxxxxxxxx",
"status": "fail",
"error": { "code": "...", "message": "..." }
}
}
Этот минимальный цикл опроса на Python одинаково работает для всех моделей выше:
import time
import requests
def run_task(model: str, input_payload: dict, api_key: str) -> list[dict]:
headers = {"Authorization": f"Bearer {api_key}"}
create = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers=headers,
json={"model": model, "input": input_payload},
).json()
task_id = create["data"]["taskId"]
time.sleep(3) # initial wait before first poll
while True:
poll = requests.get(
f"https://api.hiapi.ai/v1/tasks/{task_id}", headers=headers
).json()
status = poll["data"]["status"]
if status == "success":
return poll["data"]["output"]
if status == "fail":
raise RuntimeError(poll["data"]["error"])
time.sleep(4) # 3-5s between polls; use 5-10s for video models
Паттерны для продакшена
Используйте callback вместо опроса в продакшене
Опрос подходит для скриптов или CLI-инструментов, но при любом реальном объёме трафика предпочтительнее callback: передайте объект callback при создании задачи, и hiapi отправит POST с терминальным результатом на ваш эндпоинт, вместо того чтобы вы в цикле повторно запрашивали GET /v1/tasks/:id.
{
"model": "z-image",
"input": { "prompt": "...", "aspect_ratio": "1:1" },
"callback": { "url": "https://yourapp.com/webhooks/hiapi", "when": "final" }
}
when: "final" означает, что вы получите ровно один POST, срабатывающий в терминальном состоянии (success или fail), — без шума от промежуточных состояний handling/archiving. Если вы настроили callback, но ничего не получили, проверьте, доступен ли ваш эндпоинт публично и быстро ли он возвращает 2xx; о самой частой причине тихой потери callback см. эту статью.
Идемпотентные повторы
Сетевые сбои неизбежны. Если повторять вызов POST /v1/tasks после таймаута без защиты, можно создать (и оплатить) дублирующиеся задачи. Отправьте заголовок Idempotency-Key (любая строка не длиннее 255 байт, обычно UUID, генерируемый для каждого логического запроса), и повторы с тем же ключом вернут исходную задачу, а не создадут новую:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Idempotency-Key: 8f14e45f-ceea-467e-bd5f-...-9a2c" \
-H "Content-Type: application/json" \
-d '{"model": "z-image", "input": {"prompt": "...", "aspect_ratio": "1:1"}}'
Обработка ошибок валидации по моделям
Поскольку у каждой модели своя схема input, самый частый вид сбоя — 400 по полю, которое допустимо для одной модели, но недопустимо для другой, например отправка aspect_ratio модели, ожидающей size:
{
"code": 400,
"data": null,
"error_code": "INVALID_REQUEST",
"message": "invalid input: aspect_ratio: value must be one of '1:1', '4:3', '3:4', '16:9', '9:16'"
}
Если вы строите мультимодельный роутер (позволяющий пользователю или вашей собственной логике выбирать модель во время выполнения), ведите небольшой реестр построителей input по моделям, а не одну общую структуру payload:
MODEL_INPUT_BUILDERS = {
"z-image": lambda prompt, **kw: {
"prompt": prompt, "aspect_ratio": kw.get("aspect_ratio", "1:1")
},
"qwen-image-2.0": lambda prompt, **kw: {
"prompt": prompt, "size": kw.get("size", "2048*2048")
},
"seedance-2.5/text-to-video": lambda prompt, **kw: {
"prompt": prompt,
"duration": kw.get("duration", 5),
"aspect_ratio": kw.get("aspect_ratio", "16:9"),
},
}
def build_task_payload(model: str, prompt: str, **kw) -> dict:
return {"model": model, "input": MODEL_INPUT_BUILDERS[model](prompt, **kw)}
Так особенности каждой модели собраны в одном месте, а не разбросаны по каждой точке вызова. Несуществующий или принадлежащий другому аккаунту taskId возвращает обычный 404:
{ "code": 404, "message": "task not found", "data": null }
А временные 503 следует повторять с экспоненциальной задержкой, а не показывать пользователю напрямую — ограничения по скорости и ёмкости описаны в Ограничения скорости.
См. также
- Справочник по асинхронному API задач — полный контракт
create/detail - Аутентификация — области действия и ротация API-ключей
- Хранилище — сохранение вывода после срока истечения по умолчанию
- Почему ваш callback задачи может не срабатывать
- Просмотр всех моделей — схема
inputкаждой модели на её странице - Цены — стоимость рассчитывается по модели и выводу, а не единообразно по запросу
Частые вопросы
Нужны ли для каждой модели отдельный SDK или API-ключ?
Нет. Один API-ключ, одна схема эндпоинтов (/v1/tasks) — для каждой модели на платформе. Меняется только объект input в теле запроса.
Почему сразу после создания задачи в ответе ещё нет output?
Генерация асинхронна. Вызов создания возвращает только taskId и status: "queued" — вы должны опрашивать GET /v1/tasks/:id (или использовать callback), пока status не достигнет success или fail.
Можно ли вызывать API без аутентификации для быстрого теста?
Нет — каждый вызов /v1/tasks требует действующего ключа Authorization: Bearer. В продакшене нет бесключевого или демо-режима; сначала сгенерируйте ключ в консоли.
Что будет, если опрашивать после истечения URL вывода?
Сама запись задачи сохраняется, но output[].url непостоянных задач перестанет разрешаться после expireAt. Скачивайте файлы сразу при успехе или, если нужно долгое хранение, задайте при создании storage: "persistent".
Как узнать, какие поля принимает модель?
Смотрите страницу этой модели в разделе Модели — каждая документирует свою точную схему input. Не предполагайте, что aspect_ratio, size или duration переносимы между моделями; как показано выше, z-image и qwen-image-2.0 уже расходятся в том, как задаётся форма изображения.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата