模型能力

Custom Voices

从简短的参考音频 clip 克隆 voice,并在任何支持内置 voice 的位置使用。上传音频 sample 后,即可立即在 TTS 和 Speech to Speech API 中使用。

如何使用 Custom Voices

Console中创建 voice 后,点击 voice card 上的三点菜单,然后选择 Copy Voice ID。如果通过 API 创建 custom voice(仅限 Enterprise),response 会返回 voice_id

在所有 Voice API 中,custom voice 与内置 voice 可以互换使用。将 voice_id 传给以下任一 API:

  • POST /v1/tts

  • wss://api.x.ai/v1/tts

  • wss://api.x.ai/v1/realtime

内置 voice 仍可通过 GET /v1/tts/voices 获取。Custom voice 仅由 GET /v1/custom-voices 返回,不会出现在内置 voice 列表中。Custom voice 仅限你的 team 使用,其他用户无法访问。

录制参考音频

通过克隆最长 120 秒的参考音频 clip 创建 custom voice。为获得最佳效果:

  • 在安静环境中录制,最好使用高质量麦克风。

  • 自然朗读。 如果听起来像照着脚本念,生成的 voice 也会保留这种特点。

  • 音频越长越好。 少于 30 秒的 clip 可能缺乏细节。建议录制 90–120 秒以获得最佳效果。

  • 表达要富有变化。 生成的 voice 会匹配录音中的表现力。

录制什么内容

Model 不仅会学习音色,还会学习参考 clip 的表达方式。为获得最佳效果,请让录音内容与计划生成的内容相匹配:

  • 客户支持 — 录制真实的支持对话,包括问候、等待、故障排查步骤和结束语。

  • 有声书旁白 — 使用最终输出所需的节奏与语调朗读几段散文。

  • 对话式 assistant — 录制自然、无脚本的讲话,例如向朋友解释某个主题。

  • 新闻或纪录片 — 使用自然的播报 voice 朗读一篇短文。

与预期用例相符的录音,比精心制作但无关的 sample 效果更好。

录音设置

  • 麦克风。 建议使用录音室电容麦克风或高质量 USB 麦克风。手机耳机也能使用,但会引入明显噪声。

  • 防喷罩。 建议使用。没有防喷罩时,爆破音(pb)会被还原成明显的冲击声。

  • 房间声学处理。 请在较小且配有柔软家具的房间中录制。硬墙房间会产生回声和混响,这些也会被生成的 voice 还原。

  • 单一说话者。 录音应只包含一个 voice,不要有背景音乐或音效。

  • 背景噪声。 保持房间安静。关闭 HVAC、风扇和通知声音。背景噪声会与 voice 一起被克隆。

创建 Custom Voice

在 Console 中开始使用,可以免费创建最多 30 个 custom voice,并立即在所有 Voice API 中使用。

在 Console 中克隆 Voice

API 快速开始

根据参考音频文件创建 custom voice,然后使用它合成语音:

# 1. Create the voice from a reference clip (max 120s).
CREATE_RESPONSE=$(curl -s -X POST https://api.x.ai/v1/custom-voices \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -F "name=Friendly Narrator" \
  -F "language=en" \
  -F "gender=female" \
  -F "tone=warm" \
  -F "use_case=narration" \
  -F "file=@reference.wav;type=audio/wav")

echo "$CREATE_RESPONSE"
# {"voice_id":"abc123xy","name":"Friendly Narrator",...}

# Extract the voice_id from the response (requires jq).
VOICE_ID=$(echo "$CREATE_RESPONSE" | jq -r '.voice_id')

# 2. Use the new voice for TTS.
curl -X POST https://api.x.ai/v1/tts \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"text\": \"Hello! This audio was synthesized using my custom voice.\",
    \"voice_id\": \"$VOICE_ID\",
    \"language\": \"en\"
  }" \
  --output hello.mp3

Endpoints

所有 endpoint 都位于 https://api.x.ai/v1/custom-voices 下,并使用 Bearer API key 进行身份验证。

创建 custom voice

POST /v1/custom-voices 使用 multipart/form-data。只有 file 是必填项。

字段类型必填说明
filebinary参考音频。最长 120 秒。
namestring显示名称。
descriptionstring自由文本说明。
genderstringmalefemaleneutral
accentstring自由文本(例如 BritishAmerican)。
agestringyoungmiddle-agedold
languagestringISO 639(en)或 BCP-47 格式(en-USzh-CN)。Region 必须大写。
use_casestringconversationalnarrationcharacterseducationaladvertisementsocial_mediaentertainment
tonestringwarmcasualprofessionalfriendlyauthoritativeexpressivecalm

建议上传的参考文件使用以下格式和设置:

设置建议
Codec.wav(uncompressed PCM)。也接受 MP3、FLAC、OGG、Opus、M4A、AAC、MKV 和 MP4,但 lossy 格式可能引入压缩 artifact,并被生成的 voice 还原。
Sample rate24 kHz。更高的 rate(44.1 kHz、48 kHz)会在服务端 downsample。较低的 rate 会降低 fidelity。
Bit depth16-bit PCM 已足够。也支持 24-bit。
ChannelsMono。Stereo 文件会自动 downmix,但使用 mono 录制可以避免潜在的 phase artifact。

长度

  • 无最短限制,最长 120 秒。 接受任意长度且不超过 120 秒的 clip;更长的 clip 会以 400

  • 建议 90 秒以上。 更长的 clip 能捕捉更多 prosody 和语调变化,生成更自然、更富表现力的 voice。

创建成功会返回 201 以及新的 voice object:

JSON

{
  "voice_id": "nlbqfwie",
  "name": "Friendly Narrator",
  "description": "Warm, conversational tone for narration.",
  "gender": "female",
  "accent": "American",
  "age": "young",
  "language": "en",
  "use_case": "narration",
  "tone": "warm",
  "created_at": "2026-04-26T18:56:34.872993+00:00"
}

voice_id 是由 8 个小写字母或数字组成的标识符。

列出 custom voices

GET /v1/custom-voices 会分页返回你的 team 拥有的所有 voice。

Query parameter默认值说明
limit100Page size,1-1000。
pagination_token上一页 response 中的 token。第一页省略。
curl -s "https://api.x.ai/v1/custom-voices?limit=50" \
  -H "Authorization: Bearer $XAI_API_KEY"

Response:

JSON

{
  "voices": [
    {
      "voice_id": "nlbqfwie",
      "name": "Friendly Narrator",
      "description": "Warm, conversational tone for narration.",
      "gender": "female",
      "accent": "American",
      "age": "young",
      "language": "en",
      "use_case": "narration",
      "tone": "warm",
      "created_at": "2026-04-26T18:56:34.872993+00:00"
    }
  ],
  "pagination_token": null
}

获取 custom voice

GET /v1/custom-voices/{voice_id} 返回单个 voice 的 metadata。未知 ID 或属于其他 team 的 voice 会返回 404

Response body 与 Create

更新 metadata

PATCH /v1/custom-voices/{voice_id},使用 JSON body。所有字段均为可选,并遵循以下规则:

  • 省略字段 — 不做更改。

  • 字段设为 null — 清除该值。

  • 字段设为非空 string — 更新该值。

  • 字段设为 "" — 会以 400

该 endpoint 永远不会更改底层音频。如需重新录制,请删除 voice 并创建新的 voice。

curl -X PATCH "https://api.x.ai/v1/custom-voices/nlbqfwie" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description": "Updated after a tuning pass.", "tone": "calm"}'

返回完整的已更新 voice object:

JSON

{
  "voice_id": "nlbqfwie",
  "name": "Friendly Narrator",
  "description": "Updated after a tuning pass.",
  "gender": "female",
  "accent": "American",
  "age": "young",
  "language": "en",
  "use_case": "narration",
  "tone": "calm",
  "created_at": "2026-04-26T18:56:34.872993+00:00"
}

下载参考音频

GET /v1/custom-voices/{voice_id}/audio 会以正确的 Content-Type header streaming 原始参考文件(例如 audio/wavaudio/mpeg)。

删除 custom voice

DELETE /v1/custom-voices/{voice_id} 会删除 voice 及其底层音频。

curl -X DELETE "https://api.x.ai/v1/custom-voices/nlbqfwie" \
  -H "Authorization: Bearer $XAI_API_KEY"

Response 为 {"deleted": true}。删除后,对同一 voice_id 的后续请求会返回 404,任何引用该 voice 的 TTS / Speech to Speech 调用都会以 unknown-voice error 失败。

使用 Custom Voice

创建后,custom voice_id 可以用于任何支持内置 voice_id 的位置。

REST TTS

Bash

curl -X POST https://api.x.ai/v1/tts \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Welcome back. How can I help today?",
    "voice_id": "nlbqfwie",
    "language": "en"
  }' \
  --output welcome.mp3

Streaming TTS WebSocket

打开连接时,将 custom voice 作为 voice query parameter 传入。完整 event protocol 请参阅 Text to Speech - Streaming

前置条件:安装 WebSocket client library:Python 使用 pip install websockets,Node.js 使用 npm install ws

Python

import asyncio
import base64
import json
import os
import websockets

async def stream_with_custom_voice(voice_id: str):
    uri = f"wss://api.x.ai/v1/tts?language=en&voice={voice_id}&codec=mp3"
    async with websockets.connect(
        uri,
        additional_headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
    ) as ws:
        await ws.send(json.dumps({"type": "text.delta", "delta": "Streaming with my custom voice."}))
        await ws.send(json.dumps({"type": "text.done"}))
        audio = bytearray()
        async for msg in ws:
            event = json.loads(msg)
            if event["type"] == "audio.delta":
                audio.extend(base64.b64decode(event["delta"]))
            elif event["type"] == "audio.done":
                break
        with open("stream.mp3", "wb") as f:
            f.write(audio)

asyncio.run(stream_with_custom_voice("nlbqfwie"))

Speech to Speech API

voice message 中设置 session.update。完整 session 生命周期请参阅 Speech to Speech API 文档

Python

import asyncio
import json
import os
import websockets

async def realtime_with_custom_voice(voice_id: str):
    async with websockets.connect(
        "wss://api.x.ai/v1/realtime",
        additional_headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
    ) as ws:
        await ws.send(json.dumps({
            "type": "session.update",
            "session": {
                "voice": voice_id,
                "instructions": "You are a helpful assistant.",
                "turn_detection": {"type": "server_vad"},
            },
        }))
        # ... continue with the standard realtime event loop ...

asyncio.run(realtime_with_custom_voice("nlbqfwie"))

限制

参考音频最长时长120 秒
每个 team 的 custom voice 数量30
Voice ID 长度8 个字符,小写字母或数字

需要超过 30 个 voice?

默认每个 team 最多 30 个 custom voice。如果需要更多,请联系我们讨论提高限制。

申请更多 custom voice

错误处理

Status含义操作
201Voice 已创建保存 voice_id 并开始使用。
200读取 / 更新 / 删除成功-
400错误请求检查:音频不超过 120 秒;label 值在允许的 enum 范围内;PATCH 不包含空 string。达到 team 的 30 个 voice 限制时也会返回该错误,请删除现有 voice 或 申请更多
401未授权API key 缺失或无效。
403该 team 未启用 custom voice,或 POST /v1/custom-voices 在没有 Enterprise contract 的情况下被调用请在 Console Playground联系销售团队以启用 create API。
404Voice 不存在该 ID 不存在或属于其他 team。
500Server 错误使用 exponential backoff 重试。