【Khuyến nghị】 API hồ sơ giọng nói

Cập nhật 2026-09-18 · nhóm Suno-API

✅ Chuỗi này được khuyến nghị cho tích hợp mới. Theo đánh giá thực tế của nhiều người dùng, các bài hát tạo bằng chuỗi này giữ giọng gốc rất tốt: giọng hát trong bản hoàn chỉnh gần với người trong mẫu bạn đã tải lên hơn, nên đây là con đường chúng tôi hiện khuyến nghị cho khách hàng.

So sánh: API nhân bản giọng nói và tạo nhạc với giọng chỉ định trước đây vẫn hoạt động, nhưng menu đánh dấu "không khuyến nghị" và không còn được khuyến nghị cho tích hợp mới.

Lưu ý: tài liệu này chỉ mô tả các endpoint bạn cần gọi. Việc xử lý tư liệu, lập lịch tác vụ và kiểm tra nội dung do máy chủ tự làm; phía client không phải triển khai.


0. Bắt đầu trong năm phút

Bốn bước là đủ để từ một mẫu giọng có hai bài hát hoàn chỉnh.

① Tạo giọng     POST /api/music/voice-profile/create      → nhận voice_id (status=ready)
② Cover          POST /api/music/voice-profile/cover       → nhận ngay 2 song_id
③ Theo dõi       POST /api/music/query                     → thăm dò tới status=completed
④ Tải về         GET  /api/music/download?song_id=…&kind=mp3

Ví dụ tối thiểu (curl):

API_KEY="sk-khoa-cua-ban"
BASE="https://www.suno-api.io"

# ① Tạo giọng (tải lên một mẫu giọng; nên từ 10 giây trở lên, dưới 10 MB)
curl -sS -X POST "$BASE/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@./my-voice.mp3" \
  -F "title=Giong cua toi" \
  -F "source_kind=upload"
# → {"success":true,"message":"","data":{"voice_id":"vp_2026…","status":"ready", …}}

# ② Cover một bài bằng giọng này (song_clip_id = clip id của bài cần cover)
curl -sS -X POST "$BASE/api/music/voice-profile/cover" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Create-Ui-Client-Request-Id: cover-$(date +%s)" \
  -H "Content-Type: application/json" \
  -d '{
        "model": "suno-v6",
        "voice_id": "vp_2026…",
        "song_clip_id": "5b773e9a-…",
        "lyrics": "[Verse 1]\nloi bai hat…",
        "style_requirements": "folk cham, guitar acoustic",
        "audio_weight": 0.85,
        "max_mode": false
      }'
# → {"code":200,"message":"success","data":{"resolved_scene":"cover","clips":[{…},{…}]}}

# ③ Thăm dò (nhiều id một lần, phân tách bằng dấu phẩy)
curl -sS -X POST "$BASE/api/music/query" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"suno-v6","song_ids":"id1,id2"}'

# ④ Tải mp3 sau khi xong (chỉ khi status=completed mới có tệp)
curl -sS -L "$BASE/api/music/download?song_id=id1&kind=mp3" \
  -H "Authorization: Bearer $API_KEY" -o song1.mp3

1. Quy ước chung

1.1 Tên miền và môi trường

Môi trường Base URL Mục đích
Production https://www.suno-api.io Lưu lượng khách hàng thật

Mọi đường dẫn dưới đây là tương đối so với Base URL; ví dụ địa chỉ đầy đủ của POST /api/music/voice-profile/create là https://www.suno-api.io/api/music/voice-profile/create.

1.2 Xác thực

Mọi endpoint dùng cùng một header yêu cầu, giá trị là API Key bạn tạo trong bảng điều khiển:

Authorization: Bearer sk-xxxxxxxx

1.3 Định dạng thân yêu cầu

1.4 Hai lớp vỏ phản hồi (khách hàng chỉ cần biết hai loại này)

Các endpoint "quản lý giọng" (create / create-from-clip / list / detail / delete) dùng vỏ nghiệp vụ:

{ "success": true, "message": "", "data": { } }
{ "success": false, "message": "voice_id is required" }

"Cover bằng giọng" đi qua kênh tạo nhạc và dùng vỏ tạo nhạc: thành công là code/message/data, thất bại là đối tượng error:

{ "code": 200, "message": "success", "data": { } }
{ "error": { "message": "voice not found: vp_xxx", "type": "bad_response_status_code", "param": "", "code": "bad_response_status_code" } }

Cách xác định: xem mã trạng thái HTTP trước, rồi success === false, cuối cùng là code !== 200 hoặc có error. Lỗi nghiệp vụ không bảo đảm HTTP khác 200 (endpoint quản lý giọng khi lỗi vẫn trả HTTP 200), nên không thể chỉ nhìn mã trạng thái.

1.5 Tính bất biến (idempotency)

Tạo giọng (bao gồm "tạo từ audio có sẵn") thực sự bất biến: cùng một khóa, gửi lại cùng client_request_id chỉ tạo một giọng, lần thứ hai trả thẳng kết quả lần đầu (success=true, cùng voice_id). Cách dùng là client tự sinh một id (ví dụ UUID) và dùng lại giá trị đó khi thử lại sau khi hết thời gian chờ.

Gửi cover không khử trùng lặp ở cấp yêu cầu (đây là một lần tạo nhạc có tính phí), nên chú ý hai điểm:

  1. Định danh gửi nằm ở header X-Create-Ui-Client-Request-Id: <id gui cua ban>. Nó được ghi vào bản ghi tác vụ phía máy chủ để tiện tra cứu sau này; nó không ngăn việc trừ tiền hai lần.
  2. Hết thời gian chờ ≠ thất bại: yêu cầu có thể đã được nhận và đang tạo. Trước khi thử lại, hãy kiểm tra bằng GET /api/music/songs?p=1&page_size=20 (tham số phân trang là p / page_size; cách viết tương thích ps cũng được) xem đã xuất hiện bài mới với generation_type=voice_profile_cover chưa, và chỉ gửi lại cùng yêu cầu nếu chưa có.

Thân của create và create-from-clip cũng nhận trường client_request_id (xem §3 và §4).

1.6 Tổng quan tính phí

Hành động Endpoint Giá Ghi chú
Tạo giọng (thường) POST /api/music/voice-profile/create Miễn phí Tải mẫu lên không tiêu hạn mức Suno
Tạo giọng (từ audio có sẵn) POST /api/music/voice-profile/create-from-clip Miễn phí Máy chủ chỉ đăng ký tham chiếu tư liệu, không tải lại
Nhân bản tăng cường Như trên, enhanced=true Theo "giá tải lên tăng cường" (mặc định 10 ¥ mỗi lần) Bất đồng bộ; thất bại tự động hoàn tiền
Cover bằng giọng POST /api/music/voice-profile/cover 1,2 ¥ mỗi lần; 2,4 ¥ mỗi lần khi max_mode=true Một lần trả 2 bài
Truy vấn / danh sách / chi tiết / xóa — Miễn phí
Tải xuống (tự lấy liên kết trực tiếp) audio_url trong phản hồi Miễn phí Phát địa chỉ được cấp
Tải xuống (chuyển wav / lời bài hát, v.v.) POST /api/music/free2 0,2 ¥ mỗi bài thành công Xem §8

Giá có thể đọc bất cứ lúc nào từ một endpoint công khai, nên đừng ghi cứng (xem §9):

curl -sS https://www.suno-api.io/api/pricing/catalog | jq '.data.catalog.meta'
# {
#   "generation_price": "0.6",
#   "voice_generation_price": "1.2",      ← giá cơ bản của cover bằng giọng
#   "max_mode_factor": "2",
#   "enhanced_upload_price": "10",        ← giá nhân bản tăng cường
#   "voice_auto_verify_price": "5",
#   "voice_long_term_clone_price": "5"
# }

Cover dùng trừ trước + hoàn tiền khi thất bại:

1.7 Từ điển trạng thái

status của giọng:

Giá trị Ý nghĩa Dùng để cover được
ready Sẵn sàng ✅
processing Chỉ xuất hiện ở nhân bản tăng cường (enhanced=true); đang xử lý ❌ (chờ ready)
failed Tạo thất bại; xem error_message; nhân bản tăng cường đã hoàn tiền ❌

status của bài hát (giá trị các endpoint truy vấn trả về):

Giá trị Ý nghĩa Tải được
submitted / queued / processing Đang tạo (có thể đã có luồng nghe thử) ❌
completed Xong ✅
failed Thất bại; phí đã hoàn ❌

2. Tổng quan endpoint

# Phương thức Đường dẫn Vai trò Tính phí
1 POST /api/music/voice-profile/create Tạo giọng (tải lên / URL / base64) Miễn phí (trừ enhanced=true)
2 POST /api/music/voice-profile/create-from-clip Tạo giọng từ audio bạn đã có Miễn phí
3 GET /api/music/voice-profile/list Danh sách giọng Miễn phí
4 GET /api/music/voice-profile/{voice_id} Chi tiết giọng (gồm tiến độ nhân bản tăng cường) Miễn phí
5 POST /api/music/voice-profile/delete Xóa giọng Miễn phí
6 POST /api/music/voice-profile/cover Cover bằng giọng / hát bài mới 1,2 ¥ (MAX 2,4)
7 POST /api/music/query Truy vấn trạng thái bài hát theo lô Miễn phí
8 GET /api/music/songs/{song_id} Chi tiết một bài Miễn phí
9 GET /api/music/download Tải tệp hoàn chỉnh Miễn phí (mp3/liên kết phát)
10 POST /api/music/free2 Chuyển wav / lấy lời, v.v. 0,2 ¥ mỗi bài thành công
11 POST /api/music/free2/cached Lấy địa chỉ tải đã lưu trữ Miễn phí
12 GET /api/music/songs Danh sách tác phẩm của tôi, có phân trang Miễn phí

3. Tạo giọng

POST /api/music/voice-profile/create

Đăng ký một đoạn audio giọng hát thành "giọng" và nhận voice_id. Với nền tảng, một giọng chỉ là "một đoạn audio + clip của nó trong kho", nên sau khi tạo thành công đoạn audio nguồn đó được giữ vĩnh viễn (cho các cover sau).

3.1 Ba dạng đầu vào (chọn một)

Dạng A: tải tệp multipart (khuyến nghị)

Content-Type: multipart/form-data

file=<du lieu nhi phan audio>   # bat buoc
title=<ten giong>               # tuy chon; de trong thi lay ten tep bo phan mo rong
file_name=<ten tep goc>
source_file_name=<ten tep goc>
source_kind=upload|record       # tuy chon, danh dau nguon (tai len / ghi am); mac dinh upload
enhanced=false|true             # tuy chon, true = nhan ban tang cuong (xem §3.5)
client_request_id=<khoa idempotency>   # tuy chon
voice_id=<ID tu chon>           # tuy chon, it dung
curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@./my-voice.mp3;type=audio/mpeg" \
  -F "file_name=my-voice.mp3" \
  -F "source_file_name=my-voice.mp3" \
  -F "title=Giong cua toi" \
  -F "source_kind=upload"

Dạng B: JSON + URL audio công khai

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "file_url": "https://your-cdn.example.com/voice/my-voice.mp3",
        "file_name": "my-voice.mp3",
        "title": "Giong cua toi"
      }'

Dạng C: JSON + base64

{
  "file_base64": "data:audio/mpeg;base64,//uQxAAA…",
  "file_name": "my-voice.mp3",
  "title": "Giong cua toi"
}

3.2 Yêu cầu về audio

Mục Yêu cầu Ghi chú
Kích thước ≤ 10 MB Vượt hạn mức, gateway sẽ cắt thân yêu cầu, biểu hiện là "bị Suno từ chối"; hãy nén hoặc cắt ngắn trước
Thời lượng Ít nhất 6 giây; nên 10–60 giây Dưới 6 giây nền tảng từ chối: Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds.
Định dạng mp3 / wav / m4a / aac / flac / ogg Xác định theo phần mở rộng tệp
Nội dung Giọng hát sạch; tránh bản cover hoàn chỉnh hoặc bản gốc có nhạc đệm Audio rất giống một bản ghi có sẵn trong kho sẽ bị từ chối: This audio matches an existing recording in our catalog. (đo được)

3.3 Phản hồi

{
  "success": true,
  "message": "",
  "data": {
    "voice_id": "vp_20260926080618509168500DXXrxe",
    "clip_id": "91cc5935-389f-4193-b56b-cc796c15562d",
    "song_id": "91cc5935-389f-4193-b56b-cc796c15562d",
    "account_id": "acc_1790085275308",
    "title": "Giong cua toi",
    "source_file_name": "my-voice.mp3",
    "audio_url": "https://suno-api-p-1437223057.cos.ap-guangzhou.myqcloud.com/create-ui/voice-source/2026/09/26/xxx.mp3",
    "image_url": "https://cdn2.suno.ai/image_91cc5935-389f-4193-b56b-cc796c15562d.jpeg",
    "duration_s": 29.18,
    "enhanced": false,
    "source_kind": "upload",
    "status": "ready",
    "client_request_id": "",
    "created_at": 1790409978,
    "updated_at": 1790409998
  }
}

Mô tả trường (create / list / detail dùng chung một bộ trường):

Trường Kiểu Ghi chú
voice_id string ID giọng; các cover sau dùng nó
clip_id / song_id string clip id của audio giọng đó phía Suno (hai giá trị như nhau); để tra cứu
account_id string Định danh tài khoản đảm nhiệm (để tra cứu; client không cần bận tâm)
title string Tên giọng
source_file_name string Tên tệp gốc
audio_url string Liên kết trực tiếp dài hạn tới audio nguồn, dùng để nghe thử; giữ vĩnh viễn
image_url string Ảnh bìa giọng (Suno tạo cho audio giọng hát); khi không có bìa thì khóa này hoàn toàn không xuất hiện
duration_s number Độ dài mẫu giọng, tính bằng giây
enhanced bool Có tạo bằng nhân bản tăng cường không
source_kind string upload / record / clip (lấy từ audio có sẵn)
status string ready / processing / failed
error_message string Nguyên nhân thất bại; chỉ có khi failed
task_id number Số tác vụ nền của nhân bản tăng cường; chỉ có giá trị khi enhanced=true
pre_consumed_quota number Hạn mức trừ trước (chỉ có ở nhân bản tăng cường)
created_at / updated_at number Giây Unix

created_at / updated_at là mốc thời gian giây (10 chữ số), không phải mili giây.

3.4 Lỗi thường gặp

HTTP message Nguyên nhân và cách xử lý
200 one of file_path, file_base64, or file_url is required Không kèm nội dung audio
200 Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. Mẫu quá ngắn; dùng ≥6 giây (nên ≥10 giây)
200 This audio matches an existing recording in our catalog. Mẫu rất giống bản ghi có sẵn trong kho; dùng một đoạn giọng khô sạch khác
200 upload succeeded without clip or account identity Phản hồi nền tảng bất thường; thử lại
200 audio file exceeds 30 MB limit Vượt hạn mức máy chủ (phía khách hàng hãy giữ trong 10 MB)
401 invalid token Sai API Key

3.5 Nhân bản tăng cường (enhanced=true)

Dùng cho trường hợp "bản thân mẫu giọng có lời bản quyền / cần tải lên tăng cường". Giá theo giá tải lên tăng cường (mặc định 10 ¥ mỗi lần, thất bại tự động hoàn tiền):

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@./my-voice.mp3" -F "title=Giong cua toi" -F "enhanced=true"

4. Tạo giọng từ audio có sẵn

Nếu không muốn tải lại: sao chép thẳng một đoạn audio bạn đã tải lên hoặc đã tạo thành giọng. Miễn phí và bất biến.

POST /api/music/voice-profile/create-from-clip
Content-Type: application/json

{
  "source_song_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
  "title": "Xu Qing Qiang",
  "client_request_id": "vp-clip-1789…"
}

Phản hồi là toàn bộ trường trong §3.3 cộng hai trường chỉ đọc:

Trường Ghi chú
reused true = audio này đã là giọng của bạn và được dùng lại
source_type Nguồn của audio: generate / custom_generate / voice_generate / upload_source / enhanced_upload
{
  "success": true,
  "data": {
    "voice_id": "vp_20260926081712557959800Z5gvlt",
    "clip_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
    "title": "Xu Qing Qiang",
    "status": "ready",
    "enhanced": true,
    "reused": true,
    "source_type": "enhanced_upload"
  }
}

Lỗi (message nguyên văn; nên hiển thị trực tiếp hoặc bản địa hóa):

message Ý nghĩa
source audio not found Clip không tồn tại hoặc không thuộc bạn
source audio is invalid Audio đó vẫn đang tạo / là sản phẩm trung gian, chưa dùng được
source_song_id is required Chưa gửi source_song_id

5. Danh sách / chi tiết / xóa giọng

5.1 Danh sách

GET /api/music/voice-profile/list
GET /api/music/voice-profile/list?include_deleted=true
{
  "success": true,
  "message": "",
  "data": {
    "items": [ { "voice_id": "vp_…", "title": "Giong cua toi", "status": "ready", "audio_url": "…", "image_url": "…" } ],
    "total": 1
  }
}

Các trường hoàn toàn giống §3.3. Mặc định không trả về giọng đã xóa.

5.2 Chi tiết

GET /api/music/voice-profile/{voice_id}

Trả về một đối tượng giọng (data là chính đối tượng, không phải mảng). Khi nhân bản tăng cường đang chạy, có thêm:

Trường Ghi chú
progress_percent Số nguyên từ 0 đến 100
progress_stage Mã giai đoạn, ví dụ media_preparing
progress_message Câu chữ tiến độ để hiển thị cho người dùng

5.3 Xóa

POST /api/music/voice-profile/delete
Content-Type: application/json

{ "voice_id": "vp_2026…" }
{ "success": true, "message": "", "data": { "voice_id": "vp_2026…", "status": "deleted" } }

6. Cover bằng giọng (endpoint cốt lõi)

POST /api/music/voice-profile/cover
Content-Type: application/json

Một lần gửi tạo 2 bài (giống tạo nhạc thường).

6.1 Hai tình huống

Tình huống Điều kiện Ghi chú
A. Cover một bài đã chọn Đã gửi song_clip_id Hát bài đó bằng giọng của bạn (giai điệu / nhịp / cấu trúc theo bản gốc; giọng hát thành giọng của bạn)
B. Hát bài mới bằng giọng Không gửi song_clip_id Chỉ đưa giọng + lời (tùy chọn) + yêu cầu phong cách; mô hình sáng tác giai điệu mới theo phong cách đó rồi hát

resolved_scene trong phản hồi trả cover hoặc sing, để bạn xác nhận đã đi đường nào.

6.2 Trường yêu cầu

Trường Kiểu Bắt buộc Mặc định Ghi chú
model string Có — Tên mô hình cho khách hàng, xem §6.5. Không gửi sẽ báo model is required (HTTP 500)
voice_id string Một trong hai — ID giọng (vp_…); phải status=ready
voice_clip_id string Một trong hai — Cũng có thể dùng clip id của giọng; nếu gửi cả hai thì voice_id được ưu tiên
song_clip_id string Không rỗng Clip id (song_id) của bài cần cover. Không gửi = tình huống B
lyrics string Không rỗng Toàn bộ lời, gửi từng ký tự, không viết lại hay cắt bớt; ≤ 3000 ký tự
cover_requirements string Không rỗng Yêu cầu cover bằng ngôn ngữ tự nhiên, ví dụ "nhả chữ rõ hơn". Chúng được ghép vào prompt cố định
style_requirements string Không rỗng Yêu cầu phong cách, ví dụ "folk chậm, guitar acoustic"
title string Không rỗng Tiêu đề của hai bài này trong không gian làm việc (ảnh hưởng song_title trả về ở các truy vấn sau)
negative_tags string Không rỗng Phong cách loại trừ, ví dụ electronic, rap; ≤ 1000 ký tự
vocal_gender string Không rỗng m / f (cũng nhận male / female); rỗng = không giới hạn
duration number Không rỗng Độ dài mong muốn tính bằng giây, số nguyên 1–480; rỗng = nền tảng tự quyết. Thực tế tối thiểu của nền tảng khoảng 30 giây: nhập giá trị nhỏ hơn thì đo đạc vẫn cho ra bài khoảng 30 giây
audio_weight number Không 0,85 Audio Influence, số thập phân 0–1. Càng cao càng bám mẫu giọng
style_weight number Không rỗng Ảnh hưởng phong cách, số thập phân 0–1
weirdness_constraint number Không rỗng Độ sáng tạo, số thập phân 0–1 (nếu giao diện dùng phần trăm thì chia cho 100)
variety number Không rỗng Độ đa dạng, số nguyên 0–4 (không phải phần trăm), chỉ hỗ trợ ở dòng v6
max_mode boolean Không false Max Mode, giá ×2
client_request_id string Không rỗng Định danh gửi, ghi vào bản ghi tác vụ phía máy chủ để tra cứu (không khử trùng lặp)

Nên gửi kèm header X-Create-Ui-Client-Request-Id: <cung id gui do>: chỉ nó mới được ghi vào bản ghi tác vụ phía máy chủ và là khóa chính để tra cứu sau này (xem §1.5).

Lưu ý đơn vị: audio_weight / style_weight / weirdness_constraint là số thập phân 0–1, variety là số nguyên 0–4, duration là giây. Dùng lẫn sẽ bị từ chối hoặc cho kết quả bất thường.

Lời là tùy chọn trong tình huống B (mô hình tự xử lý), nhưng khi cần hát nội dung cụ thể hãy nhớ gửi lyrics.

6.3 Phản hồi

{
  "code": 200,
  "message": "success",
  "data": {
    "voice_id": "vp_20260926081712557959800Z5gvlt",
    "voice_clip_id": "97ee62fe-56cd-473f-a2f5-c66ac0766a2e",
    "song_clip_id": "5b773e9a-a035-4134-a4a4-29c9961d3ccb",
    "resolved_scene": "cover",
    "model": "suno-v6",
    "audio_weight": 0.85,
    "clips": [
      {
        "song_id": "0f2a…",
        "status": "processing",
        "song_title": "",
        "model_version": "suno-v6",
        "audio_url": "",
        "play_url": "https://media.suno-api.io/play/0f2a…?expires=…&signature=…",
        "lyrics": "",
        "description": "[Tac vu] Day la mot ban cover. … (phan cau truc co dinh cua may chu + yeu cau cover / phong cach ban dien)"
      },
      {
        "song_id": "7c91…",
        "status": "processing",
        "model_version": "suno-v6",
        "audio_url": ""
      }
    ],
    "source_updates": []
  }
}

Điểm chính:

  1. Định danh bản hoàn chỉnh bằng clips[].song_id (endpoint này không trả trường id).
  2. Nhận ngay 2 giá trị song_id, lúc này status vẫn là processing (chỉ nghĩa là đã nhận) và audio_url trống; phải thăm dò tới completed mới tải được. play_url là luồng nghe thử của nền tảng, có thể xuất hiện ngay khi gửi và sẽ hết hạn.
  3. description là prompt máy chủ gửi cuối cùng (phần cấu trúc cố định + cover_requirements / style_requirements bạn điền); rất hữu ích khi tra cứu kết quả.
  4. source_updates là kết quả xử lý tư liệu của máy chủ, client có thể bỏ qua.
  5. title bạn gửi được ghi vào bản ghi tác vụ phía máy chủ và thể hiện thành song_title ở các truy vấn sau; việc clips[].song_title trong phản hồi gửi thường trống là bình thường.

6.4 Lỗi

{ "error": { "message": "giong nay khong ton tai hoac da bi xoa (voice_id=vp_xxx)…", "type": "new_api_error", "param": "", "code": "invalid_request" } }
HTTP message Nguyên nhân
500 model is required Thân thiếu model (trường bắt buộc để chọn kênh)
400 voice_id is required and must be a ready voice Chưa gửi voice_id, hoặc gửi giá trị chỗ giữ chỗ / giọng chưa sẵn sàng
400 giong nay khong ton tai hoac da bi xoa (voice_id=vp_xxx)… Giọng đã bị xóa, không tồn tại hoặc không thuộc tài khoản hiện tại. Hãy dùng giọng khác đang có hoặc tạo giọng mới
400 giong nay da bi xoa (voice_id=vp_xxx)… Khi truyền tư liệu trực tiếp bằng voice_clip_id, giọng của đoạn tư liệu đó đã bị xóa; xử lý như trên
400 voice is not ready yet (status=processing) Giọng vẫn đang tạo; chờ ready rồi thử lại
400 song_clip_id must be a real completed clip song_clip_id là chỗ giữ chỗ / chưa hoàn tất
400 song_clip_id must differ from the voice clip Đối tượng cover không thể là chính mẫu giọng
400 audio_weight must be a number between 0 and 1 Sai đơn vị thanh trượt (đã gửi phần trăm)
400 duration must be an integer between 1 and 480 seconds Độ dài không phải số nguyên 1–480
400 vocal_gender must be one of m, f, male, female Giá trị giới tính không hợp lệ
400 variety must be an integer between 0 and 4 / variety is only supported on v6 models Giá trị đa dạng không hợp lệ hoặc mô hình không hỗ trợ

Số dư không đủ sẽ trả lỗi tính phí ngay khi gửi và không để lại tác vụ dở dang.

6.5 Mô hình khả dụng (tên cho khách hàng)

Tên mô hình Ghi chú
suno-v6 Mặc định, khuyến nghị
suno-v6-wild Phóng khoáng hơn
suno-v6-mini Nhẹ

Hãy dùng tên mô hình cho khách hàng (như trên). chirp-* là tên nội bộ của nền tảng, không dùng trực tiếp.


7. Theo dõi tiến độ

7.1 Truy vấn theo lô (khuyến nghị)

POST /api/music/query
Content-Type: application/json

{ "model": "suno-v6", "song_ids": "id1,id2" }
[
  {
    "song_id": "0f2a…",
    "song_title": "Hai con ho",
    "status": "completed",
    "audio_url": "https://suno-api-hk-1437223057.cos.ap-hongkong.myqcloud.com/assets/0f2a…-mp3.mp3",
    "cover_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
    "duration": 115.15,
    "model_version": "suno-v6",
    "generation_type": "voice_profile_cover",
    "play_url": "https://media.suno-api.io/play/…?expires=…&signature=…",
    "lyrics": "[Verse 1]…",
    "prompt": "[Verse 1]…",
    "description": "[Tac vu] Day la mot ban cover. … (prompt cuoi cung cua may chu)",
    "style_tags": "…",
    "created_at": "2026-09-25T18:19:09.918Z",
    "video_url": ""
  }
]
Trường Ghi chú
status Xem §1.7; chỉ completed mới tính là xong
audio_url Liên kết trực tiếp mp3; chỉ có giá trị từ completed
cover_url Địa chỉ ảnh bìa
duration Độ dài thực tế tính bằng giây
generation_type Bài do cover bằng giọng luôn là voice_profile_cover
play_url Địa chỉ nghe thử có chữ ký (sẽ hết hạn)
song_title Tiêu đề tác vụ (title bạn gửi; không gửi thì máy chủ đặt mặc định)
lyrics / prompt Lời hoàn chỉnh / lời gốc
description Prompt cuối cùng máy chủ gửi (gồm phần cấu trúc cố định)
style_tags Mô tả phong cách cuối cùng
created_at Chuỗi ISO 8601 (lưu ý khác giây Unix của endpoint chi tiết)

Gợi ý thăm dò: cách 5–10 giây, tổng thời gian chờ 10–15 phút (tài khoản "nguội" chậm nhất đo được khoảng 4 phút rưỡi; rất ít trường hợp lâu hơn). Đừng dựa vào audio_url trống để phán đoán hoàn tất, hãy dùng status.

Ghi chú tương thích: endpoint này định danh bài bằng song_id; một vài phản hồi ban đầu có trường id, nên row.song_id || row.id là cách đọc an toàn.

7.2 Chi tiết một bài

GET /api/music/songs/{song_id}
{
  "success": true,
  "data": {
    "song_id": "0f2a…",
    "title": "Hai con ho",
    "status": "completed",
    "generation_type": "voice_profile_cover",
    "model": "suno-v6",
    "duration": 115.15,
    "audio_url": "https://…/assets/0f2a…-mp3.mp3",
    "image_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
    "wav_url": "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=wav",
    "video_url": "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=video",
    "created_at": 1790411012,
    "completed_at": 1790411500,
    "parameters": {
      "prompt": "[Verse 1]…",
      "style_tags": "…",
      "title": "Hai con ho",
      "model": "suno-v6",
      "generation_type": "voice_profile_cover",
      "source_song_id": "5b773e9a-…"
    },
    "parameter_retention": {
      "core_parameters_available": true,
      "extended_parameters_available": false,
      "sources": ["suno_tasks"],
      "unavailable_fields": ["negative_tags", "vocal_gender", "style_weight", "weirdness_constraint"]
    }
  }
}

7.3 Tác phẩm của tôi

GET /api/music/songs?p=1&page_size=20
GET /api/music/songs?status=completed&q=tu khoa

Tham số phân trang: p (số trang, bắt đầu từ 1) / page_size (số mục mỗi trang; cách viết tương thích ps). Tùy chọn status, q (từ khóa tiêu đề). Mặc định sắp xếp theo thời gian tạo giảm dần.

{
  "success": true,
  "data": {
    "page": 1,
    "page_size": 20,
    "total": 42,
    "items": [
      {
        "song_id": "0f2a…",
        "title": "Hai con ho",
        "status": "completed",
        "generation_type": "voice_profile_cover",
        "model": "suno-v6",
        "duration": 115.15,
        "audio_url": "https://…/assets/0f2a…-mp3.mp3",
        "image_url": "https://cdn2.suno.ai/image_0f2a….jpeg",
        "created_at": 1790411012,
        "completed_at": 1790411500
      }
    ]
  }
}

Dùng generation_type=voice_profile_cover để phân biệt "bài do cover bằng giọng tạo ra" với các kết quả tạo nhạc khác.


8. Tải bài hoàn chỉnh

8.1 Lấy mp3 trực tiếp (khuyến nghị, miễn phí)

Cả ba cách đều được; chọn một:

  1. Dùng audio_url trong kết quả truy vấn (liên kết trực tiếp tới kho đối tượng, gọn nhất).
  2. GET /api/music/download?song_id=<id>&kind=mp3 → trả thẳng luồng byte audio (tên tệp đã có trong Content-Disposition).
  3. POST /api/music/download-url (lấy địa chỉ tạm có chữ ký).
curl -sS -L "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=mp3" \
  -H "Authorization: Bearer $API_KEY" -o song.mp3

Giá trị kind: mp3 (tương đương song) / playback (phát theo luồng) / wav / video / lyrics / timestamped_lyrics. timestamped_lyrics (.lrc) hiện chỉ hỗ trợ một số bài; khi thất bại hãy tự tạo tệp bằng API lời có mốc thời gian. Phản hồi là luồng byte tệp, Content-Type và Content-Disposition (tên tệp) đã sẵn; wav_url / video_url do GET /api/music/songs/{song_id} trả về chính là cùng đầu vào đó với kind=wav|video.

8.2 Chuyển wav / lấy lời / siêu dữ liệu (có phí)

POST /api/music/free2
Content-Type: application/json

{ "song_ids": ["0f2a…"], "files": ["mp3", "wav", "lyrics"] }
{
  "success": true,
  "data": {
    "songs": [
      { "song_id": "0f2a…", "files": [ { "type": "mp3", "url": "https://…" }, { "type": "wav", "url": "https://…" } ] }
    ],
    "requested_songs": 1,
    "succeeded_songs": 1,
    "price": 0.2
  }
}

9. Tra cứu giá

GET /api/pricing/catalog

Endpoint công khai, không cần xác thực. Mọi đơn giá cần hiển thị cho khách hàng đều nằm trong data.catalog.meta (chuỗi):

Khóa Ý nghĩa Giá trị hiện tại
generation_price Tạo nhạc thường 0,6
voice_generation_price Giá cơ bản của cover bằng giọng 1,2
max_mode_factor Hệ số Max Mode 2
enhanced_upload_price Nhân bản tăng cường / tải lên tăng cường 10
voice_auto_verify_price Tự động xác minh giọng 5
voice_long_term_clone_price Nhân bản giọng dài hạn 5

Giá được điều chỉnh ở back-office, nên đọc theo thời gian thực thay vì ghi cứng trong client. Phí cover thực tế = voice_generation_price × (nếu max_mode đúng thì nhân thêm max_mode_factor).


10. Giới hạn và lưu ý

  1. Kích thước tải lên: ≤ 10 MB (máy chủ nhận nhiều hơn, nhưng gateway đầu vào cắt thân yêu cầu quá lớn ở 10 MiB, biểu hiện là "bị Suno từ chối"; hãy chặn trước ở phía bạn).
  2. Độ dài mẫu: ít nhất 6 giây, nên 10–60 giây; quá ngắn sẽ bị nền tảng từ chối.
  3. Nội dung mẫu: giọng sạch; tránh những gì rất giống bản ghi có sẵn (so khớp kho sẽ từ chối).
  4. Giới hạn văn bản: lyrics ≤ 3000 ký tự; style_requirements / negative_tags / title nên trong 1000 / 1000 / 100 ký tự (yêu cầu phong cách và cover được ghép vào prompt, hãy giữ tổng dưới 3000 ký tự).
  5. Lời không bị viết lại: gửi gì hát nấy (từng ký tự), không cắt cục bộ.
  6. Mỗi bài luôn cho 2 bản; đừng giả định chỉ một kết quả.
  7. Audio nguồn được giữ vĩnh viễn: xóa giọng không dọn audio nguồn; điều này giữ các cover sau khả thi và việc tuân thủ có thể truy vết.
  8. Giọng phải ready: giọng ở trạng thái processing không dùng được để cover.
  9. Thời gian chờ yêu cầu: với tài khoản "nguội", lần gửi đầu đo được tới khoảng 4 phút rưỡi, nên đặt thời gian chờ của client ≥ 6 phút. Cover không khử trùng lặp ở cấp yêu cầu, nên sau khi hết thời gian chờ hãy kiểm tra xem đã có bài mới chưa (§1.5) rồi mới quyết định gửi lại.
  10. Quyền sở hữu giọng: giọng thuộc về người tạo; cover chỉ nhận giọng đã sẵn sàng và chưa bị xóa. Giọng không tồn tại, đã xóa hoặc thuộc tài khoản khác đều trả 400: giong nay khong ton tai hoac da bi xoa (voice_id=…).

11. Câu hỏi thường gặp (FAQ)

H1. Tạo giọng có tốn tiền không? Tạo thường và "tạo từ audio có sẵn" đều miễn phí; chỉ cover (1,2 ¥ / MAX 2,4 ¥) và nhân bản tăng cường (mặc định 10 ¥) mới tính phí.

H2. Có dùng bài hoàn chỉnh có nhạc đệm làm mẫu giọng được không? Không nên. Bất cứ thứ gì có nhạc, hoặc rất giống bản ghi có sẵn trong kho, đều bị nền tảng từ chối (This audio matches an existing recording in our catalog.). Hãy dùng bản ghi thuần giọng, khô.

H3. Vì sao sau khi gửi cover, audio_url trống? Gửi chỉ nghĩa là đã được nhận và status vẫn là processing. Địa chỉ phát được/tải được chỉ xuất hiện sau khi bạn thăm dò /api/music/query tới status=completed.

H4. Tình huống B (không gửi song_clip_id) có cần gửi lời không? Tùy chọn. Gửi lyrics khi cần hát nội dung cụ thể; không gửi thì mô hình tự xử lý nhưng khó kiểm soát hơn.

H5. Audio khách hàng tự tải lên có dùng thẳng làm giọng được không? Được: dùng dạng file_url của create, hoặc tải lên thành bài hát trước rồi gọi create-from-clip.

H6. Thất bại có hoàn tiền không? Yêu cầu bị từ chối thẳng (sai tham số / nền tảng báo lỗi) theo đo đạc không bị trừ tiền; tác vụ đã nhận nhưng cuối cùng thất bại sẽ hoàn lại số đã trừ trước. Khi thất bại ở trạng thái cuối, tác vụ trả status=failed và error_message.

H7. Sau khi xóa giọng, các bài tạo bằng nó còn nghe được không? Được. Việc xóa chỉ ảnh hưởng khả năng dùng giọng đó cho cover mới.

H8. Một lần cover được bài dài bao nhiêu? duration nhận 1–480 giây; không gửi thì nền tảng tự quyết theo bản gốc / tư liệu. Lưu ý bản hoàn chỉnh của nền tảng tối thiểu khoảng 30 giây: nhập giá trị nhỏ hơn 30 giây thì đo đạc vẫn ra 29,96 / 29,76 giây.


Phụ lục A: ví dụ đầy đủ (Node.js, có thăm dò và tải xuống)

const BASE = "https://www.suno-api.io";
const KEY = process.env.SUNO_API_KEY;
const H = { Authorization: `Bearer ${KEY}` };

// ① Tạo giọng (multipart)
async function createVoice(filePath, title) {
  const fd = new FormData();
  fd.set("file", new Blob([await (await import("node:fs/promises")).readFile(filePath)], { type: "audio/mpeg" }), "my-voice.mp3");
  fd.set("file_name", "my-voice.mp3");
  fd.set("source_file_name", "my-voice.mp3");
  fd.set("title", title);
  fd.set("client_request_id", `vp-create-${Date.now()}`);
  const res = await fetch(`${BASE}/api/music/voice-profile/create`, { method: "POST", headers: H, body: fd });
  const body = await res.json();
  if (!body.success) throw new Error(body.message);
  return body.data; // { voice_id, status, audio_url, ... }
}

// ② Cover
async function cover(voiceId, songClipId, lyrics) {
  const submissionId = `vp-cover-${Date.now()}`;
  const res = await fetch(`${BASE}/api/music/voice-profile/cover`, {
    method: "POST",
    headers: { ...H, "Content-Type": "application/json", "X-Create-Ui-Client-Request-Id": submissionId },
    body: JSON.stringify({
      model: "suno-v6",
      voice_id: voiceId,
      song_clip_id: songClipId || "",
      lyrics: lyrics || "",
      style_requirements: "folk cham, guitar acoustic",
      audio_weight: 0.85,
      max_mode: false,
      client_request_id: submissionId,
    }),
  });
  const body = await res.json();
  if (body.error) throw new Error(body.error.message);
  return body.data; // { resolved_scene, clips: [{ song_id, status }] }
}

// ③ Thăm dò tới khi xong (5 giây một lần, tối đa 15 phút)
async function waitUntilCompleted(songIds) {
  const deadline = Date.now() + 15 * 60 * 1000;
  while (Date.now() < deadline) {
    const res = await fetch(`${BASE}/api/music/query`, {
      method: "POST",
      headers: { ...H, "Content-Type": "application/json" },
      body: JSON.stringify({ model: "suno-v6", song_ids: songIds.join(",") }),
    });
    const songs = await res.json(); // mang tran
    if (songs.every((s) => s.status === "completed" || s.status === "failed")) return songs;
    await new Promise((r) => setTimeout(r, 5000));
  }
  throw new Error("timeout waiting for cover");
}

// ④ Tải xuống
async function download(songId, outPath) {
  const res = await fetch(`${BASE}/api/music/download?song_id=${encodeURIComponent(songId)}&kind=mp3`, { headers: H });
  if (!res.ok) throw new Error(`download failed: ${res.status}`);
  (await import("node:fs/promises")).writeFile(outPath, Buffer.from(await res.arrayBuffer()));
}

const voice = await createVoice("./my-voice.mp3", "Giong cua toi");
const result = await cover(voice.voice_id, "5b773e9a-a035-4134-a4a4-29c9961d3ccb", "[Verse 1]\nloi…");
const ids = result.clips.map((c) => c.song_id);
const songs = await waitUntilCompleted(ids);
for (const [i, s] of songs.entries()) {
  if (s.status === "completed") await download(s.song_id, `./out-${i}.mp3`);
}

Phụ lục B: lịch sử thay đổi

Ngày Thay đổi
2026-10-15 Nêu rõ nghĩa của việc xóa (§5.3); cover với voice_id "đã xóa / không có quyền" nay trả 400 trước khi trừ trước, bảng lỗi và FAQ được cập nhật đồng bộ (cùng cổng chặn xóa giọng phát hành hôm đó)
2026-10-13 Bổ sung phần "vì sao khuyến nghị chuỗi này" ở đầu: theo đánh giá thực tế của nhiều người dùng, bài tạo bằng chuỗi này giữ giọng gốc tốt hơn rõ rệt
2026-09-26 Bản đầu: tạo giọng (ba dạng đầu vào) / tạo từ audio có sẵn / danh sách, chi tiết, xóa / cover bằng giọng (tình huống A và B) / truy vấn tiến độ / tải xuống / đọc giá, kèm bằng chứng đo được
Tiếp theoAPI tăng cường phong cách

Lấy khóa API

Tạo khóa API trong bảng điều khiển sau khi đăng ký. Mỗi lần tạo tốn 0,6 ¥ và trả về 2 bản nhạc, tải xuống không giới hạn và không cần số điện thoại.

Lấy khóa API Quay lại tổng quan