HiAPI
博客

教程

如何通过 hiapi API 使用 qwen-audio-3.0-tts-plus:用 curl 和 Python 实现文本转语音

2026年11月3日
如何通过 hiapi API 使用 qwen-audio-3.0-tts-plus:用 curl 和 Python 实现文本转语音

qwen-audio-3.0-tts-plus 是一个文本转语音模型,通过 hiapi 平台的统一异步任务队列访问——与图像和视频生成使用的是同一个 POST /v1/tasks 端点,而不是独立的音频 API。你提交文本,立即拿回一个 taskId,然后轮询或等待回调,获取可下载的音频文件 URL。本教程将带你完成一个在 curl 和 Python 中可用的请求(已针对实时 API 进行端到端验证),然后介绍你实际需要的生产模式:回调与轮询、幂等重试,以及需要处理的精确错误形态。

你将构建什么

一个脚本,将文本提交到 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"}

然后使用相同的 bearer 令牌轮询 GET /v1/tasks/<taskId>,直到 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 几乎正好在 created 之后 7 天,因此如果你需要长期保留音频,请下载字节并自行存储。

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" 失败。

回调 vs. 轮询

对于超出快速脚本范围的任何情况,跳过轮询,让 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 都会向你的 callback.url POST 一次,你从该负载中读取与轮询 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 队列、相同的创建后轮询或回调流程、相同的 output[0].url 形态。只有 output[0].type(此处为 "audio")和 input 模式因模型而异。

如果我不设置 format 会怎样? 你会得到一个 MP3——测试中省略它已确认。如果你需要 wav、pcm 或 opus,请显式设置 format。

我可以流式返回音频而不是等待任务完成吗? 不可以。此模型只暴露标准的创建/轮询/回调任务流程——其输入模式中没有流式参数,而且生成速度足够快(短文本只需几秒钟),每 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。

我在哪里找到当前价格? 在 价格页面——本教程有意不硬编码每字符或每请求成本,因为价格可能会变化。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档