【Aanbevolen】 stemprofiel-API
✅ Deze keten raden we aan voor nieuwe integraties. Uit de praktijkbeoordelingen van veel gebruikers blijkt dat nummers die via deze keten zijn gemaakt de oorspronkelijke stem goed behouden: de zang in de eindmix lijkt meer op de persoon uit het monster dat je hebt geüpload. Daarom is dit momenteel de route die we klanten aanbevelen.
Ter vergelijking: de eerdere API voor stemklonen en genereren met een opgegeven stem werkt nog, maar de navigatie markeert die als "niet aanbevolen" en voor nieuwe integraties wordt die niet meer aangeraden.
- Documentdatum: 2026-09-26
- Bereik: je eigen stem aanmaken → daarmee een gekozen nummer coveren / een nieuw nummer zingen → voortgang volgen → het resultaat downloaden
- Alle endpoints, velden en antwoorden zijn met echte aanroepen geverifieerd (wat als "gemeten" staat, is in detail geverifieerd)
Opmerking: dit document beschrijft alleen de endpoints die je aanroept. Mediaverwerking, taakplanning en inhoudsvalidatie doet de server automatisch; de client implementeert die niet.
0. Binnen vijf minuten aan de slag
Vier stappen volstaan om van één stemmonster twee afgeronde nummers te maken.
① Stem aanmaken POST /api/music/voice-profile/create → voice_id ophalen (status=ready)
② Coveren POST /api/music/voice-profile/cover → meteen 2 song_id ophalen
③ Volgen POST /api/music/query → pollen tot status=completed
④ Downloaden GET /api/music/download?song_id=…&kind=mp3
Minimaal werkvoorbeeld (curl):
API_KEY="sk-jouw-sleutel"
BASE="https://www.suno-api.io"
# ① Stem aanmaken (een stemmonster uploaden; 10 s of meer, onder 10 MB aanbevolen)
curl -sS -X POST "$BASE/api/music/voice-profile/create" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@./my-voice.mp3" \
-F "title=Mijn stem" \
-F "source_kind=upload"
# → {"success":true,"message":"","data":{"voice_id":"vp_2026…","status":"ready", …}}
# ② Een nummer coveren met die stem (song_clip_id = de clip id van het nummer)
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]\ntekst van het lied…",
"style_requirements": "langzame folk, akoestische gitaar",
"audio_weight": 0.85,
"max_mode": false
}'
# → {"code":200,"message":"success","data":{"resolved_scene":"cover","clips":[{…},{…}]}}
# ③ Pollen (meerdere id's tegelijk, kommagescheiden)
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"}'
# ④ Na afronding de mp3 downloaden (alleen bij status=completed krijg je een bestand)
curl -sS -L "$BASE/api/music/download?song_id=id1&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song1.mp3
1. Algemene afspraken
1.1 Domein en omgeving
| Omgeving | Base URL | Doel |
|---|---|---|
| Productie | https://www.suno-api.io |
Echt klantverkeer |
Alle paden hieronder zijn relatief aan de Base URL; het volledige adres van POST /api/music/voice-profile/create is bijvoorbeeld
https://www.suno-api.io/api/music/voice-profile/create.
1.2 Authenticatie
Alle endpoints gebruiken dezelfde verzoekheader, met als waarde de API-sleutel die je in de console hebt aangemaakt:
Authorization: Bearer sk-xxxxxxxx
- Het voorvoegsel
Beareris optioneel; dat vansk-ook (Authorization: sk-xxxwerkt net zo goed). - Sleutel ontbreekt of is ongeldig → HTTP 401, met een body als
{"success":false,"message":"…"}(de tekst volgt de taal van het verzoek). - Elke sleutel ziet en bewerkt alleen de nummers en stemmen van het eigen account.
1.3 Indelingen van de verzoekbody
- Stem aanmaken:
multipart/form-data(een bestand uploaden) wordt aanbevolen;application/json(een URL of base64) wordt ook ondersteund. - Alle andere endpoints:
application/json.
1.4 Twee antwoordomhulsels (de klant hoeft alleen deze twee te kennen)
De endpoints voor "stembeheer" (create / create-from-clip / list / detail / delete) gebruiken het zakelijke omhulsel:
{ "success": true, "message": "", "data": { } }
{ "success": false, "message": "voice_id is required" }
"Coveren met een stem" loopt via het generatiekanaal en gebruikt het generatie-omhulsel: succes is code/message/data, mislukking is een error-object:
{ "code": 200, "message": "success", "data": { } }
{ "error": { "message": "voice not found: vp_xxx", "type": "bad_response_status_code", "param": "", "code": "bad_response_status_code" } }
Hoe je beslist: kijk eerst naar de HTTP-statuscode, dan naar success === false, en tot slot naar code !== 200 of de aanwezigheid van error.
Een zakelijke fout garandeert geen HTTP anders dan 200 (de endpoints voor stembeheer geven bij een fout nog steeds HTTP 200), dus je mag niet alleen op de statuscode afgaan.
1.5 Idempotentie
Een stem aanmaken (inclusief "aanmaken uit bestaande audio") is echt idempotent: onder dezelfde sleutel maakt het opnieuw sturen van hetzelfde client_request_id maar één stem en geeft de tweede poging direct het eerste resultaat terug (success=true, hetzelfde voice_id). Het is de bedoeling dat de client zelf een id genereert (een UUID bijvoorbeeld) en bij een nieuwe poging na een timeout dezelfde waarde hergebruikt.
Het insturen van een cover dedupliceert niet op verzoekniveau (het is een gefactureerde generatie), dus let op twee dingen:
- De inzendidentificatie staat in de header
X-Create-Ui-Client-Request-Id: <jouw inzend-id>. Die wordt in het server-side taakrecord geschreven om later onderzoek te vergemakkelijken; die voorkomt geen dubbele afschrijving. - Een timeout ≠ een mislukking: het verzoek kan al zijn aangenomen en aan het genereren zijn. Controleer vóór een nieuwe poging met
GET /api/music/songs?p=1&page_size=20(de pagineringsparameters zijnp/page_size; de compatibele spellingpswerkt ook) of er al een nieuw nummer metgeneration_type=voice_profile_coveris verschenen, en stuur hetzelfde verzoek alleen opnieuw als dat niet zo is.
De bodies van create en create-from-clip accepteren ook een veld client_request_id (zie §3 en §4).
1.6 Overzicht van de facturering
| Actie | Endpoint | Prijs | Opmerkingen |
|---|---|---|---|
| Stem aanmaken (standaard) | POST /api/music/voice-profile/create |
Gratis | Het uploaden van een monster verbruikt geen Suno-tegoed |
| Stem aanmaken (uit bestaande audio) | POST /api/music/voice-profile/create-from-clip |
Gratis | De server registreert alleen een verwijzing naar het materiaal; er wordt niets opnieuw geüpload |
| Versterkte kloon | Hetzelfde, enhanced=true |
Tegen de "prijs voor versterkte upload" (standaard 10 ¥ per aanroep) | Asynchroon; bij een fout automatisch terugbetaald |
| Coveren met stem | POST /api/music/voice-profile/cover |
1,2 ¥ per aanroep; 2,4 ¥ per aanroep bij max_mode=true |
Levert 2 nummers per aanroep |
| Opvragen / lijst / details / verwijderen | — | Gratis | |
| Downloaden (zelf de directe link pakken) | De audio_url uit het antwoord |
Gratis | Speelt het uitgegeven adres af |
| Downloaden (omzetten naar wav / songtekst enz.) | POST /api/music/free2 |
0,2 ¥ per geslaagd nummer | Zie §8 |
Prijzen zijn op elk moment via een openbaar endpoint te lezen, dus hardcodeer ze niet (zie §9):
curl -sS https://www.suno-api.io/api/pricing/catalog | jq '.data.catalog.meta'
# {
# "generation_price": "0.6",
# "voice_generation_price": "1.2", ← basisprijs voor coveren met stem
# "max_mode_factor": "2",
# "enhanced_upload_price": "10", ← prijs voor de versterkte kloon
# "voice_auto_verify_price": "5",
# "voice_long_term_clone_price": "5"
# }
Coveren werkt met vooraf afschrijven + terugbetalen bij mislukking:
- Een afgewezen verzoek (verkeerde parameters, een 4xx/5xx van het platform, onvoldoende saldo op zich) wordt niet afgeschreven — bij een inzending met een niet-bestaande stem bleef het saldo in onze metingen volledig gelijk (delta = 0);
- Een aangenomen taak die uiteindelijk mislukt (inclusief een dienstfout van het platform) loopt via het terugbetalingspad van de server en geeft het vooraf afgeschreven bedrag terug.
1.7 Statuswoordenboek
De status van de stem:
| Waarde | Betekenis | Bruikbaar voor covers |
|---|---|---|
ready |
Gereed | ✅ |
processing |
Komt alleen voor bij een versterkte kloon (enhanced=true); in verwerking |
❌ (wacht op ready) |
failed |
Aanmaken mislukt; zie error_message; bij een versterkte kloon is al terugbetaald |
❌ |
De status van het nummer (de waarde die de opvraag-endpoints teruggeven):
| Waarde | Betekenis | Downloadbaar |
|---|---|---|
submitted / queued / processing |
Wordt gegenereerd (een preview-stream kan al bestaan) | ❌ |
completed |
Klaar | ✅ |
failed |
Mislukt; de afschrijving is terugbetaald | ❌ |
2. Overzicht van de endpoints
| # | Methode | Pad | Doel | Facturering |
|---|---|---|---|---|
| 1 | POST | /api/music/voice-profile/create |
Stem aanmaken (upload / URL / base64) | Gratis (behalve enhanced=true) |
| 2 | POST | /api/music/voice-profile/create-from-clip |
Stem aanmaken uit eigen audio | Gratis |
| 3 | GET | /api/music/voice-profile/list |
Lijst met stemmen | Gratis |
| 4 | GET | /api/music/voice-profile/{voice_id} |
Details van de stem (inclusief voortgang van de versterkte kloon) | Gratis |
| 5 | POST | /api/music/voice-profile/delete |
Stem verwijderen | Gratis |
| 6 | POST | /api/music/voice-profile/cover |
Coveren met de stem / een nieuw nummer zingen | 1,2 ¥ (MAX 2,4) |
| 7 | POST | /api/music/query |
Nummerstatus in bulk opvragen | Gratis |
| 8 | GET | /api/music/songs/{song_id} |
Details van één nummer | Gratis |
| 9 | GET | /api/music/download |
Het eindbestand downloaden | Gratis (mp3/afspeellink) |
| 10 | POST | /api/music/free2 |
Omzetten naar wav / songtekst enz. | 0,2 ¥ per geslaagd nummer |
| 11 | POST | /api/music/free2/cached |
Een al gearchiveerd downloadadres ophalen | Gratis |
| 12 | GET | /api/music/songs |
Mijn werken, gepagineerd | Gratis |
3. Een stem aanmaken
POST /api/music/voice-profile/create
Registreer een stuk zang-audio als "stem" en krijg een voice_id. Voor het platform is een stem simpelweg "een audio + de clip daarvan in de catalogus", dus na een geslaagde aanmaak blijft die bronaudio permanent bewaard (voor latere covers).
3.1 Drie invoervormen (kies er één)
Vorm A: multipart bestand uploaden (aanbevolen)
Content-Type: multipart/form-data
file=<audio-binaire data> # verplicht
title=<naam van de stem> # optioneel; leeg betekent de bestandsnaam zonder extensie
file_name=<oorspronkelijke bestandsnaam>
source_file_name=<oorspronkelijke bestandsnaam>
source_kind=upload|record # optioneel, herkomstaanduiding (upload / opname); standaard upload
enhanced=false|true # optioneel, true = versterkte kloon (zie §3.5)
client_request_id=<idempotentiesleutel> # optioneel
voice_id=<eigen ID> # optioneel, zelden gebruikt
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=Mijn stem" \
-F "source_kind=upload"
Vorm B: JSON + een openbare audio-URL
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": "Mijn stem"
}'
- De URL moet een publiek bereikbare HTTPS-directlink zijn; de server downloadt die één keer en zet hem in onze objectopslag.
- Je kunt het adres ook in het veld
audio_urlzetten, het effect is gelijk (bij beide wintfile_url). - Staat het adres al op de objectopslag van dit platform (
*.myqcloud.com/create-ui/voice-source/...), dan wordt er niets opnieuw gedownload: het wordt direct geregistreerd.
Vorm C: JSON + base64
{
"file_base64": "data:audio/mpeg;base64,//uQxAAA…",
"file_name": "my-voice.mp3",
"title": "Mijn stem"
}
- Zowel het voorvoegsel
data:audio/xxx;base64,als pure base64 wordt geaccepteerd. - De grootte is beperkt (base64 blaast met 1,33× op), gebruik voor grote bestanden vorm A.
3.2 Eisen aan de audio
| Punt | Eis | Opmerkingen |
|---|---|---|
| Grootte | ≤ 10 MB | Boven de limiet kapt de gateway de body af, wat eruitziet als "door Suno geweigerd"; comprimeer of kort eerst in |
| Duur | Minimaal 6 s; 10–60 s aanbevolen | Onder de 6 s weigert het platform: Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
| Formaat | mp3 / wav / m4a / aac / flac / ogg | Bepaald aan de hand van de bestandsextensie |
| Inhoud | Schone zang; vermijd afgeronde covers of originele nummers met begeleiding | Audio die sterk lijkt op een bestaande opname in de catalogus wordt geweigerd: This audio matches an existing recording in our catalog. (gemeten) |
3.3 Antwoord
{
"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": "Mijn stem",
"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
}
}
Veldenoverzicht (create / list / detail delen dezelfde set velden):
| Veld | Type | Opmerkingen |
|---|---|---|
voice_id |
string | Het stem-ID; covers gebruiken die daarna |
clip_id / song_id |
string | De clip id van die stem-audio aan Suno's kant (beide zijn gelijk); voor diagnose |
account_id |
string | Het account dat het draagt (voor diagnose; de client hoeft er niets mee) |
title |
string | Naam van de stem |
source_file_name |
string | Oorspronkelijke bestandsnaam |
audio_url |
string | Langdurige directlink naar de bronaudio, bruikbaar voor preview; permanent bewaard |
image_url |
string | Stemhoes (die Suno voor zang-audio maakt); is er geen hoes, dan ontbreekt de sleutel volledig |
duration_s |
number | Lengte van het stemmonster in seconden |
enhanced |
bool | Of het als versterkte kloon is aangemaakt |
source_kind |
string | upload / record / clip (uit bestaande audio) |
status |
string | ready / processing / failed |
error_message |
string | Reden van de mislukking; alleen bij failed |
task_id |
number | Onderliggend taaknummer van de versterkte kloon; alleen bij enhanced=true |
pre_consumed_quota |
number | Vooraf afgeschreven tegoed (alleen bij een versterkte kloon) |
created_at / updated_at |
number | Unix-seconden |
created_at/updated_atzijn tijdstempels in seconden (10 cijfers), niet in milliseconden.
3.4 Veelvoorkomende fouten
| HTTP | message | Oorzaak en aanpak |
|---|---|---|
| 200 | one of file_path, file_base64, or file_url is required |
Er is geen audio-inhoud meegestuurd |
| 200 | Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. |
Het monster is te kort; gebruik ≥6 s (≥10 s aanbevolen) |
| 200 | This audio matches an existing recording in our catalog. |
Het monster lijkt sterk op een bestaande opname in de catalogus; gebruik andere schone droge zang |
| 200 | upload succeeded without clip or account identity |
Het antwoord van het platform was afwijkend; probeer opnieuw |
| 200 | audio file exceeds 30 MB limit |
Boven de serverlimiet (blijf voor klanten binnen 10 MB) |
| 401 | invalid token |
Verkeerde API-sleutel |
3.5 Versterkte kloon (enhanced=true)
Voor gevallen waarin "het stemmonster zelf beschermde songtekst bevat / een versterkte upload nodig is". De prijs is die van de versterkte upload (standaard 10 ¥ per aanroep, bij een fout automatisch terugbetaald):
- Het antwoord is direct
status=processing+task_id(nog zonderclip_id) en loopt asynchroon; - Tijdens de verwerking vraag je de voortgang op met
GET /api/music/voice-profile/{voice_id}; die geeftprogress_percent/progress_stage/progress_message; - Bij afronding wordt
statusreadyen wordenclip_id,audio_url,image_urlaangevuld; - Bij een fout wordt
status=faileden luidterror_messageongeveer "de versterkte upload is mislukt; het bedrag is automatisch terugbetaald, probeer het later opnieuw"; - Een versterkte kloon duurt duidelijk langer dan een standaardaanmaak (minuten), wacht er dus niet op met een synchrone timeout.
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=Mijn stem" -F "enhanced=true"
4. Een stem aanmaken uit bestaande audio
Wil je niet opnieuw uploaden: kopieer audio die je al hebt geüpload of al hebt gegenereerd direct naar een stem. Gratis en idempotent.
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: de clip id van afgeronde audio in je account (gelijk aan desong_idvan het nummer).- Dezelfde clip opnieuw insturen maakt geen nieuw record: je krijgt de bestaande stem direct terug met
reused: true(gemeten).
Het antwoord is alle velden uit §3.3 plus twee alleen-lezen velden:
| Veld | Opmerkingen |
|---|---|
reused |
true = deze audio was al je stem en wordt hergebruikt |
source_type |
Waar de audio vandaan komt: 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"
}
}
Fouten (de message zoals teruggegeven; het is aanbevolen die direct te tonen of te lokaliseren):
| message | Betekenis |
|---|---|
source audio not found |
De clip bestaat niet of is niet van jou |
source audio is invalid |
Die audio wordt nog gegenereerd / is een tussenproduct en nog niet bruikbaar |
source_song_id is required |
source_song_id is niet meegestuurd |
5. Lijst / details / verwijderen van stemmen
5.1 Lijst
GET /api/music/voice-profile/list
GET /api/music/voice-profile/list?include_deleted=true
{
"success": true,
"message": "",
"data": {
"items": [ { "voice_id": "vp_…", "title": "Mijn stem", "status": "ready", "audio_url": "…", "image_url": "…" } ],
"total": 1
}
}
De velden zijn precies die van §3.3. Verwijderde stemmen worden standaard niet teruggegeven.
5.2 Details
GET /api/music/voice-profile/{voice_id}
Geeft één stemobject terug (data is het object zelf, geen array). Loopt er een versterkte kloon, dan komen er extra bij:
| Veld | Opmerkingen |
|---|---|
progress_percent |
Geheel getal van 0 tot 100 |
progress_stage |
Faseaanduiding, bijvoorbeeld media_preparing |
progress_message |
Voortgangstekst om aan de gebruiker te tonen |
5.3 Verwijderen
POST /api/music/voice-profile/delete
Content-Type: application/json
{ "voice_id": "vp_2026…" }
{ "success": true, "message": "", "data": { "voice_id": "vp_2026…", "status": "deleted" } }
- Na het verwijderen verdwijnt de stem uit de lijst en kan die niet meer voor nieuwe covers worden gebruikt: insturen met dat
voice_idgeeft 400 (zie §6.4). - Nummers die er al mee zijn gemaakt blijven volledig onaangetast; afspelen, downloaden, verlengen, vervangen en scheiden werken zoals voorheen.
- Het verwijderen van een niet-bestaande stem, of een die niet bij dit account hoort, geeft
{"success":false,"message":"voice not found"}.
6. Coveren met een stem (het kern-endpoint)
POST /api/music/voice-profile/cover
Content-Type: application/json
Eén inzending genereert 2 nummers (net als de gewone generatie).
6.1 Twee scenario's
| Scenario | Trigger | Opmerkingen |
|---|---|---|
| A. Een gekozen nummer coveren | song_clip_id is meegestuurd |
Zingt dat nummer met jouw stem (melodie / ritme / secties blijven als het origineel; de zang wordt jouw stem) |
| B. Een nieuw nummer zingen met de stem | song_clip_id niet meegestuurd |
Alleen de stem + songtekst (optioneel) + stijlvoorkeuren; het model componeert een nieuwe melodie in die stijl en zingt die |
De resolved_scene in het antwoord geeft cover of sing terug, zodat je kunt zien welke route is gevolgd.
6.2 Verzoekvelden
| Veld | Type | Verplicht | Standaard | Opmerkingen |
|---|---|---|---|---|
model |
string | Ja | — | Modelnaam voor de klant, zie §6.5. Zonder dit krijg je model is required (HTTP 500) |
voice_id |
string | Een van de twee | — | Stem-ID (vp_…); moet status=ready zijn |
voice_clip_id |
string | Een van de twee | — | De clip id van de stem kan ook; bij beide wint voice_id |
song_clip_id |
string | Nee | leeg | Clip id (song_id) van het te coveren nummer. Niet meegestuurd = scenario B |
lyrics |
string | Nee | leeg | Volledige songtekst, teken voor teken meegestuurd zonder herschrijven of inkorten; ≤ 3000 tekens |
cover_requirements |
string | Nee | leeg | Coverinstructies in natuurlijke taal, bijvoorbeeld "duidelijker articuleren". Ze worden aan een vaste prompt geplakt |
style_requirements |
string | Nee | leeg | Stijlvoorkeuren, bijvoorbeeld "langzame folk, akoestische gitaar" |
title |
string | Nee | leeg | De titel van deze twee nummers in de werkruimte (beïnvloedt de song_title in latere opvragingen) |
negative_tags |
string | Nee | leeg | Uit te sluiten stijlen, bijvoorbeeld elektronisch, rap; ≤ 1000 tekens |
vocal_gender |
string | Nee | leeg | m / f (accepteert ook male / female); leeg = maakt niet uit |
duration |
number | Nee | leeg | Gewenste lengte in seconden, een geheel getal van 1 tot 480; leeg = het platform beslist. Het praktische minimum van het platform is ongeveer 30 s: kleinere waarden gaven in onze metingen nog steeds nummers van ongeveer 30 seconden |
audio_weight |
number | Nee | 0,85 | Audio Influence, een decimaal van 0 tot 1. Hoger blijft dichter bij het stemmonster |
style_weight |
number | Nee | leeg | Stijlinvloed, een decimaal van 0 tot 1 |
weirdness_constraint |
number | Nee | leeg | Creativiteit, een decimaal van 0 tot 1 (gebruikt je interface percentages, deel dan door 100) |
variety |
number | Nee | leeg | Variatie, een geheel getal van 0 tot 4 (geen percentage), alleen op v6-modellen |
max_mode |
boolean | Nee | false |
Max Mode, prijs ×2 |
client_request_id |
string | Nee | leeg | Inzendidentificatie, wordt voor diagnose in het server-side taakrecord geschreven (geen deduplicatie) |
Stuur ook de header X-Create-Ui-Client-Request-Id: <hetzelfde inzend-id> mee: alleen die wordt in het server-side taakrecord geschreven en dient als sleutel voor later onderzoek (zie §1.5).
Eenheden oppassen: audio_weight / style_weight / weirdness_constraint zijn decimalen van 0 tot 1, variety is een geheel getal van 0 tot 4 en duration is in seconden. Verwarring leidt tot afwijzing of vreemde resultaten.
De songtekst is optioneel in scenario B (het model redt zichzelf), maar stuur altijd lyrics als er een bepaalde tekst gezongen moet worden.
6.3 Antwoord
{
"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": "[Taak] Dit is een cover. … (het vaste structuurdeel van de server + jouw cover- / stijlvoorkeuren)"
},
{
"song_id": "7c91…",
"status": "processing",
"model_version": "suno-v6",
"audio_url": ""
}
],
"source_updates": []
}
}
Kernpunten:
- Identificeer de eindnummers met
clips[].song_id(dit endpoint geeft geen veldidterug). - Je krijgt direct 2
song_id-waarden, terwijlstatusnogprocessingis (dat betekent alleen "aangenomen") enaudio_urlleeg is; je moet pollen totcompletedvoordat je kunt downloaden.play_urlis de preview-stream van het platform, kan al bij het insturen verschijnen en verloopt. descriptionis de prompt die de server uiteindelijk stuurt (het vaste structuurdeel + decover_requirements/style_requirementsdie je hebt ingevuld); die is erg handig bij het onderzoeken van een resultaat.source_updatesis het resultaat van de mediaverwerking van de server en mag de client negeren.- De
titledie je stuurt, wordt in het server-side taakrecord geschreven en verschijnt in latere opvragingen alssong_title; datclips[].song_titlein het inzendantwoord leeg is, is normaal.
6.4 Fouten
{ "error": { "message": "deze stem bestaat niet of is verwijderd (voice_id=vp_xxx)…", "type": "new_api_error", "param": "", "code": "invalid_request" } }
| HTTP | message | Oorzaak |
|---|---|---|
| 500 | model is required |
In de body ontbreekt model (een verplicht veld voor kanaalkeuze) |
| 400 | voice_id is required and must be a ready voice |
voice_id niet meegestuurd, of een plaatsaanduidingswaarde / niet-gereed stem meegestuurd |
| 400 | deze stem bestaat niet of is verwijderd (voice_id=vp_xxx)… |
De stem is verwijderd, bestaat niet of hoort niet bij het huidige account. Gebruik een andere beschikbare stem of maak een nieuwe aan |
| 400 | deze stem is verwijderd (voice_id=vp_xxx)… |
Bij het direct doorgeven van materiaal via voice_clip_id is de stem van dat materiaal verwijderd; zelfde aanpak als hierboven |
| 400 | voice is not ready yet (status=processing) |
De stem wordt nog aangemaakt; wacht op ready en probeer opnieuw |
| 400 | song_clip_id must be a real completed clip |
song_clip_id is een plaatsaanduiding / niet afgerond |
| 400 | song_clip_id must differ from the voice clip |
Het coverdoel kan niet het stemmonster zelf zijn |
| 400 | audio_weight must be a number between 0 and 1 |
Verkeerde eenheid op de schuifregelaar (een percentage meegestuurd) |
| 400 | duration must be an integer between 1 and 480 seconds |
De duur is geen geheel getal van 1 tot 480 |
| 400 | vocal_gender must be one of m, f, male, female |
Ongeldige geslachtswaarde |
| 400 | variety must be an integer between 0 and 4 / variety is only supported on v6 models |
Ongeldige variatiewaarde of niet-ondersteund model |
Onvoldoende saldo geeft direct bij het insturen een factureringsfout en laat nooit een half afgeronde taak achter.
6.5 Beschikbare modellen (klantnamen)
| Modelnaam | Opmerkingen |
|---|---|
suno-v6 |
Standaard, aanbevolen |
suno-v6-wild |
Losser |
suno-v6-mini |
Lichtgewicht |
Gebruik de modelnamen voor klanten (die hierboven). chirp-* zijn interne platformnamen en mogen niet direct worden gebruikt.
7. Voortgang volgen
7.1 Bulk-opvraging (aanbevolen)
POST /api/music/query
Content-Type: application/json
{ "model": "suno-v6", "song_ids": "id1,id2" }
song_idsis een kommagescheiden tekenreeks (geen array).- Het antwoord is een kale array (direct
[...], zondersuccess/data-omhulsel):
[
{
"song_id": "0f2a…",
"song_title": "Twee tijgers",
"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": "[Taak] Dit is een cover. … (de uiteindelijke prompt van de server)",
"style_tags": "…",
"created_at": "2026-09-25T18:19:09.918Z",
"video_url": ""
}
]
| Veld | Opmerkingen |
|---|---|
status |
Zie §1.7; alleen completed geldt als klaar |
audio_url |
mp3-directlink; alleen gevuld vanaf completed |
cover_url |
Adres van de hoes |
duration |
Werkelijke lengte in seconden |
generation_type |
Nummers uit een cover met stem zijn altijd voice_profile_cover |
play_url |
Ondertekend previewadres (verloopt) |
song_title |
Taaktitel (de title die je stuurde; zonder opgave zet de server een terugvalwaarde) |
lyrics / prompt |
Eindtekst / oorspronkelijke songtekst |
description |
De uiteindelijk verzonden prompt (inclusief het vaste structuurdeel) |
style_tags |
De uiteindelijke stijlbeschrijving |
created_at |
Een ISO 8601-tekenreeks (let op: anders dan de Unix-seconden van het detail-endpoint) |
Advies voor pollen: elke 5–10 seconden, met een totale timeout van 10–15 minuten (het traagste gemeten koude account deed er ongeveer 4,5 minuut over; zeer weinig doen er langer over). Beoordeel de afronding niet aan een lege audio_url, maar aan status.
Compatibiliteitsnotitie: dit endpoint identificeert nummers met
song_id; in enkele vroege antwoorden stond een veldid, dusrow.song_id || row.idis de veilige manier om het te lezen.
7.2 Details van één nummer
GET /api/music/songs/{song_id}
{
"success": true,
"data": {
"song_id": "0f2a…",
"title": "Twee tijgers",
"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": "Twee tijgers",
"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"]
}
}
}
- Hier zijn
created_at/completed_atUnix-seconden (anders dan de ISO-tekenreeksen van de bulk-opvraging, dus clients moeten ze onderscheiden). wav_url/video_urlzijn de downloadingangen van dit platform (relatief aan het huidige domein) en eenGEThaalt het bestand op; ze zijn leeg wanneer het platform dat materiaal niet heeft gemaakt.parameter_retentionzegt op welke inzendparameters dat nummer terug te voeren is:core_parameters_available=truebetekent dat kernparameters (songtekst / stijl / bron) opvraagbaar zijn, en bijextended_parameters_available=falsezijn de hierboven genoemde uitgebreide parameters niet bewaard (covers met stem vallen momenteel in deze categorie).
7.3 Mijn werken
GET /api/music/songs?p=1&page_size=20
GET /api/music/songs?status=completed&q=trefwoord
Pagineringsparameters: p (paginanummer vanaf 1) / page_size (items per pagina; ps is een compatibele spelling). Optioneel status en q (een trefwoord in de titel). Standaard gesorteerd op aanmaaktijd aflopend.
{
"success": true,
"data": {
"page": 1,
"page_size": 20,
"total": 42,
"items": [
{
"song_id": "0f2a…",
"title": "Twee tijgers",
"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
}
]
}
}
Met generation_type=voice_profile_cover onderscheid je "nummers uit een cover met stem" van andere generatieresultaten.
8. De eindnummers downloaden
8.1 De mp3 direct pakken (aanbevolen, gratis)
Alle drie werken; kies er één:
- De
audio_urluit het opvraagresultaat gebruiken (een directlink naar de objectopslag, het eenvoudigst). GET /api/music/download?song_id=<id>&kind=mp3→ geeft direct de audiostream als bytes terug (met de bestandsnaam al inContent-Disposition).POST /api/music/download-url(voor een ondertekend tijdelijk adres).
curl -sS -L "https://www.suno-api.io/api/music/download?song_id=0f2a…&kind=mp3" \
-H "Authorization: Bearer $API_KEY" -o song.mp3
kind-waarden: mp3 (gelijk aan song) / playback (streamend afspelen) / wav / video / lyrics / timestamped_lyrics.
timestamped_lyrics (.lrc) is voorlopig alleen voor sommige nummers beschikbaar; mislukt het, maak het bestand dan zelf met de API voor songtekst met tijdstempels.
Het antwoord is de ruwe bestandsstroom, met Content-Type en Content-Disposition (bestandsnaam) al ingesteld; de wav_url / video_url uit GET /api/music/songs/{song_id} zijn dezelfde ingang met kind=wav|video.
8.2 Omzetten naar wav / songtekst / metadata (betaald)
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
}
}
filesaccepteert:mp3/wav/lyrics/metadata, maximaal 10 nummers tegelijk.- Afgerekend per geslaagd nummer (0,2 ¥ per stuk); een nummer dat helemaal mislukt wordt niet belast, en een mislukt formaat verschijnt alleen in
songs[].errors. - Wil je eerder opgehaalde bestanden opnieuw, gebruik dan eerst het gratis
POST /api/music/free2/cached(dezelfdesong_ids+files) voor gearchiveerde adressen; desongs[].missing_filesdaarin somt de formaten op die niet in de cache zitten en opnieuw voorbereid moeten worden.
9. Prijzen opvragen
GET /api/pricing/catalog
Een openbaar endpoint zonder authenticatie. Alle prijzen die de klant moet tonen staan in data.catalog.meta (tekenreeksen):
| Sleutel | Betekenis | Huidige waarde |
|---|---|---|
generation_price |
Gewone generatie | 0,6 |
voice_generation_price |
Basisprijs van een cover met stem | 1,2 |
max_mode_factor |
Max Mode-vermenigvuldiger | 2 |
enhanced_upload_price |
Versterkte kloon / versterkte upload | 10 |
voice_auto_verify_price |
Automatische stemverificatie | 5 |
voice_long_term_clone_price |
Langdurige stemkloning | 5 |
Prijzen worden in de backoffice aangepast, dus lees ze live in plaats van ze in de client te hardcoderen. De werkelijke afschrijving voor een cover = voice_generation_price × (bij max_mode waar nogmaals max_mode_factor).
10. Limieten en waarschuwingen
- Uploadgrootte: ≤ 10 MB (de server accepteert meer, maar de ingangsgateway kapt te grote bodies af bij 10 MiB, wat eruitziet als "door Suno geweigerd"; blokkeer het eerst aan jouw kant).
- Lengte van het monster: minimaal 6 s, 10–60 s aanbevolen; te kort en het platform weigert.
- Inhoud van het monster: schone zang; vermijd alles wat sterk lijkt op een bestaande opname (de catalogusvergelijking weigert het).
- Tekstlimieten:
lyrics≤ 3000 tekens; houdstyle_requirements/negative_tags/titlebij voorkeur binnen 1000 / 1000 / 100 tekens (stijl- en covervoorkeuren worden aan de prompt geplakt, houd het totaal binnen 3000 tekens). - Songtekst wordt niet herschreven: er wordt gezongen wat je aanlevert (teken voor teken), zonder lokale inkorting.
- Elk nummer levert 2 tracks; ga niet uit van één resultaat.
- De bronaudio blijft permanent bewaard: een stem verwijderen ruimt de bronaudio niet op; zo blijven latere covers mogelijk en blijft compliance traceerbaar.
- De stem moet gereed zijn: een stem in
processingkan niet voor covers worden gebruikt. - Timeout van het verzoek: bij een koud account duurde de eerste inzending in onze metingen tot ongeveer 4,5 minuut, zet de clienttimeout dus op ≥ 6 minuten. Covers dedupliceren niet op verzoekniveau, dus controleer na een timeout of er al een nieuw nummer is verschenen (§1.5) voordat je opnieuw stuurt.
- Eigendom van de stem: stemmen horen bij wie ze maakt; een cover accepteert alleen gereede en niet-verwijderde stemmen. Een niet-bestaande, verwijderde of bij een ander account horende stem geeft 400:
deze stem bestaat niet of is verwijderd (voice_id=…).
11. Veelgestelde vragen (FAQ)
V1. Kost het aanmaken van een stem geld? Het standaard aanmaken en "aanmaken uit bestaande audio" zijn gratis; alleen covers (1,2 ¥ / MAX 2,4 ¥) en versterkte klonen (standaard 10 ¥) worden belast.
V2. Kan ik een afgerond nummer met begeleiding als stemmonster gebruiken?
Niet aanbevolen. Alles met muziek, of met sterke gelijkenis met een bestaande opname in de catalogus, wordt door het platform geweigerd (This audio matches an existing recording in our catalog.). Gebruik een puur vocale, droge opname.
V3. Waarom is audio_url leeg nadat ik een cover heb ingestuurd?
Het insturen betekent alleen dat het is aangenomen en status is nog processing. Een afspeelbaar/downloadbaar adres verschijnt pas nadat je /api/music/query tot status=completed hebt gepolld.
V4. Moet ik in scenario B (zonder song_clip_id) een songtekst meesturen?
Optioneel. Stuur lyrics om een bepaalde tekst te zingen; zonder redt het model zichzelf, maar met minder controle.
V5. Kan door de klant geüploade audio direct als stem dienen?
Ja: via de file_url-vorm van create, of door het eerst als nummer te uploaden en daarna create-from-clip aan te roepen.
V6. Wordt geld terugbetaald als het mislukt?
Een botweg geweigerd verzoek (verkeerde parameters / platformfout) wordt niet belast, volgens onze metingen; een aangenomen taak die uiteindelijk mislukt geeft het vooraf afgeschreven bedrag terug. Bij een definitieve mislukking meldt de taak status=failed plus error_message.
V7. Kan ik na het verwijderen van een stem de nummers die ermee zijn gemaakt nog beluisteren? Ja. Verwijderen beïnvloedt alleen of die stem voor nieuwe covers gebruikt kan worden.
V8. Hoe lang kan een nummer in één keer worden gecoverd?
duration accepteert 1–480 seconden; laat je het weg, dan beslist het platform op basis van het origineel / het materiaal. Let op: de eindtracks van het platform zijn minstens ongeveer 30 seconden; met een kleinere waarde kwamen er in onze metingen nog steeds 29,96 / 29,76 seconden uit.
Bijlage A: volledig voorbeeld (Node.js, met pollen en downloaden)
const BASE = "https://www.suno-api.io";
const KEY = process.env.SUNO_API_KEY;
const H = { Authorization: `Bearer ${KEY}` };
// ① Stem aanmaken (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, ... }
}
// ② Coveren
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: "langzame folk, akoestische gitaar",
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 }] }
}
// ③ Pollen tot afronding (elke 5 seconden, maximaal 15 minuten)
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(); // kale array
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");
}
// ④ Downloaden
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", "Mijn stem");
const result = await cover(voice.voice_id, "5b773e9a-a035-4134-a4a4-29c9961d3ccb", "[Verse 1]\ntekst…");
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`);
}
Bijlage B: wijzigingslog
| Datum | Wijziging |
|---|---|
| 2026-10-15 | Verwijdersemantiek duidelijk benoemd (§5.3); een cover met een "verwijderd / onbevoegd" voice_id geeft nu 400 vóór enige voorafgaande afschrijving, met fouttabel en FAQ bijgewerkt (samen met de die dag uitgebrachte verwijderpoort voor stemmen) |
| 2026-10-13 | Bovenaan de notitie "waarom we deze keten aanbevelen" toegevoegd: volgens de praktijkbeoordelingen van veel gebruikers behouden nummers uit deze keten de oorspronkelijke stem duidelijk beter |
| 2026-09-26 | Eerste versie: stem aanmaken (drie invoervormen) / aanmaken uit bestaande audio / lijst, details, verwijderen / coveren met stem (scenario's A en B) / voortgang opvragen / downloaden / prijzen lezen, met gemeten bewijs |
Een API-sleutel aanvragen
Maak na je registratie een API-sleutel aan in de console. Elke generatie kost ¥0,6 en levert 2 nummers op, downloads zijn onbeperkt en een telefoonnummer is niet nodig.
API-sleutel ophalen Terug naar overzicht