API pembuatan mode sederhana
Deskripsi endpoint
Pembuatan mode sederhana mengubah deskripsi satu kalimat menjadi lagu yang utuh. Layanan menulis lirik, melodi, aransemen, dan vokal dari deskripsi Anda.
Endpoint: POST /api/music/create
Biaya: Berbayar, saat ini default 0,6 ¥ per panggilan. Setiap panggilan biasanya mengembalikan 2 lagu; jumlah yang benar-benar ditagih mengikuti konfigurasi harga di back-office saat ini.
Max Mode / Variety: endpoint ini mendukung parameter opsional max_mode dan variety (0-4). Dengan
max_mode aktif, panggilan ini ditagih 2× harga (0,6 ¥ → 1,2 ¥ per panggilan); variety tidak menambah
biaya. Arti dan cara mengirimnya ada di bagian "Parameter lanjutan" pada
Ringkasan API baru.
Model yang disarankan: suno-v6
Waktu tunggu dan timeout (penting): ini endpoint sinkron — pesanan baru diterima dan diteruskan ke pembuatan saat respons tiba. Dari pengukuran, sebagian besar permintaan merespons dalam 1-3 detik, sekitar 10% melewati 30 detik, dan terlama sekitar 230 detik. Setel timeout klien 300 detik atau lebih; tidak ada respons bukan berarti tidak ada yang dibuat, dan jangan mencoba ulang langsung setelah timeout (itu menduplikasi pesanan dan menagih dua kali). Jika koneksi terputus, periksa lagi nanti dengan
GET /api/music/songs. Lihat "Waktu tunggu dan pengaturan timeout" di Ringkasan API baru.
Parameter permintaan
Headers
| Parameter | Tipe | Wajib | Catatan |
|---|---|---|---|
| Authorization | string | ya | Bearer YOUR_API_KEY |
| Content-Type | string | ya | application/json |
Parameter body
| Parameter | Tipe | Wajib | Default | Catatan |
|---|---|---|---|---|
| description | string | ya | - | Deskripsi lagu, bahasa apa pun; maksimal 3000 karakter (lebih akan mengembalikan 400 dan tidak ditagih) |
| model | string | tidak | suno-v6 | Nama model untuk pelanggan: suno-v6, suno-v6-wild, atau suno-v6-mini |
| instrumental | boolean | tidak | false | Apakah lagu hanya instrumental |
| wait_completion | boolean | tidak | false | Apakah menunggu pembuatan selesai sebelum merespons |
| references | array | tidak | - | Daftar materi referensi: lagu referensi / suara lama / gambar referensi; maksimal 5 lagu, 1 suara, dan 1 gambar. Lihat "Materi referensi references (opsional)" di bawah |
Contoh permintaan
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "lagu pop Mandarin ceria tentang musim panas di tepi laut",
"instrumental": false,
"wait_completion": false
}'
Materi referensi references (opsional)
references adalah array yang menempelkan "materi referensi" pada pembuatan ini. Bersifat sepenuhnya opsional (jika dihilangkan, perilakunya persis seperti sebelumnya), dan Anda bisa menempelkan satu jenis atau kombinasi apa pun.
Jenis elemen
| type | Kolom wajib | Kolom opsional | Maksimum | Catatan |
|---|---|---|---|---|
song |
song_id |
style_prompt, lyrics, duration_s |
5 | Lagu referensi; song_id berasal dari API kueri lagu dan riwayat dan lagunya harus sudah selesai |
voice |
voice_id |
- | 1 | Suara lama; voice_id berasal dari API kloning suara dan pembuatan dengan suara |
image |
base64 |
- | 1 | Gambar referensi; kirim konten base64 dalam bentuk data:image/jpeg;base64,... |
Aturan
- Urutan lagu referensi adalah urutan maknanya: kirim sesuai urutan yang Anda maksud (misalnya "melodi dari lagu pertama, vokal dari lagu kedua").
style_prompt/lyrics/duration_sboleh dikosongkan; platform mengisinya dari informasi lagu, dan nilai yang Anda kirim yang berlaku.- Untuk lagu instrumentalia murni,
lyricsboleh""atau"[Instrumental]". - Gambar referensi mendukung
jpeg/png/webp, maksimal 10MB per gambar, dikirim bersama body sebagai base64. - Saat menempelkan beberapa lagu referensi, gunakan juga
accept_mode=async(lihat "Mode tanda terima penerimaan" di atas): layanan harus menyiapkan materi terlebih dahulu, jadi menunggu secara sinkron bisa lama.
Contoh: dua lagu referensi
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "gabungkan ide-ide ini menjadi satu lagu",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "song", "song_id": "a90438d2-35fc-4443-88f4-56531e6e5d24" }
]
}'
Contoh: lagu referensi + suara lama
{
"model": "suno-v6",
"description": "nyanyikan ide-ide ini dengan suara ini",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "voice", "voice_id": "5813cbe1-36f1-414a-a9a8-4d399dfeb292" }
]
}
Contoh: lagu referensi + gambar referensi
{
"model": "suno-v6",
"description": "tangkaplah suasana gambar ini",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
Kesalahan parameter
Kasus berikut mengembalikan HTTP 400, diblokir sebelum ada penagihan, jadi tidak berbiaya:
| Kasus | Pesan kesalahan |
|---|---|
| Lebih dari 5 lagu referensi | references supports at most 5 song references |
| Lebih dari 1 suara | references supports at most 1 voice reference |
| Lebih dari 1 gambar referensi | references supports at most 1 image reference |
type tidak valid |
references[0].type must be one of song, voice, image |
Lagu tanpa song_id |
references[0].song_id is required |
| Lagu belum selesai | references[0].song_id must be a real completed clip |
| Lagu yang sama dikirim dua kali | references[0].song_id is duplicated |
Angka pada
references[0]adalah indeks elemen itu di dalam array, sehingga elemen yang bermasalah mudah ditemukan.
Respons
Array lagu, biasanya berisi 2 tugas atau lagu.
[
{
"song_id": "clip_id",
"song_title": "Angin Laut Musim Panas",
"status": "pending",
"description": "lagu pop Mandarin ceria tentang musim panas di tepi laut",
"audio_url": "",
"cover_url": "",
"video_url": "",
"model_version": "suno-v6",
"generation_type": "generate",
"created_at": "2026-05-21T10:00:00Z"
}
]
Mode tanda terima penerimaan (opsional, disarankan untuk klien yang tidak boleh menahan koneksi lama)
Secara default endpoint ini sinkron: respons yang tiba menandakan pesanan diterima, dan waktu tunggu terukur bisa mencapai sekitar 230 detik. Jika klien Anda tidak cocok menahan koneksi lama, aktifkan mode tanda terima penerimaan — salah satu saja:
- tambahkan
"accept_mode": "async"ke body permintaan - tambahkan header
X-Accept-Mode: async
Dengan itu, endpoint langsung mengembalikan HTTP 202, yang hanya berarti "diterima dan masuk antrean pembuatan", sementara pembuatan berjalan di latar belakang:
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "queued",
"accepted_at": 1789896434,
"pre_consumed_quota": 300000,
"tasks": [
{ "index": 0, "status": "queued" },
{ "index": 1, "status": "queued" }
]
}
}
Tahap penerimaan tidak mengembalikan
song_id. ID lagu asli belum ada, dan baikrequest_idmaupuntasks[].indexbukan ID lagu — jangan menyimpannya sebagaisong_id.song_idasli muncul di kueri kemajuan di bawah.
Kueri kemajuan penerimaan
Endpoint: GET /api/music/requests/{request_id} (gratis, autentikasi dengan kunci API yang sama)
curl "https://www.suno-api.io/api/music/requests/ac_20260920092714315816800d76fv3nq" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "processing",
"tasks": [
{ "index": 0, "status": "processing", "song_id": "f3fa09f5-3d55-4953-826c-0d23f043ec57" },
{ "index": 1, "status": "processing", "song_id": "5fcafe3e-3fae-4d64-8f66-c01bc027b0c3" }
]
}
}
Arti setiap nilai status:
| status | Arti |
|---|---|
queued |
Diterima, belum terikat ke lagu tertentu (tasks bisa berupa array kosong) |
processing |
Diteruskan ke pembuatan |
partial |
Salah satu dari dua sudah selesai |
completed |
Keduanya selesai, tasks[].song_id bisa dibaca |
failed |
Pengiriman gagal, biaya sudah dikembalikan penuh, dan error_message memberi alasannya |
Setiap tugas juga punya tasks[].status sendiri, dengan nilai yang sama seperti API kueri lagu:
pending (terkirim, sedang dibuat), processing, completed, failed. Item tugas bisa juga membawa title,
duration, dan audio_url yang sudah terdaftar; yang tidak ada berarti belum dibuat.
Setelah mendapat song_id asli, lanjutkan dengan API kueri lagu atau endpoint unduhan.
Contoh Python
import time
import requests
BASE = "https://www.suno-api.io"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}
accepted = requests.post(
f"{BASE}/api/music/create",
headers={**HEADERS, "Idempotency-Key": "your-own-unique-key"},
json={"description": "lagu pop yang ceria", "model": "suno-v6", "accept_mode": "async"},
timeout=300,
).json()["data"]
request_id = accepted["request_id"]
while True:
time.sleep(5)
progress = requests.get(
f"{BASE}/api/music/requests/{request_id}", headers=HEADERS, timeout=60
).json()["data"]
if progress["status"] in ("completed", "failed"):
print(progress)
break
Kompatibilitas dan catatan
- Tanpa
accept_mode, perilakunya persis seperti sebelumnya: menunggu sinkron, mengembalikan200dan array lagu. Integrasi yang ada tidak perlu mengubah apa pun. - Sakelar ini saat ini hanya bekerja pada
POST /api/music/createdanPOST /api/music/create/custom; endpoint pembuatan lain belum mendukungnya. - Kirim juga
Idempotency-Key(string unik milik Anda, ≤128 karakter): kunci yang sama hanya diterima sekali, pengiriman ulang mengembalikan tanda terima yang sama dan tidak ditagih dua kali. Dalam mode asinkron ini lebih penting lagi. - Dengan
accept_mode=async,wait_completiondiabaikan (tanda terima langsung kembali tanpa menunggu lagu). - Biaya tetap dipotong di muka saat pesanan diterima; pembuatan yang gagal dikembalikan penuh secara otomatis.
- Batas kolom teks:
descriptionmenampung maksimal 3000 karakter (dihitung per karakter Unicode, satu aksara Han dihitung 1). Teks lebih panjang langsung mengembalikan HTTP400, tidak masuk pembuatan dan tidak ditagih, dan pesan kesalahan mencantumkan panjang terukurnya, misalnyadescription must not exceed 3000 characters; received 4120. Endpoint ini tidak punya kolom lirik/gaya; untuk itu lihat "Batas kolom teks" di API pembuatan mode kustom. Aturan umumnya ada di "Batas kolom teks" pada Ringkasan API baru. - Tanpa
references, perilaku, harga, dan respons persis seperti sebelumnya: integrasi yang ada tidak perlu mengubah apa pun. - Saat materi referensi dilampirkan (terutama beberapa lagu), pilih mode tanda terima
accept_mode=asyncdaripada menunggu sinkron yang lama; lama penyiapan materi bergantung pada jumlah dan sumbernya.
Langkah berikutnya
Jika lagu belum selesai saat respons tiba, gunakan API kueri lagu untuk mengambil hasil akhir.
Contoh integrasi Node/Electron
Jika Anda mengintegrasikan pembuatan standar di proses utama Electron, server Node.js, atau klien desktop, alur yang disarankan adalah:
- Panggil
POST /api/music/createuntuk membuat tugas pembuatan. - Baca
song_idatauiddari respons. - Panggil
POST /api/music/querysetiap 2 detik untuk memeriksa status. - Anggap pembuatan selesai begitu
audio_urlmuncul di hasil kueri.
Berhenti memakai jalur lama POST /api/generate atau GET /api/clip?id=...; keduanya bukan bagian dari permukaan integrasi publik yang disarankan saat ini.
const http = require('http');
const https = require('https');
const BASE_URL = 'https://www.suno-api.io';
const MODEL = 'suno-v6';
const POLL_INTERVAL_MS = 2000;
const MAX_POLL_ATTEMPTS = 60;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function requestJson(urlString, apiKey, body) {
const url = new URL(urlString);
const transport = url.protocol === 'https:' ? https : http;
const payload = JSON.stringify(body);
return new Promise((resolve, reject) => {
const req = transport.request(
{
method: 'POST',
hostname: url.hostname,
port: url.port || undefined,
path: `${url.pathname}${url.search}`,
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
},
(res) => {
let raw = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
raw += chunk;
});
res.on('end', () => {
const data = raw ? JSON.parse(raw) : {};
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(`Suno API request failed: HTTP ${res.statusCode} ${raw}`));
return;
}
resolve(data);
});
}
);
req.on('error', reject);
req.write(payload);
req.end();
});
}
function getPayload(response) {
return response && response.data !== undefined ? response.data : response;
}
function toSongList(payload) {
if (Array.isArray(payload)) return payload;
if (Array.isArray(payload?.songs)) return payload.songs;
if (Array.isArray(payload?.clips)) return payload.clips;
return payload ? [payload] : [];
}
function collectSongIds(createResponse) {
return toSongList(getPayload(createResponse))
.map((song) => song.song_id || song.id)
.filter(Boolean);
}
async function generateSunoSong({ apiKey, description, instrumental = false }) {
const createResponse = await requestJson(`${BASE_URL}/api/music/create`, apiKey, {
description,
model: MODEL,
instrumental,
wait_completion: false,
});
const songIds = collectSongIds(createResponse);
if (songIds.length === 0) {
throw new Error(`Suno API did not return song ids: ${JSON.stringify(createResponse)}`);
}
for (let attempt = 0; attempt < MAX_POLL_ATTEMPTS; attempt += 1) {
await sleep(POLL_INTERVAL_MS);
const queryResponse = await requestJson(`${BASE_URL}/api/music/query`, apiKey, {
song_ids: songIds,
model: MODEL,
});
const songs = toSongList(getPayload(queryResponse));
const completed = songs.find((song) => song.audio_url);
if (completed) {
return {
audioUrl: completed.audio_url,
title: completed.song_title || completed.title || 'Suno Song',
duration: completed.duration,
};
}
const allFailed = songs.length > 0 && songs.every((song) =>
['failed', 'error', 'rejected'].includes(String(song.status || '').toLowerCase())
);
if (allFailed) {
throw new Error(`Suno generation failed: ${JSON.stringify(songs)}`);
}
}
throw new Error('Suno generation timed out after 120 seconds. Please query again later.');
}
// Usage:
// generateSunoSong({
// apiKey: process.env.SUNO_API_KEY,
// description: 'A bright pop song about the ocean in summer',
// }).then(console.log).catch(console.error);
Di proyek nyata, simpan kunci API di variabel lingkungan server, pengaturan klien desktop, atau penyimpanan aman — jangan pernah di kode front-end dan jangan pernah di-commit ke repositori.
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