API di generazione in modalità semplice
Descrizione dell'endpoint
La generazione in modalità semplice trasforma una descrizione di una frase in un brano completo. Il servizio scrive testo, melodia, arrangiamento e voce a partire dalla tua descrizione.
Endpoint: POST /api/music/create
Fatturazione: A pagamento, attualmente 0,6 ¥ per chiamata per impostazione predefinita. Ogni chiamata restituisce di solito 2 brani; l'importo effettivamente addebitato segue la configurazione prezzi attuale del back-office.
Max Mode / Variety: questo endpoint supporta i parametri opzionali max_mode e variety (0-4). Con
max_mode attivo, questa chiamata viene fatturata al doppio del prezzo (0,6 ¥ → 1,2 ¥ per chiamata); variety non costa
nulla in più. Significato e modalità di invio sono nella sezione «Parametri avanzati» della
Panoramica della nuova API.
Modello consigliato: suno-v6
Tempi di attesa e timeout (importante): è un endpoint sincrono — l'ordine viene accettato e passato alla generazione solo quando arriva la risposta. Dai dati misurati, la maggior parte delle richieste risponde in 1-3 secondi, circa il 10% supera i 30 secondi e la più lunga arriva a circa 230 secondi. Imposta il timeout del client a 300 secondi o più; nessuna risposta non significa che non sia stato generato nulla, e non ritentare subito dopo un timeout (duplica l'ordine e riaddebita). Se la connessione è caduta, verifica più tardi con
GET /api/music/songs. Vedi «Tempi di attesa e impostazione del timeout» nella Panoramica della nuova API.
Parametri della richiesta
Headers
| Parametro | Tipo | Obbligatorio | Note |
|---|---|---|---|
| Authorization | string | sì | Bearer YOUR_API_KEY |
| Content-Type | string | sì | application/json |
Parametri del body
| Parametro | Tipo | Obbligatorio | Predefinito | Note |
|---|---|---|---|---|
| description | string | sì | - | Descrizione del brano, in qualsiasi lingua; al massimo 3000 caratteri (oltre restituisce 400 e non viene addebitato) |
| model | string | no | suno-v6 | Nome del modello lato cliente: suno-v6, suno-v6-wild o suno-v6-mini |
| instrumental | boolean | no | false | Se il brano è solo strumentale |
| wait_completion | boolean | no | false | Se attendere la fine della generazione prima di rispondere |
| references | array | no | - | Elenco di materiale di riferimento: brani di riferimento / voci legacy / immagini di riferimento; al massimo 5 brani, 1 voce e 1 immagine. Vedi «Materiale di riferimento references (opzionale)» sotto |
Esempi di richiesta
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": "una canzone pop in mandarino vivace sull'estate al mare",
"instrumental": false,
"wait_completion": false
}'
Materiale di riferimento references (opzionale)
references è un array che allega «materiale di riferimento» a questa generazione. È del tutto opzionale (ometterlo si comporta esattamente come prima) e puoi allegare un solo tipo o qualsiasi combinazione.
Tipi di elemento
| type | Campo obbligatorio | Campi opzionali | Massimo | Note |
|---|---|---|---|---|
song |
song_id |
style_prompt, lyrics, duration_s |
5 | Brano di riferimento; il song_id viene dalla API di consultazione e cronologia dei brani e il brano deve essere già completato |
voice |
voice_id |
- | 1 | Voce legacy; il voice_id viene dalla API di clonazione vocale e generazione con voce |
image |
base64 |
- | 1 | Immagine di riferimento; invia contenuto base64 nella forma data:image/jpeg;base64,... |
Regole
- L'ordine dei brani di riferimento è il loro ordine semantico: passali nell'ordine che vuoi esprimere (per esempio «melodia del primo, voce del secondo»).
style_prompt/lyrics/duration_spossono essere omessi; la piattaforma li completa dalle informazioni del brano e ciò che invii tu prevale.- Nei brani puramente strumentali,
lyricspuò essere""o"[Instrumental]". - Le immagini di riferimento supportano
jpeg/png/webp, fino a 10MB ciascuna, inviate con il body in base64. - Quando alleghi più brani di riferimento, usa anche
accept_mode=async(vedi «Modalità ricevuta di accettazione» sopra): il servizio deve prima preparare il materiale, quindi l'attesa sincrona può essere lunga.
Esempio: due brani di riferimento
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": "combina queste idee in un unico brano",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "song", "song_id": "a90438d2-35fc-4443-88f4-56531e6e5d24" }
]
}'
Esempio: brano di riferimento + voce legacy
{
"model": "suno-v6",
"description": "canta queste idee con questa voce",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "voice", "voice_id": "5813cbe1-36f1-414a-a9a8-4d399dfeb292" }
]
}
Esempio: brano di riferimento + immagine di riferimento
{
"model": "suno-v6",
"description": "cattura l'atmosfera di questa immagine",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
Errori sui parametri
Questi casi restituiscono HTTP 400, bloccati prima di qualsiasi addebito, quindi non costano nulla:
| Caso | Messaggio di errore |
|---|---|
| Più di 5 brani di riferimento | references supports at most 5 song references |
| Più di 1 voce | references supports at most 1 voice reference |
| Più di 1 immagine di riferimento | references supports at most 1 image reference |
type non valido |
references[0].type must be one of song, voice, image |
Brano senza song_id |
references[0].song_id is required |
| Brano non ancora completato | references[0].song_id must be a real completed clip |
| Stesso brano ripetuto | references[0].song_id is duplicated |
Il numero in
references[0]è l'indice di quell'elemento nell'array, quindi l'elemento che ha fallito è facile da individuare.
Risposta
Un array di brani, di solito con 2 attività o brani.
[
{
"song_id": "clip_id",
"song_title": "Brezza marina d'estate",
"status": "pending",
"description": "una canzone pop in mandarino vivace sull'estate al mare",
"audio_url": "",
"cover_url": "",
"video_url": "",
"model_version": "suno-v6",
"generation_type": "generate",
"created_at": "2026-05-21T10:00:00Z"
}
]
Modalità ricevuta di accettazione (opzionale, consigliata ai client che non devono tenere connessioni lunghe)
Per impostazione predefinita questo endpoint è sincrono: l'arrivo della risposta è ciò che significa che l'ordine è stato accettato, e le attese misurate possono arrivare a circa 230 secondi. Se il tuo client non deve tenere una connessione lunga, attiva la modalità ricevuta di accettazione — va bene una delle due:
- aggiungere
"accept_mode": "async"nel body della richiesta - aggiungere l'intestazione
X-Accept-Mode: async
Con essa attiva, l'endpoint restituisce subito HTTP 202, che significa solo «accettato e messo in coda di generazione», mentre la generazione continua in background:
{
"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" }
]
}
}
La fase di accettazione non restituisce un
song_id. Non esiste ancora un ID brano reale, e nérequest_idnétasks[].indexsono un ID brano — non salvarli comesong_id. Ilsong_idreale appare nella consultazione del progresso qui sotto.
Consultare il progresso dell'accettazione
Endpoint: GET /api/music/requests/{request_id} (gratis, autenticato con la stessa chiave API)
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" }
]
}
}
Cosa significa ogni valore di status:
| status | Significato |
|---|---|
queued |
Accettato, non ancora legato a brani specifici (tasks può essere un array vuoto) |
processing |
Passato alla generazione |
partial |
Uno dei due è già completato |
completed |
Entrambi completati, tasks[].song_id è leggibile |
failed |
Invio non riuscito, l'importo è stato rimborsato integralmente e error_message ne indica il motivo |
Ogni attività ha anche il proprio tasks[].status, con gli stessi valori della API di consultazione dei brani:
pending (inviata, in generazione), processing, completed, failed. Gli elementi di attività possono anche portare title,
duration e un audio_url già registrato; ciò che manca semplicemente non è ancora generato.
Quando hai il song_id reale, prosegui con la API di consultazione dei brani o con gli endpoint di download.
Esempio in 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": "una canzone pop vivace", "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
Compatibilità e note
- Senza
accept_mode, il comportamento è esattamente quello di prima: attesa sincrona, risposta200e array di brani. Le integrazioni esistenti non devono cambiare nulla. - Questo interruttore oggi funziona solo su
POST /api/music/createePOST /api/music/create/custom; gli altri endpoint di generazione non lo supportano ancora. - Invia anche un
Idempotency-Key(una tua stringa univoca, ≤128 caratteri): la stessa chiave inviata due volte viene accettata una sola volta, una ripetizione restituisce la stessa ricevuta e non viene addebitato nulla due volte. In modalità asincrona questo conta ancora di più. - Con
accept_mode=async,wait_completionviene ignorato (la ricevuta torna subito, senza aspettare i brani). - L'importo viene comunque pre-addebitato all'accettazione dell'ordine; una generazione fallita viene rimborsata integralmente in automatico.
- Limite del campo di testo:
descriptioncontiene al massimo 3000 caratteri (contati in caratteri Unicode, un carattere han conta come 1). Un testo più lungo restituisce subito HTTP400, non entra in generazione e non viene addebitato, e il messaggio di errore riporta la lunghezza misurata, per esempiodescription must not exceed 3000 characters; received 4120. Questo endpoint non ha campi testo/stile; per quelli vedi «Limite del campo di testo» nella API di generazione in modalità personalizzata. Le convenzioni generali sono in «Limiti dei campi di testo» della Panoramica della nuova API. - Senza
references, comportamento, prezzo e risposta sono esattamente quelli di prima: le integrazioni esistenti non devono cambiare nulla. - Quando è allegato materiale di riferimento (soprattutto più brani), preferisci la modalità ricevuta
accept_mode=asynca una lunga attesa sincrona; quanto tempo richieda la preparazione dipende dalla quantità e dalla provenienza del materiale.
Passi successivi
Se i brani non sono completati quando arriva la risposta, usa la API di consultazione dei brani per ottenere il risultato finale.
Esempio di integrazione Node/Electron
Se integri la generazione standard nel processo principale di Electron, in un server Node.js o in un client desktop, questo è il flusso consigliato:
- Chiama
POST /api/music/createper creare l'attività di generazione. - Leggi
song_idoiddalla risposta. - Chiama
POST /api/music/queryogni 2 secondi per controllare lo stato. - Considera la generazione conclusa non appena
audio_urlcompare nel risultato.
Smetti di usare i vecchi percorsi POST /api/generate o GET /api/clip?id=...; non fanno parte della superficie pubblica di integrazione attualmente consigliata.
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);
Nei progetti reali tieni la chiave API in una variabile d'ambiente del server, nelle impostazioni di un client desktop o in un archivio sicuro — mai nel codice front-end e mai committata in un repository.
Ottenere una chiave API
Dopo la registrazione puoi creare una chiave API nella console. Ogni generazione costa 0,6 ¥ e restituisce 2 brani, i download sono illimitati e non serve un numero di telefono.
Ottieni chiave API Torna alla panoramica