API di caricamento e cover in un solo passaggio
Descrizione dell'endpoint
Caricamento e cover in un solo passaggio invia un file audio o un URL audio e genera una nuova versione cover da quell'audio di origine.
Endpoint: POST /api/music/upload-cover
Fatturazione: A pagamento, attualmente 0,6 ¥ per chiamata per impostazione predefinita. Questo endpoint è «carica e fai il cover», non si tratta di caricare una copertina immagine. 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.
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.
Quando l'audio è grande, conviene separare «caricamento» e «cover» in due passaggi (consigliato)
Questo endpoint richiede che tutto l'audio vada nel corpo della richiesta: più grande è l'audio, più grande è il corpo, e una singola instabilità di rete o un timeout interrompe il trasferimento a metà, dopo di che il server restituisce
unexpected end of JSON input(HTTP 400, nessun addebito).Quando l'audio supera circa 8 MB, la rete è instabile o lo stesso materiale di origine verrà riutilizzato, passa alla forma in due passaggi:
POST /api/music/upload-sourcecarica prima l'audio di origine — gratis, ripetibile in qualsiasi momento — e restituisce unclip_id;POST /api/music/generate-from-sourceavvia il cover con quelclip_id— il corpo del passaggio a pagamento è di soli circa 250 byte.Vedi l'API di caricamento dell'audio di origine, l'API di cover da un clip di origine e «File di grandi dimensioni e richieste troncate» in fondo a questa pagina.
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 |
|---|---|---|---|---|
| model | string | no | suno-v6 | Nome del modello lato cliente: suno-v6, suno-v6-wild o suno-v6-mini |
| file_url | string | no | - | URL dell'audio di origine |
| file_base64 | string | no | - | Audio in Base64 |
| file_name | string | no | - | Nome del file |
| prompt | string | no | - | Testo nuovo o direzione dell'adattamento |
| style | string | no | - | Tag di stile |
| title | string | no | - | Titolo |
| negativeTags | string | no | - | Stile negativo |
| instrumental | boolean | no | false | Se il brano è strumentale |
| waitAudio | boolean | no | false | Se attendere il completamento dell'audio |
| cover_start_s | number | no | - | Secondo iniziale del frammento da riprendere |
| cover_end_s | number | no | - | Secondo finale del frammento da riprendere |
| audio_weight | number | no | - | Dipendenza dall'audio di riferimento, intervallo 0.0-1.0; può essere inviato solo quando è fornito un audio di riferimento |
cover_start_s e cover_end_s sono in secondi e ammettono decimali; il tempo iniziale deve essere minore di quello finale e non può superare la durata dell'audio di origine. Se entrambi i campi sono omessi, si usa l'audio intero. audio_weight corrisponde al metadata.control_sliders.audio_weight di Suno e controlla quanto il risultato si appoggia all'audio di riferimento; assume 0.0-1.0 e può essere incluso solo quando la richiesta fornisce un audio di riferimento valido tramite file_url o file_base64. 0 è un valore valido; omettere il campo significa "non specificato" e mantiene il comportamento predefinito di Suno. instrumental e waitAudio devono essere booleani JSON, non stringhe.
L'endpoint di caricamento risponde per impostazione predefinita in modo asincrono. Finché clips[].status nella risposta è pending, un audio_url vuoto è normale e non significa che il caricamento o il cover siano falliti; salva il song_id reale restituito e interroga l'endpoint di consultazione dei brani fino al completamento prima di leggere l'indirizzo audio.
Esempio di richiesta
curl -X POST https://www.suno-api.io/api/music/upload-cover \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"file_url": "https://example.com/source.mp3",
"file_name": "source.mp3",
"prompt": "Testo nuovo o direzione dell'adattamento",
"style": "Mandopop, acoustic guitar",
"title": "Versione cover",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
Risposta
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "Versione cover",
"status": "pending"
}
]
}
}
File di grandi dimensioni e richieste troncate
Consigliato: separare caricamento e cover in due passaggi
L'endpoint in un solo passaggio (questo) unisce caricamento e generazione in un unico passaggio: il corpo grande sta in quell'unico passaggio, quindi quando si rompe non sai né se è stato generato qualcosa né se ti è stato addebitato.
| Passaggio 1 caricamento | Passaggio 2 cover | |
|---|---|---|
| Endpoint | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| Fatturazione | Gratis (solo caricamento, nessuna generazione) | 0,6 ¥ per chiamata; 1,2 ¥ per chiamata con Max Mode |
| Corpo della richiesta | L'audio stesso (base64 / multipart), o solo un link con file_url |
Circa 250 byte (solo un sourceClipId) |
| Restituisce | clip_id (il clip ID dell'audio di origine) |
data.clips[].song_id (il risultato generato) |
| Se fallisce | Riprova semplicemente, nessun addebito e nessuna attività di generazione | Imposta il timeout del client a ≥300 s; in caso di timeout verifica prima con /api/music/songs e non riprovare subito |
| Riutilizzo del materiale di origine | Lo stesso clip_id vale anche per extend / replace / separazione |
L'audio va ricaricato ogni volta |
Conclusione: audio oltre circa 8 MB, rete instabile o stesso materiale usato più volte → usa la forma in due passaggi; audio minuscolo su rete stabile → questo endpoint è più comodo.
Che cosa significa 400 unexpected end of JSON input
Significa che il JSON ricevuto dal server è incompleto (non è un parametro sbagliato, né un problema di permessi o di saldo). Le cause abituali, dalla più probabile:
- Un corpo grande troncato a metà trasferimento: il livello di ingresso registra sia «quanti byte ha dichiarato il client» sia «quanti ne sono arrivati davvero». Caso misurato: il client dichiarava 14,17 MB e ne sono arrivati solo 11,8–12,4 MB, e tutte e tre le richieste si sono fermate intorno a 1,6–1,7 s; il numero di byte mancanti era diverso ogni volta, il che indica un'interruzione del trasferimento e non un limite fisso (il server non limita la dimensione del corpo).
Content-Lengthche non corrisponde ai byte realmente inviati: in Node.js usare.lengthdi una stringa (conteggio di caratteri UTF-16) come lunghezza sbaglia non appena il contenuto include cinese o altro testo multi-byte.- Scrivere il corpo come stringa invece che come Buffer, per cui i byte scritti non corrispondono a quanto dichiarato.
Tutti e tre i casi avvengono prima dell'addebito, quindi non generano costi.
Lista di autocontrollo lato client
- Il
Content-Lengthderiva daBuffer.byteLength(json, 'utf8')(oBuffer.from(json).length) — mai dajson.length; - Il corpo della richiesta è scritto come Buffer, non come stringa;
- Il timeout del socket / della richiesta è ≥ 300 secondi;
- Quando l'audio supera circa 8 MB: usa
file_url(il corpo è di poche centinaia di byte), oppure il caricamento multipart diupload-source, oppure passa direttamente alla forma in due passaggi; - Nelle richieste multipart non impostare
Content-Typea mano (lascia che sia il client ad aggiungere il boundary); - Stampa i «byte realmente inviati» e confrontali con
Content-Length; - Nella forma in due passaggi, verifica che il passaggio 1 abbia restituito un
clip_idconstatuscompletato prima di inviare il passaggio 2.
Errori frequenti
| Errore | Significato | Cosa fare |
|---|---|---|
unexpected end of JSON input |
Corpo della richiesta incompleto (troncato) | Fai l'autocontrollo sopra, oppure passa alla forma in due passaggi |
invalid character '-' in numeric literal |
Un corpo multipart è stato inviato a un endpoint JSON | Non usare multipart sugli endpoint JSON e non impostare Content-Type a mano |
one of file_path, file_base64, file_url, or multipart file is required |
Nessun audio fornito | Aggiungi file_base64 / file_url / un file multipart |
model is required |
Il corpo era JSON valido ma vuoto (per esempio {}) |
Invia almeno model |
Invalid request: Invalid request, ... |
Messaggio involucro di un corpo non analizzabile | Leggi la seconda metà per il motivo concreto (di solito uno dei precedenti) |
Endpoint correlati: API di caricamento dell'audio di origine (passaggio 1), API di cover da un clip di origine (passaggio 2).
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