【Aanbevolen】 stemprofiel-API

Bijgewerkt op 2026-09-18 · Suno-API-team

✅ 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.

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

1.3 Indelingen van de verzoekbody

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:

  1. 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.
  2. 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 zijn p / page_size; de compatibele spelling ps werkt ook) of er al een nieuw nummer met generation_type=voice_profile_cover is 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:

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"
      }'

Vorm C: JSON + base64

{
  "file_base64": "data:audio/mpeg;base64,//uQxAAA…",
  "file_name": "my-voice.mp3",
  "title": "Mijn stem"
}

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_at zijn 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):

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…"
}

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" } }

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:

  1. Identificeer de eindnummers met clips[].song_id (dit endpoint geeft geen veld id terug).
  2. Je krijgt direct 2 song_id-waarden, terwijl status nog processing is (dat betekent alleen "aangenomen") en audio_url leeg is; je moet pollen tot completed voordat je kunt downloaden. play_url is de preview-stream van het platform, kan al bij het insturen verschijnen en verloopt.
  3. description is de prompt die de server uiteindelijk stuurt (het vaste structuurdeel + de cover_requirements / style_requirements die je hebt ingevuld); die is erg handig bij het onderzoeken van een resultaat.
  4. source_updates is het resultaat van de mediaverwerking van de server en mag de client negeren.
  5. De title die je stuurt, wordt in het server-side taakrecord geschreven en verschijnt in latere opvragingen als song_title; dat clips[].song_title in 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_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 veld id, dus row.song_id || row.id is 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"]
    }
  }
}

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:

  1. De audio_url uit het opvraagresultaat gebruiken (een directlink naar de objectopslag, het eenvoudigst).
  2. GET /api/music/download?song_id=<id>&kind=mp3 → geeft direct de audiostream als bytes terug (met de bestandsnaam al in Content-Disposition).
  3. 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
  }
}

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

  1. 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).
  2. Lengte van het monster: minimaal 6 s, 10–60 s aanbevolen; te kort en het platform weigert.
  3. Inhoud van het monster: schone zang; vermijd alles wat sterk lijkt op een bestaande opname (de catalogusvergelijking weigert het).
  4. Tekstlimieten: lyrics ≤ 3000 tekens; houd style_requirements / negative_tags / title bij voorkeur binnen 1000 / 1000 / 100 tekens (stijl- en covervoorkeuren worden aan de prompt geplakt, houd het totaal binnen 3000 tekens).
  5. Songtekst wordt niet herschreven: er wordt gezongen wat je aanlevert (teken voor teken), zonder lokale inkorting.
  6. Elk nummer levert 2 tracks; ga niet uit van één resultaat.
  7. De bronaudio blijft permanent bewaard: een stem verwijderen ruimt de bronaudio niet op; zo blijven latere covers mogelijk en blijft compliance traceerbaar.
  8. De stem moet gereed zijn: een stem in processing kan niet voor covers worden gebruikt.
  9. 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.
  10. 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
VolgendeAPI voor stijlversterking

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