API d'envoi puis reprise en une étape
Description du point d'accès
L'envoi puis reprise en une étape transmet un fichier audio ou une URL d'audio et génère une nouvelle version de cover à partir de cet audio source.
Point d'accès : POST /api/music/upload-cover
Facturation : Payant, actuellement 0,6 ¥ par appel par défaut. Ce point d'accès est « envoyer puis faire un cover », il ne s'agit pas d'envoyer une pochette d'image. Le montant réellement facturé suit la configuration tarifaire actuelle du back-office.
Max Mode / Variety : ce point d'accès accepte les paramètres optionnels max_mode et variety (0-4). Avec
max_mode activé, cet appel est facturé au double (0,6 → 1,2 ¥ par appel) ; variety ne coûte rien
de plus. Leur signification et leur envoi sont décrits dans la section « Paramètres avancés » de la
Présentation de la nouvelle API.
Temps d'attente et timeouts (important) : c'est un point d'accès synchrone — la commande n'est acceptée et transmise à la génération qu'à l'arrivée de la réponse. D'après les mesures, la plupart des requêtes répondent en 1 à 3 secondes, environ 10 % prennent plus de 30 secondes et la plus longue avoisine 230 secondes. Réglez le timeout du client à 300 secondes ou plus ; l'absence de réponse ne signifie pas qu'aucune génération n'a eu lieu, et ne réessayez pas juste après un timeout (cela duplique la commande et refacture). Si la connexion a été coupée, vérifiez plus tard avec
GET /api/music/songs. Voir « Temps d'attente et réglage du timeout » dans la Présentation de la nouvelle API.
Quand l'audio est volumineux, il vaut mieux séparer « envoi » et « cover » en deux étapes (recommandé)
Ce point d'accès impose de mettre tout l'audio dans le corps de la requête : plus l'audio est gros, plus le corps est gros, et une simple instabilité réseau ou un timeout coupe le transfert à mi-chemin, après quoi le serveur renvoie
unexpected end of JSON input(HTTP 400, sans facturation).Quand l'audio dépasse environ 8 Mo, que le réseau est instable ou que le même matériel source sera réutilisé, passez à la forme en deux étapes :
POST /api/music/upload-sourceenvoie d'abord l'audio source — gratuit, réessayable à tout moment — et donne unclip_id;POST /api/music/generate-from-sourcelance le cover avec ceclip_id— le corps de l'étape facturée ne fait qu'environ 250 octets.Voir l'API d'envoi d'audio source, l'API de cover à partir d'un clip source, et « Fichiers volumineux et requêtes tronquées » en fin de page.
Paramètres de la requête
Headers
| Paramètre | Type | Obligatoire | Remarques |
|---|---|---|---|
| Authorization | string | oui | Bearer YOUR_API_KEY |
| Content-Type | string | oui | application/json |
Paramètres du body
| Paramètre | Type | Obligatoire | Par défaut | Remarques |
|---|---|---|---|---|
| model | string | non | suno-v6 | Nom de modèle côté client : suno-v6, suno-v6-wild ou suno-v6-mini |
| file_url | string | non | - | URL de l'audio source |
| file_base64 | string | non | - | Audio en Base64 |
| file_name | string | non | - | Nom du fichier |
| prompt | string | non | - | Nouvelles paroles ou direction de l'adaptation |
| style | string | non | - | Tags de style |
| title | string | non | - | Titre |
| negativeTags | string | non | - | Style négatif |
| instrumental | boolean | non | false | Morceau instrumental ou non |
| waitAudio | boolean | non | false | Attendre ou non la fin de l'audio |
| cover_start_s | number | non | - | Seconde de début du passage à reprendre |
| cover_end_s | number | non | - | Seconde de fin du passage à reprendre |
| audio_weight | number | non | - | Dépendance à l'audio de référence, plage 0.0-1.0 ; ne peut être envoyé que si un audio de référence est fourni |
cover_start_s et cover_end_s sont en secondes et acceptent des décimales ; le début doit être inférieur à la fin et ne peut pas dépasser la durée de l'audio source. Si les deux champs sont omis, c'est l'audio entier qui est utilisé. audio_weight correspond au metadata.control_sliders.audio_weight de Suno et contrôle à quel point le résultat s'appuie sur l'audio de référence ; il prend 0.0-1.0 et ne peut être inclus que lorsque la requête fournit un audio de référence valide via file_url ou file_base64. 0 est une valeur valide ; omettre le champ signifie « non spécifié » et conserve le comportement par défaut de Suno. instrumental et waitAudio doivent être des booléens JSON, pas des chaînes.
Le point d'accès d'envoi renvoie par défaut de façon asynchrone. Tant que clips[].status dans la réponse vaut pending, un audio_url vide est normal et ne signifie pas que l'envoi ou le cover a échoué ; conservez le song_id réel renvoyé et interrogez le point d'accès de consultation des morceaux jusqu'à la fin avant de lire l'adresse audio.
Exemple de requête
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": "Nouvelles paroles ou direction de l'adaptation",
"style": "Mandopop, acoustic guitar",
"title": "Version reprise",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
Réponse
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "Version reprise",
"status": "pending"
}
]
}
}
Fichiers volumineux et requêtes tronquées
Recommandé : séparer envoi et cover en deux étapes
Le point d'accès en une seule fois (celui-ci) réunit envoi et génération en une étape : le gros corps se trouve dans cette étape unique, donc en cas de rupture vous ne savez ni si quelque chose a été généré, ni si vous avez été facturé.
| Étape 1 envoi | Étape 2 cover | |
|---|---|---|
| Point d'accès | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| Facturation | Gratuit (envoi seulement, pas de génération) | 0,6 ¥ par appel ; 1,2 ¥ par appel avec Max Mode |
| Corps de la requête | L'audio lui-même (base64 / multipart), ou juste un lien via file_url |
Environ 250 octets (un seul sourceClipId) |
| Renvoie | clip_id (le clip ID de l'audio source) |
data.clips[].song_id (le résultat généré) |
| En cas d'échec | Réessayez simplement, aucune facturation et aucune tâche de génération | Réglez le timeout du client à ≥300 s ; en cas de timeout vérifiez d'abord avec /api/music/songs et ne réessayez pas tout de suite |
| Réutilisation du matériel source | Le même clip_id sert aussi pour étendre / remplacer / séparer |
L'audio doit être renvoyé à chaque fois |
Conclusion : audio de plus d'environ 8 Mo, réseau instable ou même matériel utilisé plusieurs fois → utilisez la forme en deux étapes ; audio minuscule sur réseau stable → ce point d'accès est plus simple.
Que signifie 400 unexpected end of JSON input
Cela signifie que le JSON reçu par le serveur est incomplet (ce n'est ni un paramètre mal écrit, ni un problème de droits ou de solde). Les causes habituelles, de la plus probable à la moins :
- Un gros corps tronqué en cours de transfert : la couche d'entrée enregistre à la fois « combien d'octets le client a déclaré » et « combien sont réellement arrivés ». Cas mesuré : le client déclarait 14,17 Mo et seulement 11,8–12,4 Mo sont arrivés, les trois requêtes s'arrêtant vers 1,6–1,7 s ; le nombre d'octets manquants différait à chaque fois, ce qui indique une coupure de transfert et non une limite fixe (le serveur ne plafonne pas la taille du corps).
Content-Lengthqui ne correspond pas aux octets réellement envoyés : en Node.js, utiliser le.lengthd'une chaîne (nombre de caractères UTF-16) comme longueur donne un résultat faux dès que le contenu comporte du chinois ou tout autre texte multi-octets.- Écrire le corps sous forme de chaîne plutôt que de Buffer, les octets écrits ne correspondant alors pas à ce qui est déclaré.
Les trois cas surviennent avant la facturation, donc aucun frais n'est généré.
Liste d'autocontrôle côté client
-
Content-Lengthprovient deBuffer.byteLength(json, 'utf8')(ouBuffer.from(json).length) — jamais dejson.length; - Le corps de la requête est écrit en Buffer, pas en chaîne ;
- Le timeout du socket / de la requête est ≥ 300 secondes ;
- Quand l'audio dépasse environ 8 Mo : utilisez
file_url(le corps ne fait que quelques centaines d'octets), ou l'envoi multipart deupload-source, ou passez directement à la forme en deux étapes ; - Pour les requêtes multipart, ne définissez pas
Content-Typeà la main (laissez le client ajouter le boundary) ; - Affichez les « octets réellement envoyés » et comparez-les au
Content-Length; - Dans la forme en deux étapes, vérifiez que l'étape 1 a renvoyé un
clip_idavec unstatusterminé avant d'envoyer l'étape 2.
Erreurs courantes
| Erreur | Signification | Que faire |
|---|---|---|
unexpected end of JSON input |
Corps de requête incomplet (tronqué) | Faites l'autocontrôle ci-dessus, ou passez à la forme en deux étapes |
invalid character '-' in numeric literal |
Un corps multipart a été envoyé à un point d'accès JSON | N'utilisez pas multipart sur les points d'accès JSON, et ne définissez pas Content-Type à la main |
one of file_path, file_base64, file_url, or multipart file is required |
Aucun audio n'a été fourni | Ajoutez file_base64 / file_url / un file multipart |
model is required |
Le corps était un JSON valide mais vide (par exemple {}) |
Envoyez au moins model |
Invalid request: Invalid request, ... |
Message d'enveloppe pour un corps non analysable | Lisez la seconde moitié pour la raison précise (souvent l'une des précédentes) |
Points d'accès liés : API d'envoi d'audio source (étape 1), API de cover à partir d'un clip source (étape 2).
Obtenir une clé d'API
Créez une clé d'API dans la console après votre inscription. Chaque génération coûte 0,6 ¥ et renvoie 2 pistes, les téléchargements sont illimités et aucun numéro de téléphone n'est requis.
Obtenir une clé d'API Retour à la présentation