Suno Track Operations
Add vocals or an instrumental, replace a section, export WAV, make a music video, get MIDI and timed lyrics, and save personas from finished Suno tracks.
These routes work on a Suno track Kolbo already made. Each one creates a new generation and leaves the source untouched. To make the first track, see Music Generation.
Picking a track: generation_id + audio_id
A Suno generation usually holds two tracks, and a stem separation holds one per stem. Every operation names one of them with two ids:
generation_id— the finished music generation (from/generate/music,/generate/music/extend, an earlier operation, or a stem separation made in the Kolbo music tool).audio_id— which track inside it:result.tracks[].audio_idfromGET /api/v1/generate/{generation_id}/status.
The operation runs in the source track's session. A generation that does not exist or that you cannot access returns 404 GENERATION_NOT_FOUND (never 403). A source that has not finished yet returns 409 SOURCE_NOT_READY.
Routes and prices
| Route | What it does | Credits | Answers |
|---|---|---|---|
POST /api/v1/generate/music/add-vocals | Sing new vocals over an instrumental or stem | 12 | async |
POST /api/v1/generate/music/add-instrumental | Build a backing track under a vocal / a cappella | 12 | async |
POST /api/v1/generate/music/replace-section | Regenerate one time range, keep the rest | 5 | async |
POST /api/v1/music/{generation_id}/wav | Lossless WAV of one track | 1 | async |
POST /api/v1/music/{generation_id}/video | Visualizer video (cover art + waveform) | 5 | async |
POST /api/v1/music/{generation_id}/midi | MIDI notes from a finished stem separation | 2 | async |
GET /api/v1/music/{generation_id}/timed-lyrics | Word-by-word timed lyrics | 1, then free | sync |
POST /api/v1/music/personas | Save a track's voice and style as a persona | 0 | sync |
GET /api/v1/music/personas | List your personas | 0 | sync |
Extend costs 15 credits. A 2-stem separation made in the Kolbo music tool costs 10 (12 stems: 45).
Each operation holds its own price before it starts and answers 402 when your balance cannot cover it. Every route except GET /music/personas needs an API key with write permission, the timed-lyrics GET included, because it can charge (403 API_KEY_READ_ONLY). The async routes share the standard generation rate-limit bucket.
Async routes return the standard Generation Started shape. Poll GET /api/v1/generate/{generation_id}/status as for any music generation; credits_charged on submit is the hold, credits_used on the completed status is the charge. Sync routes answer with the result directly.
Add vocals / add instrumental
POST /api/v1/generate/music/add-vocals
POST /api/v1/generate/music/add-instrumentalThe source is either a finished Kolbo track or your own audio.
| Field | Type | Required | Description |
|---|---|---|---|
generation_id + audio_id | string | One source* | A finished Suno track or stem. Pass a stem separation's generation_id and the stem's audio_id to build on one stem |
audio_url | string | One source* | Your own audio, a public URL. Requires rights_confirmed: true |
rights_confirmed | boolean | With audio_url | You hold the rights to that audio |
upload_id | string | One source* | An upload_id from /generate/music/import |
title | string | Yes | Title for the result (≤ 80) |
style | string | add-vocals: Yes | The vocal style to sing in, e.g. "soulful female vocals, R&B" (≤ 1000) |
tags | string | add-instrumental: Yes | The accompaniment style, e.g. "acoustic guitar, soft piano" (≤ 1000). style is accepted as an alias |
lyrics | string | No | add-vocals: the lyrics to sing (omit to have them written). add-instrumental: the lyrics of the existing vocal, to guide the arrangement (≤ 5000) |
prompt | string | No | Extra direction for the new layer |
negative_tags, vocal_gender, style_weight, weirdness, audio_weight, variety | No | Same meaning as on /generate/music. variety is a whole number 0–4 | |
project_id / session_id | string | No | Only used for an audio_url / upload_id source. A Kolbo track source always runs in its own session |
*Send generation_id + audio_id, or audio_url with rights_confirmed: true, or upload_id.
curl -X POST https://api.kolbo.ai/api/v1/generate/music/add-vocals \
-H "X-API-Key: kolbo_live_..." \
-H "Content-Type: application/json" \
-d '{
"generation_id": "68f2c1a9b4e5d6f7a8b9c0d1",
"audio_id": "a1b2c3d4-0000-0000-0000-000000000001",
"title": "Night Drive (vocal)",
"style": "breathy female vocals, synth-pop",
"lyrics": "[Verse]\nCity lights on the windshield..."
}'Replace a section
POST /api/v1/generate/music/replace-sectionRegenerates start..end seconds of one track ("rewrite the second verse") and keeps the rest. ElevenLabs Music tracks use /generate/music/edit-section instead.
| Field | Type | Required | Description |
|---|---|---|---|
generation_id / audio_id | string | Yes | The source track |
start / end | number | Yes | Seconds. The window must be at least 10 s, at most 50% of the track, and inside it |
prompt | string | One of | What the new section should be (≤ 3000) |
lyrics | string | One of | Lyrics of the new section (≤ 5000) |
full_lyrics | string | No | Whole-song lyrics after the edit (≤ 10000). Default: the source lyrics |
tags | string | No | Style for the section. Default: the source style |
title | string | No | Default: the source title |
negative_tags, vocal_gender, style_weight, weirdness, audio_weight, variety | No | As on add vocals |
The completed status carries result.replace_window: { start, end }.
WAV export
POST /api/v1/music/{generation_id}/wavBody: { "audio_id": "..." }. The completed status carries result.wav_url. A WAV already made (or in progress) for the same track is returned again without a new charge.
Music video
POST /api/v1/music/{generation_id}/videoBody: audio_id (required), optional author (artist name shown on the video, ≤ 50) and domain_name (watermark, ≤ 50). The completed status carries result.video_url. The provider makes one video per track: a repeat request returns the existing video.
MIDI
POST /api/v1/music/{generation_id}/midigeneration_id must be a completed Suno stem separation (2 or 12 stems) made in the Kolbo music tool. A normal song, or a result of Audio Separation, does not qualify. Optional body audio_id limits it to one stem.
The completed status carries result.midi_data: notes per instrument (pitch, start, end, velocity). There is no .mid file URL.
Timed lyrics
GET /api/v1/music/{generation_id}/timed-lyrics?audio_id=...Synchronous. Charged 1 credit the first time for a track; later calls return the cached result free (cached: true, credits_used: 0). Missing audio_id returns 400 MISSING_AUDIO_ID.
{
"success": true,
"generation_id": "68f2c1a9b4e5d6f7a8b9c0d1",
"audio_id": "a1b2c3d4-0000-0000-0000-000000000001",
"cached": false,
"instrumental": false,
"aligned_words": [
{ "word": "[Verse]\nCity", "success": true, "start_s": 12.4, "end_s": 12.9, "palign": 0 }
],
"waveform_data": [0.12, 0.31, 0.27],
"hoot_cer": 0.08,
"fetched_at": "2026-10-30T12:00:00.000Z",
"credits_used": 1
}Words carry section tags inline ("[Verse]\nCity"). An instrumental returns instrumental: true with no words and no charge.
Personas
A persona saves the sound of one finished track (its voice and style) so new songs can sing in it. Free.
POST /api/v1/music/personas| Field | Type | Required | Description |
|---|---|---|---|
generation_id / audio_id | string | Yes | The source track |
name | string | Yes | ≤ 80 |
description | string | Yes | What the voice / style is like (≤ 1000) |
style | string | No | Short style line (≤ 200) |
vocal_start / vocal_end | number | No | A 10–30 s window (seconds) where the voice is clearly heard |
{
"success": true,
"already_exists": false,
"persona": {
"id": "68f2c1a9b4e5d6f7a8b9c0e1",
"name": "Warm Alto",
"description": "warm female alto, breathy, indie folk",
"style": "indie folk",
"image_url": null,
"audio_url": "https://media.kolbo.ai/music/.../track-1.mp3",
"source_generation_id": "68f2c1a9b4e5d6f7a8b9c0d1",
"source_audio_id": "a1b2c3d4-0000-0000-0000-000000000001",
"created_at": "2026-10-30T12:00:00.000Z"
},
"credits_used": 0
}Saving the same track again returns the existing persona with already_exists: true.
GET /api/v1/music/personas?page=1&limit=50Returns { success, personas: [...], page, limit, total } (limit 1–100, default 50), newest first. Pass a persona id as persona_voice_id on /generate/music to sing a new song in that voice (Suno V6).
Completed status fields
Operation results are read from GET /api/v1/generate/{generation_id}/status like any music generation. In addition to urls and tracks[] (each with audio_id, and video_url when a music video exists), result can carry:
| Field | When |
|---|---|
operation | Which operation made this (add-vocals, add-instrumental, replace-section, wav, music-video, midi, extend, …) |
source_generation_id / source_audio_id | The source the operation ran on |
replace_window | Replace section |
wav_url | WAV export |
video_url | Music video |
midi_data | MIDI |
variety / persona_voice_id / references | Echo of the Suno V6 inputs, when sent |
MCP tools
The Kolbo MCP server exposes the same operations: add_vocals, add_instrumental, replace_music_section, export_music_wav, make_music_video, generate_music_midi, get_timed_lyrics, create_music_persona, list_music_personas.