HiAPI
Блог

Руководство

Как использовать qwen-audio-3.0-tts-plus через hiapi API: преобразование текста в речь с помощью curl и Python

Aug 4, 2026
Как использовать 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 верхнего уровня.

Связанные материалы

Часто задаваемые вопросы

Генерация аудио отличается от 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.

Где найти актуальную цену? На странице цен — в этом руководстве намеренно не зашита стоимость за символ или за запрос, поскольку цены могут меняться.

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

Все статьи →

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

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

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