通过语音验证创建个性化的 Voice Persona。这是一个单任务、两阶段的流程:init(上传语音 + 获取验证短语)→ complete(上传验证录音 + 创建角色)。整个流程使用同一个 taskId。
工作流程
用户的语音音频
│
▼
① voicePersona/init
│ 上传语音 → 提取人声 → 返回验证短语
│
│ 返回: { taskId }
│ 轮询: GET /suno/v2/status?taskId=xxx
│ 等待 status == "awaiting"
│ data: { phrase_text, ... }
│
▼
用户朗读 phrase_text 并录音(30 秒超时限制内)
│
▼
② voicePersona/complete(使用相同 taskId)
│ 上传验证录音 → 语音验证 → 创建角色
│
│ 轮询同一 taskId: GET /suno/v2/status?taskId=xxx
│ 等待 status == "success"
│ data: 角色详情
▼
完成 → 在 /generate 中使用角色
任务状态流
queued → running → awaiting → running → success
│ │
│ └── complete 失败 → failed
└── 用户超时 → failed (VP_USER_TIMEOUT)
任务达到 awaiting 状态后,您必须在 30 秒(默认)内调用 complete。超时后任务将失败并返回 VP_USER_TIMEOUT,您需要从 init 重新开始。
第一步:Init — 上传语音并获取验证短语
上传用户的语音音频。系统将提取人声并返回一段用户需要朗读的验证短语。
这是一个异步任务。使用返回的 taskId 轮询获取任务状态。等待状态变为 awaiting(不是 success)。
POST /suno/v2/voicePersona/init
| 字段 | 类型 | 必填 | 描述 |
|---|
voice_audio_url | string (URL) | 是 | 可公开下载的语音音频 URL(WAV/MP3) |
language | string | 是 | 验证短语语言:zh en ja ko es fr de pt ru hi |
vocal_start_s | number | 否 | 人声提取开始时间(秒),默认:0 |
vocal_end_s | number | 否 | 人声提取结束时间(秒),默认:自动检测 |
轮询结果(status: awaiting)
当任务达到 awaiting 状态时,data 包含:
| 字段 | 描述 |
|---|
phrase_text | 验证短语文本 — 用户必须朗读并录制此文本 |
phrase_id | 验证短语 ID(内部使用) |
vox_audio_id | 提取的人声音频 ID(内部使用) |
voice_recording_id | 录音 ID(内部使用) |
vocal_start_s | 人声开始时间(秒) |
vocal_end_s | 人声结束时间(秒) |
用户只需要 phrase_text。所有其他字段由系统内部使用 — 您无需将它们传给 complete 步骤。
参见 Init API 参考 →
第二步:Complete — 上传验证录音并创建角色
用户朗读 phrase_text 并录制后,使用相同的 taskId 上传验证录音,完成语音验证并创建角色。
使用 init 返回的相同 taskId。调用 complete 后,继续轮询同一个 taskId 直到状态变为 success。
POST /suno/v2/voicePersona/complete
| 字段 | 类型 | 必填 | 描述 |
|---|
taskId | string (UUID) | 是 | init 返回的 taskId(同一任务) |
verification_audio_url | string (URL) | 是 | 用户的验证录音 URL(WAV/MP3) |
name | string | 是 | 角色名称 |
description | string | 否 | 角色描述 |
is_public | boolean | 否 | 是否公开(默认:false) |
image_s3_id | string | 否 | 封面图片(base64),未提供则自动生成 |
不需要中间数据(vox_audio_id、phrase_id 等)— 系统会自动从 init 阶段读取这些数据。
参见 Complete API 参考 →
完整示例
const API_BASE = 'https://api.mountsea.ai';
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-api-key'
};
async function pollTask(taskId, targetStatus = 'success') {
while (true) {
const res = await fetch(`${API_BASE}/suno/v2/status?taskId=${taskId}`, { headers });
const task = await res.json();
if (task.status === targetStatus) return task.data;
if (task.status === 'success') return task.data;
if (task.status === 'failed') throw new Error(task.failReason);
await new Promise(r => setTimeout(r, 3000));
}
}
// Step 1: Init — upload voice and get verification phrase
const initRes = await fetch(`${API_BASE}/suno/v2/voicePersona/init`, {
method: 'POST',
headers,
body: JSON.stringify({
voice_audio_url: 'https://example.com/my-voice.wav',
language: 'zh'
})
});
const { taskId } = await initRes.json();
// Poll until status is "awaiting"
const initData = await pollTask(taskId, 'awaiting');
console.log('Please read aloud:', initData.phrase_text);
// → User records themselves reading the phrase ...
// Step 2: Complete — upload verification recording (same taskId)
await fetch(`${API_BASE}/suno/v2/voicePersona/complete`, {
method: 'POST',
headers,
body: JSON.stringify({
taskId,
verification_audio_url: 'https://example.com/verification.wav',
name: 'My Voice',
description: '我的专属声音'
})
});
// Poll the SAME taskId until status is "success"
const persona = await pollTask(taskId, 'success');
console.log('Voice Persona created:', persona);
错误码
| 状态码 | 错误 | 描述 |
|---|
| 400 | VP_TASK_NOT_FOUND | taskId 不存在或不是 Voice Persona 任务 |
| 400 | VP_INVALID_STATUS | 任务状态不是 awaiting,无法调用 complete |
| 408 | VP_USER_TIMEOUT | init 后等待 complete 超时(默认 30 秒) |
| 409 | VP_SESSION_EXPIRED | 验证会话已过期,需从 init 重新开始 |
| 500 | VP_LOCK_EXPIRED | 内部锁已过期(请重试) |
| 503 | VP_NO_DEDICATED_ACCOUNT_AVAILABLE | 没有可用的专用账户 |
| 503 | VP_ALL_ACCOUNTS_BUSY | 所有账户队列已满,请稍后重试 |
| 504 | VP_ORPHAN_TIMEOUT | 任务排队超时 |
重要说明
验证录音必须清晰包含完整的 phrase_text 内容。不完整或不清晰的录音将导致语音验证失败。
- 单一 taskId 生命周期:init 和 complete 使用相同的
taskId — 在整个流程中轮询同一个任务。
awaiting 状态:init 完成后,任务状态为 awaiting(不是 success)。data 字段包含供用户朗读的 phrase_text。
- 30 秒时间限制:任务达到
awaiting 后,您必须在 30 秒内调用 complete。超时将导致 VP_USER_TIMEOUT。
- 简化参数:
complete 只需要 taskId + 验证录音 URL + 角色信息。所有中间数据由系统自动填充。
- 同一账户保证:两个阶段自动使用相同的 Suno 账户。
- 语言选择:
language 决定验证短语的语言。为获得最佳效果,请选择与原始语音音频匹配的语言。
- 处理时间:Init 大约需要 20-60 秒(包含人声提取);Complete 大约需要 10-30 秒(包含语音验证)。
- 并发安全:系统对每个账户的 Voice Persona 操作进行串行化 — 不同用户的并发请求不会相互干扰。