【Disarankan】 API profil suara
✅ Jalur ini kami sarankan untuk integrasi baru. Menurut penilaian nyata banyak pengguna, lagu yang dibuat lewat jalur ini mempertahankan suara asli dengan baik: vokal di hasil akhir lebih mirip dengan orang pada sampel yang Anda unggah, jadi inilah jalur yang saat ini kami sarankan ke pelanggan.
Perbandingan: API kloning suara dan pembuatan dengan suara yang ditentukan sebelumnya masih berfungsi, tetapi menu menandainya "tidak disarankan" dan tidak lagi disarankan untuk integrasi baru.
- Tanggal dokumen: 2026-09-26
- Cakupan: membuat suara Anda sendiri → memakainya untuk meng-cover lagu tertentu / menyanyikan lagu baru → memantau kemajuan → mengunduh hasil
- Semua endpoint, field, dan respons diuji dengan pemanggilan nyata (yang ditandai "terukur" diverifikasi secara rinci)
Catatan: dokumen ini hanya menjelaskan endpoint yang Anda panggil. Pemrosesan materi, penjadwalan tugas, dan validasi konten dilakukan otomatis oleh server; klien tidak mengimplementasikannya.
0. Mulai dalam lima menit
Empat langkah cukup untuk mengubah satu sampel vokal menjadi dua lagu jadi.
① Buat suara POST /api/music/voice-profile/create → dapat voice_id (status=ready)
② Cover POST /api/music/voice-profile/cover → langsung dapat 2 song_id
③ Pantau POST /api/music/query → polling sampai status=completed
④ Unduh GET /api/music/download?song_id=…&kind=mp3
Contoh minimal (curl):
API_KEY="sk-kunci-anda"
BASE="https://www.suno-api.io"
# ① Buat suara (unggah sampel vokal; sebaiknya 10 detik atau lebih, di bawah 10 MB)
curl -sS -X POST "$BASE/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@./my-voice.mp3" \
-F "title=Suara saya" \
-F "source_kind=upload"
# → {"success":true,"message":"","data":{"voice_id":"vp_2026…","status":"ready", …}}
# ② Cover satu lagu dengan suara ini (song_clip_id = clip id lagu yang akan di-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]\nlirik…",
"style_requirements": "folk lambat, gitar akustik",
"audio_weight": 0.85,
"max_mode": false
}'
# → {"code":200,"message":"success","data":{"resolved_scene":"cover","clips":[{…},{…}]}}
# ③ Polling (kirim beberapa id sekaligus, dipisah koma)
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"}'
# ④ Unduh mp3 setelah selesai (file hanya ada saat status=completed)
curl -sS -L "$BASE/api/music/download?song_id=id1&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song1.mp3
1. Konvensi umum
1.1 Domain dan lingkungan
| Lingkungan | Base URL | Kegunaan |
|---|---|---|
| Produksi | https://www.suno-api.io |
Lalu lintas pelanggan nyata |
Semua jalur di bawah ini relatif terhadap Base URL; misalnya alamat lengkap POST /api/music/voice-profile/create adalah
https://www.suno-api.io/api/music/voice-profile/create.
1.2 Autentikasi
Semua endpoint memakai header permintaan yang sama, nilainya adalah API Key yang Anda buat di konsol:
Authorization: Bearer sk-xxxxxxxx
- Prefiks
Beareropsional; prefikssk-juga (Authorization: sk-xxxsama-sama berfungsi). - Kunci hilang atau tidak valid → HTTP 401, isi balasan seperti
{"success":false,"message":"…"}(teksnya mengikuti bahasa permintaan). - Setiap kunci hanya dapat melihat dan mengoperasikan lagu serta suara milik akunnya sendiri.
1.3 Format isi permintaan
- Membuat suara: disarankan
multipart/form-data(mengunggah berkas);application/json(URL atau base64) juga didukung. - Endpoint lain:
application/json.
1.4 Dua pembungkus respons (pelanggan hanya perlu mengenal dua ini)
Endpoint "pengelolaan suara" (create / create-from-clip / list / detail / delete) memakai pembungkus bisnis:
{ "success": true, "message": "", "data": { } }
{ "success": false, "message": "voice_id is required" }
"Cover dengan suara" melewati kanal pembuatan dan memakai pembungkus pembuatan: sukses adalah code/message/data, gagal adalah objek error:
{ "code": 200, "message": "success", "data": { } }
{ "error": { "message": "voice not found: vp_xxx", "type": "bad_response_status_code", "param": "", "code": "bad_response_status_code" } }
Cara menilai: lihat kode status HTTP dulu, lalu success === false, terakhir code !== 200 atau ada error.
Kegagalan bisnis tidak menjamin HTTP selain 200 (endpoint pengelolaan suara tetap HTTP 200 saat error), jadi jangan hanya melihat kode status.
1.5 Idempotensi
Membuat suara (termasuk "buat dari audio yang sudah ada") benar-benar idempoten: di bawah kunci yang sama, mengirim ulang client_request_id yang sama hanya membuat satu suara dan percobaan kedua langsung mengembalikan hasil pertama (success=true, voice_id yang sama). Pola pakainya: klien membuat id sendiri (misalnya UUID) dan memakai nilai yang sama saat mencoba ulang setelah timeout.
Pengiriman cover tidak melakukan deduplikasi tingkat permintaan (ini pembuatan berbayar), jadi perhatikan dua hal:
- Identitas pengiriman ada di header
X-Create-Ui-Client-Request-Id: <id pengiriman Anda>. Nilai itu ditulis ke catatan tugas sisi server agar mudah ditelusuri; ia tidak mencegah penagihan ganda. - Timeout ≠ gagal: permintaan bisa sudah diterima dan sedang dibuat. Sebelum mengulang, periksa dengan
GET /api/music/songs?p=1&page_size=20(parameter paginasi adalahp/page_size; penulisan kompatibelpsjuga bisa) apakah sudah muncul lagu baru dengangeneration_type=voice_profile_cover, dan kirim ulang hanya bila belum ada.
Isi create dan create-from-clip juga menerima field client_request_id (lihat §3 dan §4).
1.6 Ringkasan penagihan
| Tindakan | Endpoint | Harga | Catatan |
|---|---|---|---|
| Membuat suara (biasa) | POST /api/music/voice-profile/create |
Gratis | Mengunggah sampel tidak memakai kuota Suno |
| Membuat suara (dari audio yang ada) | POST /api/music/voice-profile/create-from-clip |
Gratis | Server hanya mencatat referensi materi, tidak mengunggah ulang |
| Kloning yang diperkuat | Sama, enhanced=true |
Menurut "harga unggah yang diperkuat" (default 10 ¥ per panggilan) | Asinkron; gagal otomatis dikembalikan |
| Cover dengan suara | POST /api/music/voice-profile/cover |
1,2 ¥ per panggilan; 2,4 ¥ per panggilan saat max_mode=true |
Satu panggilan mengembalikan 2 lagu |
| Kueri / daftar / detail / hapus | — | Gratis | |
| Unduh (ambil tautan langsung sendiri) | audio_url pada respons |
Gratis | Memutar alamat yang diberikan |
| Unduh (konversi ke wav / lirik, dll.) | POST /api/music/free2 |
0,2 ¥ per lagu berhasil | Lihat §8 |
Harga bisa dibaca kapan saja dari endpoint publik, jadi jangan di-hardcode (lihat §9):
curl -sS https://www.suno-api.io/api/pricing/catalog | jq '.data.catalog.meta'
# {
# "generation_price": "0.6",
# "voice_generation_price": "1.2", ← harga dasar cover dengan suara
# "max_mode_factor": "2",
# "enhanced_upload_price": "10", ← harga kloning yang diperkuat
# "voice_auto_verify_price": "5",
# "voice_long_term_clone_price": "5"
# }
Cover memakai pola potong di muka + kembalikan bila gagal:
- Permintaan yang ditolak (parameter salah, 4xx/5xx platform, saldo sendiri tidak cukup) tidak ditagih — saat dikirim dengan suara yang tidak ada, saldo tidak berubah sama sekali dalam pengukuran kami (delta = 0);
- Tugas yang diterima tetapi akhirnya gagal (termasuk gangguan layanan platform) melewati jalur pengembalian sisi server dan mengembalikan jumlah yang dipotong di muka.
1.7 Kamus status
status suara:
| Nilai | Arti | Bisa untuk cover |
|---|---|---|
ready |
Siap | ✅ |
processing |
Muncul hanya pada kloning yang diperkuat (enhanced=true); sedang diproses |
❌ (tunggu ready) |
failed |
Pembuatan gagal; lihat error_message; kloning yang diperkuat sudah dikembalikan |
❌ |
status lagu (nilai yang dikembalikan endpoint kueri):
| Nilai | Arti | Bisa diunduh |
|---|---|---|
submitted / queued / processing |
Sedang dibuat (stream pratinjau mungkin sudah ada) | ❌ |
completed |
Selesai | ✅ |
failed |
Gagal; biaya sudah dikembalikan | ❌ |
2. Ringkasan endpoint
| # | Metode | Jalur | Fungsi | Penagihan |
|---|---|---|---|---|
| 1 | POST | /api/music/voice-profile/create |
Membuat suara (unggah / URL / base64) | Gratis (kecuali enhanced=true) |
| 2 | POST | /api/music/voice-profile/create-from-clip |
Membuat suara dari audio yang sudah ada | Gratis |
| 3 | GET | /api/music/voice-profile/list |
Daftar suara | Gratis |
| 4 | GET | /api/music/voice-profile/{voice_id} |
Detail suara (termasuk kemajuan kloning yang diperkuat) | Gratis |
| 5 | POST | /api/music/voice-profile/delete |
Menghapus suara | Gratis |
| 6 | POST | /api/music/voice-profile/cover |
Cover dengan suara / menyanyikan lagu baru | 1,2 ¥ (MAX 2,4) |
| 7 | POST | /api/music/query |
Kueri status lagu secara massal | Gratis |
| 8 | GET | /api/music/songs/{song_id} |
Detail satu lagu | Gratis |
| 9 | GET | /api/music/download |
Mengunduh berkas jadi | Gratis (mp3/tautan putar) |
| 10 | POST | /api/music/free2 |
Konversi ke wav / lirik, dll. | 0,2 ¥ per lagu berhasil |
| 11 | POST | /api/music/free2/cached |
Mengambil alamat unduh yang sudah diarsipkan | Gratis |
| 12 | GET | /api/music/songs |
Daftar karya saya, berpaginasi | Gratis |
3. Membuat suara
POST /api/music/voice-profile/create
Daftarkan satu potong audio vokal sebagai "suara" dan dapatkan voice_id. Bagi platform, suara hanyalah "satu audio + clip-nya di katalog", jadi setelah berhasil dibuat audio sumber itu disimpan permanen (untuk cover berikutnya).
3.1 Tiga bentuk masukan (pilih satu)
Bentuk A: unggah berkas multipart (disarankan)
Content-Type: multipart/form-data
file=<biner audio> # wajib
title=<nama suara> # opsional; bila kosong memakai nama berkas tanpa ekstensi
file_name=<nama berkas asli>
source_file_name=<nama berkas asli>
source_kind=upload|record # opsional, penanda sumber (unggah / rekaman); default upload
enhanced=false|true # opsional, true = kloning yang diperkuat (lihat §3.5)
client_request_id=<kunci idempotensi> # opsional
voice_id=<ID sendiri> # opsional, jarang dipakai
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=Suara saya" \
-F "source_kind=upload"
Bentuk B: JSON + URL audio publik
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": "Suara saya"
}'
- URL harus tautan langsung HTTPS yang dapat diakses publik; server mengunduhnya sekali lalu menyimpannya ke penyimpanan objek kami.
- Alamat juga bisa ditaruh di field
audio_url, efeknya sama (bila keduanya dikirim,file_urlyang dipakai). - Bila alamat sudah ada di penyimpanan objek platform ini (
*.myqcloud.com/create-ui/voice-source/...), tidak diunduh ulang: langsung didaftarkan.
Bentuk C: JSON + base64
{
"file_base64": "data:audio/mpeg;base64,//uQxAAA…",
"file_name": "my-voice.mp3",
"title": "Suara saya"
}
- Mendukung prefiks
data:audio/xxx;base64,maupun base64 murni. - Ukuran terbatas (base64 membesar 1,33×), untuk berkas besar gunakan bentuk A.
3.2 Persyaratan audio
| Butir | Persyaratan | Catatan |
|---|---|---|
| Ukuran | ≤ 10 MB | Melebihi batas, gateway memotong isi dan tampak seperti "ditolak Suno"; kompres atau potong dulu |
| Durasi | Minimal 6 detik; disarankan 10–60 detik | Di bawah 6 detik platform menolak: Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
| Format | mp3 / wav / m4a / aac / flac / ogg | Ditentukan dari ekstensi berkas |
| Isi | Vokal bersih; hindari cover jadi atau lagu asli beriringan musik | Audio yang sangat mirip rekaman di katalog akan ditolak: This audio matches an existing recording in our catalog. (terukur) |
3.3 Respons
{
"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": "Suara saya",
"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
}
}
Penjelasan field (create / list / detail memakai kumpulan field yang sama):
| Field | Tipe | Catatan |
|---|---|---|
voice_id |
string | ID suara; cover berikutnya memakainya |
clip_id / song_id |
string | clip id audio suara itu di sisi Suno (keduanya sama); untuk penelusuran |
account_id |
string | Akun yang menaunginya (untuk penelusuran; klien tidak perlu peduli) |
title |
string | Nama suara |
source_file_name |
string | Nama berkas asli |
audio_url |
string | Tautan langsung jangka panjang ke audio sumber, bisa untuk pratinjau; disimpan permanen |
image_url |
string | Sampul suara (yang Suno buat untuk audio vokal); bila tidak ada sampul kunci ini sama sekali tidak muncul |
duration_s |
number | Panjang sampel suara dalam detik |
enhanced |
bool | Dibuat dengan kloning yang diperkuat atau tidak |
source_kind |
string | upload / record / clip (dari audio yang sudah ada) |
status |
string | ready / processing / failed |
error_message |
string | Sebab gagal; hanya muncul saat failed |
task_id |
number | Nomor tugas dasar kloning yang diperkuat; hanya ada saat enhanced=true |
pre_consumed_quota |
number | Kuota potong di muka (hanya pada kloning yang diperkuat) |
created_at / updated_at |
number | Detik Unix |
created_at/updated_atadalah cap waktu tingkat detik (10 digit), bukan milidetik.
3.4 Kesalahan umum
| HTTP | message | Sebab dan penanganan |
|---|---|---|
| 200 | one of file_path, file_base64, or file_url is required |
Tidak menyertakan isi audio |
| 200 | Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
Sampel terlalu pendek; gunakan ≥6 detik (disarankan ≥10 detik) |
| 200 | This audio matches an existing recording in our catalog. |
Sampel sangat mirip rekaman di katalog; pakai vokal kering bersih yang lain |
| 200 | upload succeeded without clip or account identity |
Balasan platform tidak normal; coba lagi |
| 200 | audio file exceeds 30 MB limit |
Melebihi batas server (untuk pelanggan jaga di 10 MB) |
| 401 | invalid token |
API Key salah |
3.5 Kloning yang diperkuat (enhanced=true)
Untuk kasus "sampel suara sendiri memuat lirik berhak cipta / perlu unggah yang diperkuat". Harga mengikuti harga unggah yang diperkuat (default 10 ¥ per panggilan, gagal otomatis dikembalikan):
- Responsnya langsung
status=processing+task_id(belum adaclip_id) dan berjalan asinkron; - Selama diproses, pantau dengan
GET /api/music/voice-profile/{voice_id}yang mengembalikanprogress_percent/progress_stage/progress_message; - Saat selesai
statusmenjadireadydanclip_id,audio_url,image_urldilengkapi; - Bila gagal
status=faileddanerror_messageberbunyi kira-kira "unggah yang diperkuat gagal; biaya sudah dikembalikan otomatis, coba lagi nanti"; - Kloning yang diperkuat jauh lebih lama daripada pembuatan biasa (menit), jadi jangan menunggunya dengan logika timeout sinkron.
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=Suara saya" -F "enhanced=true"
4. Membuat suara dari audio yang sudah ada
Kalau tidak ingin mengunggah lagi: salin langsung audio yang sudah Anda unggah atau sudah Anda buat menjadi suara. Gratis dan idempoten.
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…"
}
source_song_id: clip id audio yang sudah selesai di akun Anda (sama dengansong_idlagu).- Mengirim clip yang sama berulang tidak membuat catatan baru: suara yang ada langsung dikembalikan dengan
reused: true(terukur).
Responsnya adalah semua field pada §3.3 plus dua field hanya-baca:
| Field | Catatan |
|---|---|
reused |
true = audio ini sudah jadi suara Anda dan dipakai ulang |
source_type |
Asal 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"
}
}
Kesalahan (message apa adanya; sebaiknya ditampilkan atau dilokalkan):
| message | Arti |
|---|---|
source audio not found |
Clip tidak ada atau bukan milik Anda |
source audio is invalid |
Audio itu masih dibuat / produk antara dan belum bisa dipakai |
source_song_id is required |
source_song_id tidak dikirim |
5. Daftar / detail / hapus suara
5.1 Daftar
GET /api/music/voice-profile/list
GET /api/music/voice-profile/list?include_deleted=true
{
"success": true,
"message": "",
"data": {
"items": [ { "voice_id": "vp_…", "title": "Suara saya", "status": "ready", "audio_url": "…", "image_url": "…" } ],
"total": 1
}
}
Field-nya persis seperti §3.3. Suara yang dihapus tidak dikembalikan secara default.
5.2 Detail
GET /api/music/voice-profile/{voice_id}
Mengembalikan satu objek suara (data adalah objek itu sendiri, bukan larik). Saat kloning yang diperkuat berjalan, ada tambahan:
| Field | Catatan |
|---|---|
progress_percent |
Bilangan bulat 0–100 |
progress_stage |
Penanda tahap, misalnya media_preparing |
progress_message |
Teks kemajuan untuk ditampilkan ke pengguna |
5.3 Hapus
POST /api/music/voice-profile/delete
Content-Type: application/json
{ "voice_id": "vp_2026…" }
{ "success": true, "message": "", "data": { "voice_id": "vp_2026…", "status": "deleted" } }
- Setelah dihapus, suara hilang dari daftar dan tidak bisa dipakai untuk cover baru: mengirim dengan
voice_iditu mengembalikan 400 (lihat §6.4). - Lagu yang sudah dibuat dengannya sama sekali tidak terpengaruh; pemutaran, unduhan, lanjutan, penggantian, dan pemisahan tetap berjalan.
- Menghapus suara yang tidak ada, atau yang bukan milik akun ini, mengembalikan
{"success":false,"message":"voice not found"}.
6. Cover dengan suara (endpoint inti)
POST /api/music/voice-profile/cover
Content-Type: application/json
Satu pengiriman menghasilkan 2 lagu (sama seperti pembuatan biasa).
6.1 Dua skenario
| Skenario | Pemicu | Catatan |
|---|---|---|
| A. Cover lagu tertentu | song_clip_id dikirim |
Menyanyikan lagu itu dengan suara Anda (melodi / ritme / bagian mengikuti aslinya; vokal menjadi suara Anda) |
| B. Nyanyikan lagu baru dengan suara | song_clip_id tidak dikirim |
Hanya suara + lirik (opsional) + kebutuhan gaya; model mengarang melodi baru dalam gaya itu lalu menyanyikannya |
resolved_scene pada respons menggemakan cover atau sing, supaya Anda bisa memastikan jalur yang dipakai.
6.2 Field permintaan
| Field | Tipe | Wajib | Default | Catatan |
|---|---|---|---|---|
model |
string | Ya | — | Nama model untuk pelanggan, lihat §6.5. Tidak dikirim akan menghasilkan model is required (HTTP 500) |
voice_id |
string | Salah satu | — | ID suara (vp_…); harus status=ready |
voice_clip_id |
string | Salah satu | — | Bisa juga memakai clip id suara; bila keduanya dikirim, voice_id yang dipakai |
song_clip_id |
string | Tidak | kosong | Clip id (song_id) lagu yang akan di-cover. Tidak dikirim = skenario B |
lyrics |
string | Tidak | kosong | Lirik lengkap, dikirim karakter demi karakter tanpa ditulis ulang atau dipotong; ≤ 3000 karakter |
cover_requirements |
string | Tidak | kosong | Instruksi cover dalam bahasa alami, misalnya "artikulasi lebih jelas". Digabungkan ke prompt tetap |
style_requirements |
string | Tidak | kosong | Kebutuhan gaya, misalnya "folk lambat, gitar akustik" |
title |
string | Tidak | kosong | Judul kedua lagu ini di ruang kerja (memengaruhi song_title pada kueri berikutnya) |
negative_tags |
string | Tidak | kosong | Gaya yang dikecualikan, misalnya elektronik, rap; ≤ 1000 karakter |
vocal_gender |
string | Tidak | kosong | m / f (juga menerima male / female); kosong = bebas |
duration |
number | Tidak | kosong | Durasi yang diinginkan dalam detik, bilangan bulat 1–480; kosong = platform menentukan. Minimum praktis platform sekitar 30 detik: nilai lebih kecil tetap menghasilkan lagu sekitar 30 detik dalam pengukuran |
audio_weight |
number | Tidak | 0,85 | Audio Influence, desimal 0–1. Makin tinggi makin dekat ke sampel suara |
style_weight |
number | Tidak | kosong | Pengaruh gaya, desimal 0–1 |
weirdness_constraint |
number | Tidak | kosong | Kreativitas, desimal 0–1 (bila antarmuka memakai persen, bagi 100) |
variety |
number | Tidak | kosong | Keragaman, bilangan bulat 0–4 (bukan persen), hanya pada model v6 |
max_mode |
boolean | Tidak | false |
Max Mode, harga ×2 |
client_request_id |
string | Tidak | kosong | Identitas pengiriman, ditulis ke catatan tugas sisi server untuk penelusuran (tidak menduplikasi-filter) |
Sebaiknya sertakan header X-Create-Ui-Client-Request-Id: <id pengiriman yang sama>: hanya itu yang ditulis ke catatan tugas sisi server dan menjadi kunci utama penelusuran nanti (lihat §1.5).
Perhatikan satuan: audio_weight / style_weight / weirdness_constraint adalah desimal 0–1, variety adalah bilangan bulat 0–4, duration dalam detik. Tertukar akan ditolak atau hasilnya aneh.
Lirik opsional pada skenario B (model menanganinya sendiri), tetapi kirim lyrics bila ingin menyanyikan konten tertentu.
6.3 Respons
{
"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": "[Tugas] Ini sebuah cover. … (bagian struktur tetap dari server + kebutuhan cover / gaya yang Anda isi)"
},
{
"song_id": "7c91…",
"status": "processing",
"model_version": "suno-v6",
"audio_url": ""
}
],
"source_updates": []
}
}
Poin penting:
- Identifikasi hasil jadi dengan
clips[].song_id(endpoint ini tidak mengembalikan fieldid). - Anda langsung mendapat 2 nilai
song_id, sementarastatusmasihprocessing(hanya berarti sudah diterima) danaudio_urlkosong; harus polling sampaicompletedsebelum mengunduh.play_urladalah stream pratinjau platform, bisa muncul sejak tahap pengiriman dan akan kedaluwarsa. descriptionadalah prompt yang akhirnya dikirim server (bagian struktur tetap +cover_requirements/style_requirementsyang Anda isi); sangat berguna saat menelusuri hasil.source_updatesadalah hasil pemrosesan materi di server dan bisa diabaikan klien.titleyang Anda kirim ditulis ke catatan tugas sisi server dan muncul sebagaisong_titlepada kueri selanjutnya;clips[].song_titleyang kosong pada respons pengiriman adalah normal.
6.4 Kesalahan
{ "error": { "message": "suara ini tidak ada atau sudah dihapus (voice_id=vp_xxx)…", "type": "new_api_error", "param": "", "code": "invalid_request" } }
| HTTP | message | Sebab |
|---|---|---|
| 500 | model is required |
Isi tidak memuat model (field wajib untuk pemilihan kanal) |
| 400 | voice_id is required and must be a ready voice |
voice_id tidak dikirim, atau dikirim nilai placeholder / suara belum siap |
| 400 | suara ini tidak ada atau sudah dihapus (voice_id=vp_xxx)… |
Suara sudah dihapus, tidak ada, atau bukan milik akun saat ini. Pakai suara lain yang tersedia atau buat suara baru |
| 400 | suara ini sudah dihapus (voice_id=vp_xxx)… |
Saat mengirim materi langsung lewat voice_clip_id, suara untuk materi itu sudah dihapus; penanganannya sama seperti di atas |
| 400 | voice is not ready yet (status=processing) |
Suara masih dibuat; tunggu ready lalu coba lagi |
| 400 | song_clip_id must be a real completed clip |
song_clip_id adalah placeholder / belum selesai |
| 400 | song_clip_id must differ from the voice clip |
Target cover tidak boleh sampel suara itu sendiri |
| 400 | audio_weight must be a number between 0 and 1 |
Satuan penggeser salah (dikirim persen) |
| 400 | duration must be an integer between 1 and 480 seconds |
Durasi bukan bilangan bulat 1–480 |
| 400 | vocal_gender must be one of m, f, male, female |
Nilai gender tidak valid |
| 400 | variety must be an integer between 0 and 4 / variety is only supported on v6 models |
Nilai keragaman tidak valid atau model tidak didukung |
Saldo tidak cukup langsung mengembalikan kesalahan penagihan pada tahap pengiriman dan tidak meninggalkan tugas setengah jadi.
6.5 Model yang tersedia (nama untuk pelanggan)
| Nama model | Catatan |
|---|---|
suno-v6 |
Default, disarankan |
suno-v6-wild |
Lebih liar |
suno-v6-mini |
Ringan |
Pakai nama model untuk pelanggan (yang di atas). chirp-* adalah nama internal platform dan tidak boleh dipakai langsung.
7. Memantau kemajuan
7.1 Kueri massal (disarankan)
POST /api/music/query
Content-Type: application/json
{ "model": "suno-v6", "song_ids": "id1,id2" }
song_idsadalah string dipisah koma (bukan larik).- Responsnya larik telanjang (langsung
[...], tanpa pembungkussuccess/data):
[
{
"song_id": "0f2a…",
"song_title": "Dua Harimau",
"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": "[Tugas] Ini sebuah cover. … (prompt akhir dari server)",
"style_tags": "…",
"created_at": "2026-09-25T18:19:09.918Z",
"video_url": ""
}
]
| Field | Catatan |
|---|---|
status |
Lihat §1.7; hanya completed yang dihitung selesai |
audio_url |
Tautan langsung mp3; terisi hanya setelah completed |
cover_url |
Alamat sampul |
duration |
Durasi sebenarnya dalam detik |
generation_type |
Lagu dari cover dengan suara selalu voice_profile_cover |
play_url |
Alamat pratinjau bertanda tangan (kedaluwarsa) |
song_title |
Judul tugas (yakni title yang Anda kirim; bila tidak dikirim server memberi nilai default) |
lyrics / prompt |
Lirik jadi / lirik asli |
description |
Prompt akhir yang dikirim server (termasuk bagian struktur tetap) |
style_tags |
Deskripsi gaya akhir |
created_at |
String ISO 8601 (perhatikan beda dengan detik Unix pada endpoint detail) |
Saran polling: setiap 5–10 detik, total timeout 10–15 menit (akun "dingin" paling lambat terukur sekitar 4,5 menit; sangat sedikit yang lebih lama). Jangan menilai selesai dari audio_url kosong, gunakan status.
Catatan kompatibilitas: endpoint ini mengidentifikasi lagu dengan
song_id; pada beberapa respons awal muncul fieldid, jadirow.song_id || row.idadalah cara baca yang aman.
7.2 Detail satu lagu
GET /api/music/songs/{song_id}
{
"success": true,
"data": {
"song_id": "0f2a…",
"title": "Dua Harimau",
"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": "Dua Harimau",
"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"]
}
}
}
- Di sini
created_at/completed_atadalah detik Unix (berbeda dari string ISO pada kueri massal, klien harus membedakannya). wav_url/video_urladalah pintu unduh platform ini (relatif terhadap domain saat ini) danGETmengambil berkasnya; menjadi string kosong bila platform belum menghasilkan materi itu.parameter_retentionmemberi tahu parameter pengiriman mana yang masih dapat ditelusuri:core_parameters_available=trueberarti parameter inti (lirik / gaya / sumber) bisa dikueri, sedangkan denganextended_parameters_available=falseparameter lanjutan di atas tidak disimpan (cover dengan suara saat ini termasuk kategori ini).
7.3 Karya saya
GET /api/music/songs?p=1&page_size=20
GET /api/music/songs?status=completed&q=kata kunci
Parameter paginasi: p (nomor halaman, mulai 1) / page_size (jumlah per halaman; penulisan kompatibel ps). Opsional status dan q (kata kunci judul). Default urut waktu pembuatan menurun.
{
"success": true,
"data": {
"page": 1,
"page_size": 20,
"total": 42,
"items": [
{
"song_id": "0f2a…",
"title": "Dua Harimau",
"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
}
]
}
}
Dengan generation_type=voice_profile_cover Anda bisa memisahkan "lagu dari cover dengan suara" dari hasil pembuatan lain.
8. Mengunduh hasil jadi
8.1 Ambil mp3 langsung (disarankan, gratis)
Ketiganya bisa; pilih satu:
- Pakai
audio_urldari hasil kueri (tautan langsung ke penyimpanan objek, paling praktis). GET /api/music/download?song_id=<id>&kind=mp3→ langsung mengembalikan aliran byte audio (nama berkas sudah ada diContent-Disposition).POST /api/music/download-url(untuk alamat sementara bertanda tangan).
curl -sS -L "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song.mp3
Nilai kind: mp3 (setara song) / playback (pemutaran streaming) / wav / video / lyrics / timestamped_lyrics.
timestamped_lyrics (.lrc) saat ini hanya untuk sebagian lagu; bila gagal, buat berkasnya sendiri dengan API lirik bermarka waktu.
Responsnya adalah aliran byte berkas, Content-Type dan Content-Disposition (nama berkas) sudah terpasang; wav_url / video_url yang dikembalikan GET /api/music/songs/{song_id} adalah pintu yang sama dengan kind=wav|video.
8.2 Konversi ke wav / lirik / metadata (berbayar)
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
}
}
filesmenerima:mp3/wav/lyrics/metadata, maksimal 10 lagu sekali jalan.- Ditagih per lagu yang berhasil (0,2 ¥ per lagu); lagu yang gagal total tidak ditagih, dan format yang gagal hanya muncul di
songs[].errors. - Untuk mengambil ulang berkas yang pernah diunduh, gunakan dulu yang gratis
POST /api/music/free2/cached(dengansong_ids+filesyang sama) untuk alamat terarsip;songs[].missing_filespada responsnya mencantumkan format yang belum tercache dan perlu disiapkan ulang.
9. Melihat harga
GET /api/pricing/catalog
Endpoint publik tanpa autentikasi. Semua harga satuan yang perlu ditampilkan ke pelanggan ada di data.catalog.meta (string):
| Kunci | Arti | Nilai saat ini |
|---|---|---|
generation_price |
Pembuatan biasa | 0,6 |
voice_generation_price |
Harga dasar cover dengan suara | 1,2 |
max_mode_factor |
Pengali Max Mode | 2 |
enhanced_upload_price |
Kloning yang diperkuat / unggah yang diperkuat | 10 |
voice_auto_verify_price |
Verifikasi suara otomatis | 5 |
voice_long_term_clone_price |
Kloning suara jangka panjang | 5 |
Harga disesuaikan di back-office, jadi bacalah secara langsung dan jangan di-hardcode di klien. Biaya cover sebenarnya = voice_generation_price × (bila max_mode benar, kalikan lagi max_mode_factor).
10. Batasan dan peringatan
- Ukuran unggah: ≤ 10 MB (server menerima lebih, tetapi gateway masuk memotong isi yang terlalu besar pada 10 MiB dan tampak seperti "ditolak Suno"; blokir dulu di sisi Anda).
- Durasi sampel: minimal 6 detik, disarankan 10–60 detik; terlalu pendek akan ditolak platform.
- Isi sampel: vokal bersih; hindari apa pun yang sangat mirip rekaman yang sudah ada (pencocokan katalog menolaknya).
- Batas teks:
lyrics≤ 3000 karakter; sebaiknyastyle_requirements/negative_tags/titledalam 1000 / 1000 / 100 karakter (kebutuhan gaya dan cover digabung ke prompt, jaga totalnya di bawah 3000 karakter). - Lirik tidak ditulis ulang: apa yang dikirim itulah yang dinyanyikan (karakter demi karakter), tanpa pemotongan lokal.
- Setiap lagu menghasilkan 2 trek; jangan mengasumsikan satu hasil.
- Audio sumber disimpan permanen: menghapus suara tidak membersihkan audio sumbernya; ini menjaga cover berikutnya tetap mungkin dan kepatuhan tetap tertelusuri.
- Suara harus ready: suara berstatus
processingtidak bisa dipakai untuk cover. - Timeout permintaan: pada akun "dingin" pengiriman pertama terukur sampai sekitar 4,5 menit, jadi setel timeout klien ≥ 6 menit. Cover tidak menduplikasi-filter tingkat permintaan, jadi setelah timeout periksa apakah sudah ada lagu baru (§1.5) sebelum memutuskan mengirim ulang.
- Kepemilikan suara: suara milik pembuatnya; cover hanya menerima suara yang siap dan belum dihapus. Suara yang tidak ada, sudah dihapus, atau milik akun lain mengembalikan 400:
suara ini tidak ada atau sudah dihapus (voice_id=…).
11. Pertanyaan yang sering diajukan (FAQ)
T1. Apakah membuat suara berbiaya? Pembuatan biasa dan "buat dari audio yang sudah ada" gratis; hanya cover (1,2 ¥ / MAX 2,4 ¥) dan kloning yang diperkuat (default 10 ¥) yang berbiaya.
T2. Bolehkah memakai lagu jadi beriringan musik sebagai sampel suara?
Tidak disarankan. Apa pun yang berisi musik, atau sangat mirip rekaman yang ada di katalog, akan ditolak platform (This audio matches an existing recording in our catalog.). Pakai rekaman murni vokal yang kering.
T3. Kenapa audio_url kosong setelah mengirim cover?
Pengiriman hanya berarti sudah diterima dan status masih processing. Alamat yang bisa diputar/diunduh muncul setelah Anda melakukan polling /api/music/query sampai status=completed.
T4. Perlukah mengirim lirik pada skenario B (tanpa song_clip_id)?
Opsional. Kirim lyrics untuk menyanyikan konten tertentu; tanpa itu model menanganinya sendiri, tetapi kontrolnya berkurang.
T5. Bisakah audio yang diunggah pelanggan langsung jadi suara?
Bisa: lewat bentuk file_url pada create, atau mengunggahnya dulu sebagai lagu lalu memanggil create-from-clip.
T6. Apakah uang dikembalikan bila gagal?
Permintaan yang langsung ditolak (parameter salah / platform error) tidak ditagih, menurut pengukuran; tugas yang diterima tetapi akhirnya gagal mengembalikan jumlah yang dipotong di muka. Pada kegagalan akhir, tugas melaporkan status=failed plus error_message.
T7. Setelah menghapus suara, apakah lagu yang pernah dibuat dengannya masih bisa didengar? Bisa. Penghapusan hanya memengaruhi apakah suara itu bisa dipakai untuk cover baru.
T8. Seberapa panjang lagu yang bisa di-cover sekali jalan?
duration menerima 1–480 detik; bila tidak dikirim platform menentukan dari lagu asli / materi. Perhatikan: trek jadi platform minimal sekitar 30 detik; dengan nilai lebih kecil, pengukuran tetap memberi 29,96 / 29,76 detik.
Lampiran A: contoh lengkap (Node.js, dengan polling dan unduhan)
const BASE = "https://www.suno-api.io";
const KEY = process.env.SUNO_API_KEY;
const H = { Authorization: `Bearer ${KEY}` };
// ① Buat suara (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 lambat, gitar akustik",
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 }] }
}
// ③ Polling sampai selesai (tiap 5 detik, maksimal 15 menit)
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(); // larik telanjang
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");
}
// ④ Unduh
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", "Suara saya");
const result = await cover(voice.voice_id, "5b773e9a-a035-4134-a4a4-29c9961d3ccb", "[Verse 1]\nlirik…");
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`);
}
Lampiran B: catatan perubahan
| Tanggal | Perubahan |
|---|---|
| 2026-10-15 | Semantik penghapusan dinyatakan gamblang (§5.3); cover dengan voice_id "sudah dihapus / tanpa hak" kini mengembalikan 400 sebelum potong di muka, tabel kesalahan dan FAQ disinkronkan (bersama gerbang penghapusan suara yang dirilis hari itu) |
| 2026-10-13 | Menambahkan catatan "mengapa kami menyarankan jalur ini" di awal: menurut penilaian nyata banyak pengguna, lagu dari jalur ini jauh lebih baik mempertahankan suara asli |
| 2026-09-26 | Versi pertama: membuat suara (tiga bentuk masukan) / membuat dari audio yang sudah ada / daftar, detail, hapus / cover dengan suara (skenario A dan B) / kueri kemajuan / unduhan / pembacaan harga, dengan bukti terukur |
Dapatkan kunci API
Buat kunci API di konsol setelah mendaftar. Setiap pembuatan berbiaya 0,6 ¥ dan menghasilkan 2 lagu, unduhan tidak terbatas, dan nomor telepon tidak diperlukan.
Ambil kunci API Kembali ke ringkasan