Руководство
Как использовать qwen-audio-3.0-tts-plus через hiapi API: преобразование текста в речь с помощью curl и Python
qwen-audio-3.0-tts-plus — это модель преобразования текста в речь, доступная через унифицированную асинхронную очередь задач платформы hiapi — тот же эндпоинт POST /v1/tasks, что используется для генерации изображений и видео, а не отдельный аудио API. Вы отправляете текст, сразу получаете taskId, а затем опрашиваете задачу или ждёте callback, чтобы получить URL загружаемого аудиофайла. В этом руководстве мы пройдём рабочий запрос на curl и Python (проверенный сквозным образом на живом API), а затем разберём производственные паттерны, которые вам действительно понадобятся: callback против опроса, идемпотентные повторы и точные формы ошибок, которые нужно обрабатывать.
Что вы создадите
Скрипт, который отправляет текст в qwen-audio-3.0-tts-plus, ждёт завершения задачи и скачивает сгенерированное аудио — плюс справочник по параметрам и паттерны обработки ошибок, чтобы превратить этот скрипт в настоящую интеграцию.
Предварительные требования: ключ hiapi API. Получите его в панели управления hiapi — каждый запрос ниже аутентифицируется с помощью Authorization: Bearer sk-<your-key>.
Минимальный рабочий пример
curl
Создание задачи:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-audio-3.0-tts-plus",
"input": {
"text": "Welcome to hiapi, the unified API for AI models.",
"voice": "longanlingxin"
}
}'
{"code": 200, "data": {"taskId": "tk-hiapi-01KZ59B7ZJ7012PXB5J9GE1QE7"}, "message": "success"}
Затем опрашивайте GET /v1/tasks/<taskId> с тем же bearer-токеном, пока data.status не перестанет быть "processing". Для этой модели в тестах это заняло около 5 секунд:
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01KZ59B7ZJ7012PXB5J9GE1QE7 \
-H "Authorization: Bearer $HIAPI_KEY"
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01KZ59B7ZJ7012PXB5J9GE1QE7",
"status": "success",
"model": "qwen-audio-3.0-tts-plus",
"storage": "temp",
"created": 1785810231,
"completed": 1785810236,
"output": [{"type": "audio", "url": "https://temp.hiapi.ai/.../01KZ59B7ZJ7012PXB5J9GE1QE7-0.mp3", "artifactId": "66654", "expireAt": 1786415036}]
},
"message": "success"
}
output[0].url — это реально загружаемый MP3-файл (content-type: audio/mpeg — подтверждено прямой загрузкой). Это временная ссылка: при значении storage по умолчанию "temp" expireAt наступает почти ровно через 7 дней после created, поэтому если вам нужно долговременное хранение аудио, скачайте байты и сохраните их самостоятельно.
Python
import os
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
headers = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}
resp = requests.post(
API_BASE,
headers={**headers, "Content-Type": "application/json"},
json={
"model": "qwen-audio-3.0-tts-plus",
"input": {
"text": "Welcome to hiapi, the unified API for AI models.",
"voice": "longanlingxin",
},
},
timeout=30,
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
while True:
task = requests.get(f"{API_BASE}/{task_id}", headers=headers, timeout=30).json()["data"]
if task["status"] == "success":
audio_url = task["output"][0]["url"]
break
if task["status"] == "fail":
raise RuntimeError(task["error"])
time.sleep(2)
audio_bytes = requests.get(audio_url, timeout=60).content
with open("output.mp3", "wb") as f:
f.write(audio_bytes)
Паттерны для производственного использования
Полная схема входных данных
Объект input принимает только перечисленные ниже поля — API отклоняет любые другие поля с кодом 400, поэтому не переносите имена параметров от других TTS-провайдеров:
| Поле | Обязательно | Тип / значение |
|---|---|---|
text |
Да | Строка |
voice |
Да | Одно из: "longanlingxin", "longanlufeng" (у этой модели сейчас доступны только два голоса) |
format |
Нет | Одно из: "pcm", "wav", "mp3", "opus" — при пропуске по умолчанию используется mp3 |
sample_rate |
Нет | Одно из: 8000, 16000, 22050, 24000, 44100, 48000 |
pitch |
Нет | Число, 0.5–2 |
volume |
Нет | Число, 0–100 |
Каждое из этих ограничений и значений перечисления взято из собственных ошибок валидации API — передайте недопустимый voice или pitch вне диапазона, и hiapi точно сообщит вам допустимые значения:
{"code": 400, "data": null, "error_code": "INVALID_REQUEST", "message": "invalid input: voice: value must be one of 'longanlingxin', 'longanlufeng'"}
У этой модели нет полей управления emotion, speed или в стиле SSML — запросы с этими полями завершаются ошибкой "additional properties '...' not allowed".
Callback против опроса
Для всего, что выходит за рамки быстрого скрипта, пропустите опрос и позвольте hiapi отправлять результат. Добавьте объект callback в запрос создания задачи:
{
"model": "qwen-audio-3.0-tts-plus",
"callback": {"url": "https://example.com/hiapi/callback", "when": "final"},
"input": {"text": "Welcome to hiapi.", "voice": "longanlingxin"}
}
"final" сейчас является единственным поддерживаемым значением when — hiapi отправит один POST на ваш callback.url независимо от того, завершилась задача успешно или с ошибкой, а из этой полезной нагрузки вы прочитаете ту же форму деталей задачи, что и при опросе GET /v1/tasks/<taskId>. Полностью опустите callback и вместо этого опрашивайте самостоятельно, как показано в примерах выше.
Также стоит знать: по умолчанию вывод задачи имеет storage: "temp" (файлы живут около недели, как видно из значения expireAt выше). Если вам нужно, чтобы аудио было доступно долго, установите для задачи "storage": "persistent" — постоянное хранение оплачивается по размеру, поэтому для разовых генераций обычно дешевле скачать файл и сохранить его самостоятельно.
Идемпотентность и повторы
POST /v1/tasks принимает заголовок Idempotency-Key (до 255 байт). Повтор одного и того же запроса с тем же ключом в рамках одной учётной записи создаёт задачу только один раз — повтор возвращает исходный taskId, а не вторую оплачиваемую генерацию. Используйте его для повторов после таймаута или 5xx, когда вы действительно не знаете, дошёл ли первый запрос:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: tts-job-42" \
-d '{"model": "qwen-audio-3.0-tts-plus", "input": {"text": "...", "voice": "longanlingxin"}}'
Обработка ошибок
Недействительный или неавторизованный ключ возвращает HTTP 401 со стандартным конвертом ошибки hiapi (проверено напрямую на этой модели):
{"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "request_id": "...", "type": "hiapi_error"}}
Неверная полезная нагрузка input возвращает HTTP 400 с error_code: "INVALID_REQUEST" и message, указывающим на нарушающее поле, как показано в разделе схемы выше — ветвитесь по error_code / error.code, а не по человекочитаемому тексту сообщения. Если задача достигает терминального состояния "fail" вместо сбоя при создании, ответ с деталями задачи содержит ту же форму в data.error (code + message), а не в ключе error верхнего уровня.
Связанные материалы
- Панель управления hiapi — создание и управление ключами API.
- Документация по созданию задач — полный контракт
POST /v1/tasks, включая заголовки, callback и идемпотентность. - Документация по получению деталей задачи — эндпоинт опроса, использованный выше.
- Документация по аутентификации hiapi — как заголовок
Authorizationи области действия ключей работают на всей платформе. - Документация по ограничениям скорости hiapi — поведение
429иRetry-After. - Аудиомодели на hiapi — просмотрите другие голосовые и аудиомодели платформы.
- Актуальную цену этой модели смотрите на живой странице цен, здесь она не повторяется.
Часто задаваемые вопросы
Генерация аудио отличается от API задач hiapi для изображений/видео?
Нет — та же очередь POST /v1/tasks, тот же процесс создания с последующим опросом или callback, та же форма output[0].url. Отличаются только output[0].type (здесь "audio") и схема input в зависимости от модели.
Что будет, если я не укажу format?
Вы получите MP3 — это подтверждено в тестах при его пропуске. Если вам нужен wav, pcm или opus, явно задайте format.
Могу ли я получать аудио потоком вместо ожидания завершения задачи? Нет. Эта модель предоставляет только стандартный процесс задач create/poll/callback — в её схеме входных данных нет параметра потоковой передачи, а генерация достаточно быстрая (для короткого текста всего несколько секунд), так что опроса каждые 1–2 секунды обычно достаточно.
Как долго URL вывода остаётся действительным?
Около 7 дней по умолчанию (storage: "temp"), исходя из интервала между временными метками задачи created и expireAt. Скачивайте аудио вовремя или, если вам нужна более долгая доступность, установите для задачи "storage": "persistent".
Почему мой запрос завершается ошибкой "additional properties ... not allowed"?
Схема строгая — эта модель принимает только text, voice, format, sample_rate, pitch и volume. Параметры из других TTS API (например, emotion или speed) здесь не распознаются и вернут 400.
Где найти актуальную цену? На странице цен — в этом руководстве намеренно не зашита стоимость за символ или за запрос, поскольку цены могут меняться.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата