GPT Image 2.5 is live — OpenAI's newest image model, targeted edits that leave the rest of the frame alone
rreAPI Docs

Suno API

Generate full songs with vocals and lyrics on Suno V6, then extend, cover, mashup, replace sections, split stems, convert to WAV, render MIDI, make music videos, and clone voices. 18 async operations plus 4 instant helpers, one unified task flow.

Suno API

The suno-* model family exposes the complete Suno music toolchain through one endpoint. Generate a song from a text idea or exact lyrics, then keep working on it: extend it, re-cover an uploaded track, layer vocals or instrumentals, mash two songs together, replace a section, separate stems, convert to WAV, extract MIDI, render a music video, or clone a singing voice.

Current pricing for every operation is on the Suno model page.

Surface change (2026-09-13). Every request and response field on this family is now snake_case (custom_mode, negative_tags, task_id, …) and the current model versions are V6, V6_MINI and V6_WILD. The earlier camelCase field names are no longer accepted, and V4–V5_5 are discontinued upstream.

Endpoints

All 18 asynchronous operations share the audio task endpoint — the model field picks the operation:

POST /api/v1/audio/generations

Poll completion with:

GET /api/v1/tasks/{id}

Four synchronous helpers answer inline (no task lifecycle):

POST /api/v1/audio/suno/boost-style
POST /api/v1/audio/suno/timestamped-lyrics
POST /api/v1/audio/suno/persona
POST /api/v1/audio/suno/check-voice

Quick example — generate a song

curl https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-music",
    "custom_mode": false,
    "instrumental": false,
    "version": "V6",
    "prompt": "A dreamy synthwave track about driving through a neon city at midnight"
  }'
import requests, time

headers = {"Authorization": "Bearer YOUR_API_KEY"}
task = requests.post(
    "https://reapi.ai/api/v1/audio/generations",
    headers=headers,
    json={
        "model": "suno-music",
        "custom_mode": False,
        "instrumental": False,
        "version": "V6",
        "prompt": "A dreamy synthwave track about driving through a neon city at midnight",
    },
).json()

while True:
    r = requests.get(
        f"https://reapi.ai/api/v1/tasks/{task['id']}", headers=headers
    ).json()
    if r["status"] in ("completed", "failed"):
        break
    time.sleep(5)

print(r["output"]["tracks"])
const headers = {
  Authorization: 'Bearer YOUR_API_KEY',
  'Content-Type': 'application/json',
};

const task = await fetch('https://reapi.ai/api/v1/audio/generations', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    model: 'suno-music',
    custom_mode: false,
    instrumental: false,
    version: 'V6',
    prompt:
      'A dreamy synthwave track about driving through a neon city at midnight',
  }),
}).then((r) => r.json());

let result;
do {
  await new Promise((r) => setTimeout(r, 5000));
  result = await fetch(`https://reapi.ai/api/v1/tasks/${task.id}`, {
    headers,
  }).then((r) => r.json());
} while (result.status === 'processing');

console.log(result.output.tracks);
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

const key = "YOUR_API_KEY"

func main() {
	body, _ := json.Marshal(map[string]any{
		"model":        "suno-music",
		"custom_mode":  false,
		"instrumental": false,
		"version":      "V6",
		"prompt":       "A dreamy synthwave track about driving through a neon city at midnight",
	})

	req, _ := http.NewRequest("POST",
		"https://reapi.ai/api/v1/audio/generations", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer "+key)
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var task struct {
		ID string `json:"id"`
	}
	json.NewDecoder(resp.Body).Decode(&task)

	for {
		time.Sleep(5 * time.Second)

		poll, _ := http.NewRequest("GET",
			"https://reapi.ai/api/v1/tasks/"+task.ID, nil)
		poll.Header.Set("Authorization", "Bearer "+key)

		pr, err := http.DefaultClient.Do(poll)
		if err != nil {
			panic(err)
		}
		var result struct {
			Status string `json:"status"`
			Output struct {
				Tracks []struct {
					ID    string `json:"id"`
					URL   string `json:"url"`
					Title string `json:"title"`
				} `json:"tracks"`
			} `json:"output"`
		}
		json.NewDecoder(pr.Body).Decode(&result)
		pr.Body.Close()

		if result.Status != "processing" {
			fmt.Printf("%+v\n", result.Output.Tracks)
			return
		}
	}
}

One generation request returns two tracks. Each track carries an id you reuse as audio_id in every track-referencing operation below.

Modes: inspiration vs custom

Generation-class operations (suno-music, suno-upload-cover, suno-mashup) run in one of two modes:

  • custom_mode: false (inspiration) — prompt describes the song idea; Suno writes the lyrics. Capped at 3000 characters on suno-music, 500 on suno-upload-cover and suno-mashup.
  • custom_mode: true (custom) — prompt is used strictly as lyrics; style and title become required. With instrumental: true, prompt is not needed. duration (10–360 s) is honoured in this mode on the V6 family.

Character caps scale with version: prompt 3000 (V4) / 5000 (others), style 200 (V4) / 1000 (others), title 80 (100 on some extend variants).

Versions

version selects the Suno model. Current versions:

ValueCharacter
V6Greater musical expression, more natural vocals, richer detail. Default wherever version is optional.
V6_MINILightweight and fast — quality/speed balance.
V6_WILDPushes creative boundaries for bolder, more distinctive results.

V4, V4_5, V4_5PLUS, V4_5ALL, V5 and V5_5 are still accepted by the schema for callers that have not migrated, but they are discontinued upstream and a request that names one fails at the provider. version is required on generation-class operations; suno-add-vocals / suno-add-instrumental accept V4_5PLUS and newer (default V6); suno-sounds accepts V5 and newer.

Referencing earlier work: task_id + audio_id

Operations that act on an existing song take:

  • task_id — your reAPI task id (task_...) of the source task. It must be your own completed task; reAPI resolves it internally.
  • audio_id — the track id from that task's output.tracks[].id.

Media inputs (upload_url, upload_url_list, audio_url, voice_url, verify_url) accept public HTTP(S) URLs only — no base64 / data URIs.

Operation reference

Every asynchronous operation posts to /api/v1/audio/generations and is selected by the model field; poll /api/v1/tasks/{id} for the result. The four synchronous helpers have their own routes and answer inline.

Create

Generate a song

POST /api/v1/audio/generations · model: "suno-music"

Generates a song from a text description — either a short idea the model turns into lyrics, or your own lyrics, style and title — and returns multiple finished audio variations.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-music.
custom_modebooleanyesfalse = inspiration mode (describe an idea, the model writes the lyrics). true = custom mode (you supply style, title and — for vocal tracks — the exact lyrics).
instrumentalbooleanyestrue generates a track with no lyrics. In custom mode it decides whether prompt is required; in inspiration mode it does not change which fields are required.
versionstringyesModel version — see Versions. V6, V6_MINI or V6_WILD; discontinued values are accepted but fail upstream. Also selects the prompt / style character limits below.
promptstringconditionalInspiration mode: the core idea, max 3000 characters — required, and the lyrics are written from it rather than matching it word for word. Custom mode: used verbatim as the sung lyrics; required when instrumental is false; max 3000 characters on V4, 5000 on every other version.
stylestringconditionalGenre, mood or artistic direction (e.g. Classical, Jazz, upbeat). Required in custom mode; max 200 characters on V4, 1000 on every other version. Ignored in inspiration mode.
titlestringconditionalTrack title. Required in custom mode; max 80 characters on all versions. Ignored in inspiration mode.
negative_tagsstringnoComma-separated styles or traits to steer away from, e.g. Heavy Metal, Upbeat Drums.
vocal_genderstringnom or f. Only effective when custom_mode is true, and it biases the voice rather than guaranteeing it.
style_weightnumbernoHow strictly the result adheres to style. 0–1, up to 2 decimal places.
weirdness_constraintnumbernoHow far the result may deviate creatively. 0–1, up to 2 decimal places.
audio_weightnumbernoBalance of audio features against the other inputs. 0–1, up to 2 decimal places.
persona_idstringnoPersona id or voice id to apply to the generated music. Only available when custom_mode is true. Persona ids come from POST /api/v1/audio/suno/persona; voice ids come from suno-voice-generate.
persona_modelstringnostyle_persona or voice_persona — which kind of persona persona_id refers to. V6 family only.
durationintegernoTarget track length in seconds, 10–360, whole seconds only. Only honoured when custom_mode is true on the V6 family; omit to let Suno choose (upstream default 20).

Response — on completion, output.audio_urls[] holds one URL per generated variation (usually two). output.tracks[] carries the same items with metadata, index-aligned with audio_urls: type (audio), url, id (the track's audio id — pass it as audio_id to extend, WAV, stem-separation, MIDI, music-video and timestamped-lyrics operations), title, duration in seconds, tags (comma-separated style tags), lyrics and image_url (cover art, rehosted alongside the audio). Only url is guaranteed — metadata keys are omitted when upstream returns them empty.

Notes — the two modes have different required sets, and the API enforces them. Inspiration mode (custom_mode: false) needs only prompt, capped at 3000 characters; style and title are ignored. Custom mode (custom_mode: true) always requires style and title, and additionally requires prompt when instrumental is false — an instrumental custom request is valid with just style and title. Character caps move with version: prompt 3000 on V4 and 5000 elsewhere, style 200 on V4 and 1000 elsewhere; title is 80 on every version. Pricing per generation is listed at https://reapi.ai/models/suno.

Generate lyrics

POST /api/v1/audio/generations · model: "suno-lyrics"

Writes song lyrics from a theme description and returns them as structured text — no audio is produced.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-lyrics.
promptstringyesDescription of the lyrics you want — theme, mood, style or story elements. Max 200 characters. More specific prompts yield more targeted lyrics.

Response — this task returns text, not audio: there is no audio_urls or tracks. On completion output.result.lyrics[] holds the generated variations (typically 2–3), each an object with title and text. The text body is formatted with standard section markers ([Verse], [Chorus], [Bridge], …), so it can be passed straight into suno-music as prompt in custom mode.

{
  "output": {
    "result": {
      "lyrics": [
        { "title": "Small Town Lights", "text": "[Verse]\n...\n\n[Chorus]\n..." },
        { "title": "Back Then", "text": "[Verse]\n...\n\n[Chorus]\n..." }
      ]
    }
  }
}

Notes — variations that the upstream model failed to produce are dropped rather than returned as empty entries, so lyrics[] can be shorter than the usual 2–3 items. If none survive, the task fails and the reservation is refunded.

Generate a sound

POST /api/v1/audio/generations · model: "suno-sounds"

Generates a short sound or sound bed — background music, ambience, game SFX — with optional looping, tempo and key control, and returns audio.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-sounds.
promptstringyesDescription of the sound to generate. Max 500 characters.
versionstringyesV6, V6_MINI or V6_WILD (V5 / V5_5 still accepted, discontinued upstream).
sound_loopbooleannoGenerate the result as a seamless loop, for background music and ambient beds. Defaults to false.
sound_tempointegernoTarget tempo in BPM, 1–300. Omit to let the model choose.
sound_keystringnoMusical key: Cm, C#m, Dm, D#m, Em, Fm, F#m, Gm, G#m, Am, A#m, Bm, C, C#, D, D#, E, F, F#, G, G#, A, A#, B. Omit for any key.
grab_lyricsbooleannoCapture lyric subtitles for the generated audio. Defaults to false.

Response — same shape as a song: output.audio_urls[] with one URL per generated variation, and output.tracks[] index-aligned with it, each entry carrying the same per-track fields — type (audio), url, id, title, duration in seconds, tags, lyrics and image_url (cover art) — with the empty ones omitted.

Extend & rework

Extend a track

POST /api/v1/audio/generations · model: "suno-extend"

Continues an existing track from a chosen time point, producing a new set of audio variants that keep the source track's style.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-extend.
default_param_flagbooleanyestrue — extend using the parameters in this request (style, title, continue_at become required, plus prompt unless instrumental is true). false — inherit the source track's parameters; only audio_id and version are needed.
audio_idstringyesThe track to extend. Take it from the parent task's output.tracks[].id.
versionenumyesSee Versions. Must match the source track's version.
instrumentalbooleannotrue extends without lyrics; with custom parameters this drops the prompt requirement (upstream then rejects a prompt or vocal_gender). Defaults to false.
promptstringconditionalRequired when default_param_flag is true and instrumental is not true. Describes how the music should continue or change across the extension. Max 3000 chars on V4, 5000 on every other version.
stylestringconditionalRequired when default_param_flag is true. Style of the extended audio; align it with the source track's style for the most consistent result. Max 200 chars on V4, 1000 on every other version.
titlestringconditionalRequired when default_param_flag is true. Title of the extended track. Max 80 chars on V4 and V4_5ALL, 100 on every other version.
continue_atnumberconditionalRequired when default_param_flag is true. Seconds into the source track where the extension begins. Must be greater than 0 and less than the source track's duration (the upper bound is checked upstream).
negative_tagsstringnoStyles or traits to keep out of the extension, e.g. Heavy Metal, Upbeat Drums.
vocal_genderenumnom or f. Raises the probability of that vocal gender; it is not a guarantee.
style_weightnumberno0–1, up to 2 decimal places. Strength of adherence to style.
weirdness_constraintnumberno0–1, up to 2 decimal places. Controls experimental/creative deviation.
audio_weightnumberno0–1, up to 2 decimal places. Balance of audio features against the other inputs.
persona_idstringnoPersona ID or Voice ID to apply. Only takes effect when default_param_flag is true.
persona_modelenumnostyle_persona or voice_persona. V6 family only.

Response — on completion, output.audio_urls holds the generated audio URLs and output.tracks[] carries one index-aligned entry per variant, each with id (pass this back as audio_id in follow-up operations), url, type (audio), title, duration in seconds, tags (comma-separated style tags), lyrics and image_url (cover art).

Notes — the default_param_flag matrix is strict: with true, style, title and continue_at must be present (and prompt unless the extension is instrumental), and the per-version character caps above apply; with false, everything except audio_id and version is inherited from the source track. continue_at must be greater than 0.

Cover an uploaded track

POST /api/v1/audio/generations · model: "suno-upload-cover"

Re-records audio you supply in a new style while keeping its core melody, returning the reworked variants.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-upload-cover.
upload_urlstringyesPublic http(s) URL of the source audio. Maximum 8 minutes. Base64 and data: URIs are rejected.
custom_modebooleanyestrue — supply your own style/title (and prompt when the result has vocals). false — only prompt is used and lyrics are generated from it.
instrumentalbooleanyestrue produces a track with no lyrics. In custom mode it decides whether prompt is required; in non-custom mode it does not change which fields are required.
versionenumyesSee Versions.
promptstringconditionalRequired in custom mode when instrumental is false, where it is used verbatim as the lyrics (max 3000 chars on V4, 5000 on every other version). Required in non-custom mode, where it is the core idea lyrics are written from (max 500 chars).
stylestringconditionalRequired in custom mode; the genre or style of the cover, e.g. Jazz, Classical. Max 200 chars on V4, 1000 on every other version. Leave empty in non-custom mode.
titlestringconditionalRequired in custom mode. Max 80 chars on V4 and V4_5ALL, 100 on every other version. Leave empty in non-custom mode.
negative_tagsstringnoStyles or traits to exclude from the cover.
vocal_genderenumnom or f. Only effective when custom_mode is true, and only raises the probability of that vocal gender.
style_weightnumberno0–1, up to 2 decimal places. Strength of adherence to style.
weirdness_constraintnumberno0–1, up to 2 decimal places. Controls experimental/creative deviation.
audio_weightnumberno0–1, up to 2 decimal places. Balance of audio features against the other inputs.
persona_idstringnoPersona ID or Voice ID to apply. Only available when custom_mode is true.
persona_modelenumnostyle_persona or voice_persona. V6 family only.
durationintegernoTarget track length in seconds, 10–360. Only honoured when custom_mode is true on the V6 family.

Response — on completion, output.audio_urls holds the cover's audio URLs and output.tracks[] carries one index-aligned entry per variant, each with id, url, type (audio), title, duration in seconds, tags, lyrics and image_url (cover art).

Notes — the requirement matrix is custom_mode × instrumental: custom + instrumental needs style and title; custom + vocals needs style, title and prompt; non-custom needs only prompt (capped at 500 characters) regardless of instrumental, and style/title should be left empty. upload_url is always required and the audio behind it must not exceed 8 minutes.

Extend an uploaded track

POST /api/v1/audio/generations · model: "suno-upload-extend"

Continues audio you supply from a chosen time point, returning a longer track that carries on the uploaded material's style.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-upload-extend.
upload_urlstringyesPublic http(s) URL of the source audio. Maximum 8 minutes. Base64 and data: URIs are rejected.
default_param_flagbooleanyestrue — extend using the parameters in this request (style, title and continue_at become required, plus prompt when instrumental is false). false — reuse the uploaded audio's own parameters; on top of the always-required upload_url, instrumental and version, only prompt is needed.
instrumentalbooleanyestrue extends without lyrics. When default_param_flag is true it decides whether prompt is required; when false it does not change which fields are required.
versionenumyesSee Versions. Must match the source music's version.
continue_atnumberconditionalRequired when default_param_flag is true. Seconds into the uploaded audio where the extension begins. Must be greater than 0 and less than the uploaded audio's duration (the upper bound is checked upstream).
promptstringconditionalRequired when default_param_flag is true and instrumental is false, where it is used verbatim as the lyrics; also required when default_param_flag is false, where lyrics are generated from it. Max 3000 chars on V4, 5000 on every other version.
stylestringconditionalRequired when default_param_flag is true; e.g. Jazz, Classical, Electronic. Max 200 chars on V4, 1000 on every other version.
titlestringconditionalRequired when default_param_flag is true. Max 80 chars on V4 and V4_5ALL, 100 on every other version.
negative_tagsstringnoStyles to exclude from the extension.
vocal_genderenumnom or f. Raises the probability of that vocal gender; it is not a guarantee.
style_weightnumberno0–1, up to 2 decimal places. Strength of adherence to style.
weirdness_constraintnumberno0–1, up to 2 decimal places. Controls experimental/creative deviation.
audio_weightnumberno0–1, up to 2 decimal places. Balance of audio features against the other inputs.
persona_idstringnoPersona ID or Voice ID to apply. Only available when default_param_flag is true.
persona_modelenumnostyle_persona or voice_persona. V6 family only.

Response — on completion, output.audio_urls holds the extended audio URLs and output.tracks[] carries one index-aligned entry per variant, each with id, url, type (audio), title, duration in seconds, tags, lyrics and image_url (cover art).

Notes — the requirement matrix is default_param_flag × instrumental: flag true + instrumental needs style, title and continue_at; flag true + vocals needs style, title, prompt and continue_at; flag false needs only prompt beyond the always-required upload_url, instrumental and version (everything else is taken from the uploaded audio). continue_at must be greater than 0, and unlike the cover operation there is no 500-character short-prompt mode — the per-version caps apply in both modes.

Layer & combine

Add vocals to a track

POST /api/v1/audio/generations · model: "suno-add-vocals"

Takes an audio file you host and sings a new vocal line over it, returning the layered tracks as audio URLs.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-add-vocals.
upload_urlstringyesPublic HTTP(S) URL of the source audio to add vocals to. Base64 and data: URIs are rejected.
promptstringyesLyric content and singing style to guide the vocal. Min 1 character.
stylestringyesMusical style for the vocal, e.g. Jazz. 1–1000 characters.
titlestringyesTrack title, shown in players and used for the file name. Min 1 character.
negative_tagsstringyesComma-separated styles or elements to keep out of the result, e.g. heavy metal, strong drum beats. 1–200 characters.
versionstringnoV6, V6_MINI or V6_WILD (V4_5PLUS / V5 / V5_5 still accepted, discontinued upstream). Defaults to V6.
vocal_genderstringnom or f. Biases the voice; it raises the probability rather than guaranteeing the gender.
style_weightnumbernoAdherence to style. 0–1, up to 2 decimal places.
weirdness_constraintnumbernoExperimental / creative deviation. 0–1, up to 2 decimal places.
audio_weightnumbernoRelative weight of the source audio's elements. 0–1, up to 2 decimal places.

Response — on completion, output.audio_urls[] holds the generated audio URLs and output.tracks[] carries one entry per track with id, url, type (audio), title, duration (seconds), tags (comma-separated style tags), lyrics and image_url (cover art). The two arrays are index-aligned, one entry per generated variant. tracks[].id is the audio_id you pass to track-referencing operations.

Notes — unlike the generate/extend operations, all five content fields (prompt, style, title, negative_tags, upload_url) are unconditionally required, and version is restricted to V4_5PLUS and newer: V4, V4_5 and V4_5ALL are rejected. Pricing: reapi.ai/models/suno.

curl -X POST https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-add-vocals",
    "upload_url": "https://example.com/music.mp3",
    "prompt": "A calm and relaxing piano track.",
    "style": "Jazz",
    "title": "Relaxing Piano",
    "negative_tags": "heavy metal, strong drum beats",
    "version": "V6"
  }'

Add instrumental to a track

POST /api/v1/audio/generations · model: "suno-add-instrumental"

Takes an audio file you host and generates an instrumental accompaniment for it, returning the layered tracks as audio URLs.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-add-instrumental.
upload_urlstringyesPublic HTTP(S) URL of the source audio to accompany. Base64 and data: URIs are rejected.
tagsstringyesStyles to include, e.g. relaxing, piano, soothing. Defines the character of the accompaniment. 1–1000 characters.
titlestringyesTrack title, shown in players and used for the file name. Min 1 character.
negative_tagsstringyesComma-separated styles or elements to keep out of the result. 1–200 characters.
versionstringnoV6, V6_MINI or V6_WILD (V4_5PLUS / V5 / V5_5 still accepted, discontinued upstream). Defaults to V6.
vocal_genderstringnom or f. Biases the voice; it raises the probability rather than guaranteeing the gender.
style_weightnumbernoAdherence to the requested style. 0–1, up to 2 decimal places.
weirdness_constraintnumbernoExperimental / creative deviation. 0–1, up to 2 decimal places.
audio_weightnumbernoRelative weight of the source audio's elements. 0–1, up to 2 decimal places.

Response — same shape as add-vocals: output.audio_urls[] plus output.tracks[] with id, url, type, title, duration, tags and lyrics per track.

Notes — this operation names the style field tags, not style; sending style is rejected. All four of upload_url, tags, title and negative_tags are unconditionally required, and version accepts V4_5PLUS and newer only. Pricing: reapi.ai/models/suno.

curl -X POST https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-add-instrumental",
    "upload_url": "https://example.com/music.mp3",
    "tags": "relaxing, piano, soothing",
    "title": "Relaxing Piano",
    "negative_tags": "heavy metal, strong drum beats",
    "version": "V6"
  }'

Mash up two tracks

POST /api/v1/audio/generations · model: "suno-mashup"

Combines exactly two audio files you host into one new piece, returning the remixed tracks as audio URLs.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-mashup.
upload_url_liststring[]yesExactly 2 public HTTP(S) audio URLs. Fewer or more is rejected; base64 and data: URIs are rejected.
custom_modebooleanyestrue unlocks the detailed controls (style, title, lyrics); false is the simple mode driven by prompt alone.
versionstringyesSee Versions.
instrumentalbooleannoGenerate the mashup without lyrics. In custom mode it decides whether prompt is required; in non-custom mode it has no effect on required fields.
promptstringnoConditionally required — see Notes. In custom mode it is used verbatim as the lyrics; in non-custom mode it is the core idea and lyrics are written from it.
stylestringconditionalRequired in custom mode, ignored otherwise. Genre, mood or artistic direction.
titlestringconditionalRequired in custom mode, ignored otherwise. Max 80 characters on every version.
vocal_genderstringnom or f. Only takes effect when custom_mode is true.
style_weightnumbernoAdherence to style. 0–1, up to 2 decimal places. Only takes effect when custom_mode is true.
weirdness_constraintnumbernoCreative deviation. 0–1, up to 2 decimal places. Only takes effect when custom_mode is true.
audio_weightnumbernoWeight of the source audio elements. 0–1, up to 2 decimal places. Only takes effect when custom_mode is true.
durationintegernoTarget track length in seconds, 10–360. Only honoured when custom_mode is true on the V6 family.

Response — output.audio_urls[] plus output.tracks[], each track carrying id, url, type, title, duration, tags and lyrics.

Notes — upload_url_list must contain exactly two URLs. With custom_mode: true, style and title become required, and prompt is required too unless instrumental is true; the caps then depend on version — prompt up to 3000 characters on V4 and 5000 on every other version, style up to 200 on V4 and 1000 elsewhere, title 80 throughout. With custom_mode: false, prompt is optional but capped at 500 characters and the other content fields are ignored. Pricing: reapi.ai/models/suno.

curl -X POST https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-mashup",
    "upload_url_list": [
      "https://example.com/audio1.mp3",
      "https://example.com/audio2.mp3"
    ],
    "custom_mode": true,
    "instrumental": false,
    "version": "V6",
    "prompt": "A calm and relaxing piano track with soft melodies",
    "style": "Jazz",
    "title": "Relaxing Piano"
  }'

Section editing

Replace a section

POST /api/v1/audio/generations · model: "suno-replace-section"

Regenerates one time window inside an existing song from a new prompt and style, blending the replacement into the material before and after it, and returns the re-rendered track(s).

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-replace-section.
task_idstringconditionalVariant A. The reAPI task id (task_...) of the song you are editing. Required together with audio_id; see Notes.
audio_idstringconditionalVariant A. Identifies which track of that task to edit — take it from the parent task's output.tracks[].id. Required together with task_id.
upload_urlstringconditionalVariant B. Public http(s) URL of your own audio file. Required together with version. Base64 / data: URIs are rejected.
versionenumconditionalVariant B. Model version used to render the replacement — see Versions. Required together with upload_url.
promptstringyesLyrics for the replaced segment. Min 1 char.
tagsstringyesStyle tags for the replaced segment, e.g. Jazz. Min 1 char.
titlestringyesTitle of the resulting song. Min 1 char.
negative_tagsstringnoStyles to keep out of the replaced segment, e.g. Rock. Min 1 char.
infill_start_snumberyesStart of the replacement window, in seconds from the beginning of the track. >= 0. Must be less than infill_end_s. Values are interpreted to 2-decimal precision (e.g. 10.50).
infill_end_snumberyesEnd of the replacement window, in seconds. >= 0. Must be greater than infill_start_s, and infill_end_s - infill_start_s must be between 6 and 60 seconds.
full_lyricsstringyesThe COMPLETE lyrics of the song after the edit — untouched sections plus the rewritten one — not just the replaced part. Min 1 char.

Response — on completion, output.audio_urls[] holds the URL of each rendered track. output.tracks[] carries the same audio index-aligned with per-track metadata: type ("audio"), url, id (pass this back as audio_id in later track-referencing operations), title, duration (seconds), tags, and lyrics.

Notes — the source is specified by exactly one of two mutually exclusive variants: (A) task_id + audio_id to edit a track generated on reAPI, or (B) upload_url + version to edit audio you supply. Both halves of a variant must be present together, and mixing fields from the two variants in one request is rejected with a validation error — so is sending neither. version belongs to variant B only — sending it alongside task_id / audio_id is what makes a request "mixed", so variant A must omit it and the replacement is rendered with the source track's own model. Two further limits apply to the window: it must span at least 6 and at most 60 seconds, and upstream additionally refuses a replacement longer than 50% of the original track's total duration. full_lyrics is what the whole song is re-rendered against, so passing only the new lines will drop the rest of the lyrics.

Track assets

These operations act on a track you already generated: they take the reapi task_id of a completed Suno task plus (usually) the audio_id of one track inside it, and return a derived asset. Per-operation pricing: https://reapi.ai/models/suno.

Separate vocals and instrument stems

POST /api/v1/audio/generations · model: "suno-vocal-separation"

Splits a track into vocal/accompaniment or per-instrument stems and returns one audio URL per stem. The source is either a track you generated here or an audio file you host.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-vocal-separation.
task_idstringconditionalVariant A. reapi task id (task_...) of a completed Suno task that produced the track. Mutually exclusive with audio_url.
audio_urlstringconditionalVariant B. Public http(s) URL of your own audio file. Mutually exclusive with task_id. Base64 / data: URIs are rejected.
audio_idstringyesThe track to process. For variant A copy it from the parent task's output.tracks[].id. Min length 1.
typeenumnoSeparation mode. separate_vocal (default) splits into 2 stems — vocals + instrumental. split_stem splits into up to 12 stems (vocals, backing vocals, drums, bass, guitar, keyboard, strings, brass, woodwinds, percussion, synth, FX/other). split_stem_advanced does multi-stem separation and can target one specific instrument via stem_name.
stem_nameenumconditionalThe single instrument track to extract. Only meaningful with type: "split_stem_advanced", where it is required. 98 accepted values covering vocals, drums, guitars, keys, strings, brass, woodwinds, percussion and synths — e.g. Lead Vocal, Backing Vocals, Drum Kit, Kick, Bass, Piano, Electric Guitar, Synth Pad, Brass Section, Violin, Flute, 808.

Response

output.audio_urls holds one URL per separated stem, index-aligned with output.tracks[]. Each entry in output.tracks[] carries type: "audio", url, and label naming the stem — Vocals, Instrumental, Drums, Bass and so on, matching the instrument the stem was split out as. When upstream returns per-stem records the track additionally carries id (pass it as audio_id to suno-midi) and duration. Stems that upstream did not produce are simply absent, so the array length varies with the mode and the source material; a stem whose name cannot be determined arrives with an empty label and is still delivered.

Notes — exactly one of task_id / audio_url must be present; both or neither is rejected before any charge. stem_name is rejected as missing only when type is split_stem_advanced; the other two modes ignore it. Separation quality depends on the mix: cleanly separated AI mixes yield the best stems. The per-stem id values returned here are what you pass as audio_id to suno-midi.

Convert a track to WAV

POST /api/v1/audio/generations · model: "suno-wav"

Re-renders one generated track as an uncompressed WAV file for professional editing.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-wav.
task_idstringyesreapi task id (task_...) of the completed Suno task that produced the track. Min length 1.
audio_idstringyesWhich track in that task to convert. Copy it from the parent task's output.tracks[].id. Min length 1.

Response

output.audio_urls holds a single URL pointing at the WAV file. No output.tracks[] is emitted for this operation.

Notes — WAV files are typically 5–10× larger than the MP3 equivalent, and processing time scales with the length of the source track.

Generate MIDI from separated stems

POST /api/v1/audio/generations · model: "suno-midi"

Transcribes separated audio into structured MIDI note data (pitch, timing, velocity) per detected instrument.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-midi.
task_idstringyesreapi task id (task_...) of a completed vocal-separation task — not a music-generation task. Min length 1.
audio_idstringnoRestricts transcription to one separated stem; take the value from that separation task's output.tracks[].id. Omit to transcribe all separated stems. Min length 1.

Response

A structured text result, not audio: there is no audio_urls or tracks. On completion output.result.midi carries a state string and an instruments[] array with one entry per detected instrument. Each instrument has a name (e.g. Alto Sax, Electric Bass (finger)) and a notes[] array whose entries carry pitch (MIDI note number, 0–127), start and end (seconds), and velocity (0–1).

Notes — Separation must run first; passing the task id of a plain music-generation task is not valid input for this operation. Not every instrument is detected — the result reflects what is actually present in the source stems, and upstream notes that separations run with type: "split_stem" can yield no note data at all. If upstream completes with no note data, the task is reported as failed rather than completing with an empty result.

Create a music video

POST /api/v1/audio/generations · model: "suno-music-video"

Renders one generated track into an MP4 with visualizations plus optional artist and brand attribution.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-music-video.
task_idstringyesreapi task id (task_...) of the completed Suno task that produced the track. Min length 1.
audio_idstringyesWhich track in that task to visualize. Copy it from the parent task's output.tracks[].id. Min length 1.
authorstringnoArtist or creator name shown as a signature on the video cover. 1–50 characters.
domain_namestringnoWebsite or brand shown as a watermark at the bottom of the video. 1–50 characters.

Response

output.video_urls holds a single URL pointing at the rendered MP4.

Notes — Render time varies with the length of the source track.

Generate cover art

POST /api/v1/audio/generations · model: "suno-cover-image"

Generates cover images for a completed music task; usually returns two stylistic variants to choose from.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-cover-image.
task_idstringyesreapi task id (task_...) of the completed suno-music task to illustrate — see Notes for which parent tasks upstream accepts. Min length 1. This operation targets the task as a whole, so there is no audio_id.

Response

output.image_urls holds the generated cover images, typically two.

Notes — the parent has to be a task upstream still holds as a music record, which is narrower than "any completed Suno task". Two rejections to plan around, both live-verified 2026-09-13:

  • The parent must be a suno-music task. A task produced by suno-upload-cover — or another rework operation — is refused with Original music record does not exist, even though that task itself completed normally.
  • That suno-music task must have carried a prompt. A custom-mode instrumental built from style + title alone is refused with Prompt cannot be empty in original music record.

In practice: generate the song in inspiration mode (custom_mode: false, which always requires a prompt) or in custom mode with lyrics, then ask for its cover art. A cover can also be generated only once per source task — a second request for the same task_id is rejected upstream rather than producing new images. Both rejections arrive as 80007 carrying the upstream reason, and the reservation is refunded in full.

Voice cloning

Cloning a singing voice is a three-step chain, and each step is its own billable task (see pricing):

  1. suno-voice-validate — submit the source recording and the vocal segment to analyse. The completed task returns a validation phrase.
  2. suno-voice-generate — have the person record themselves reading (ideally singing) that phrase, host the recording at a public URL, and submit it as verify_url together with the reapi task_id of the step-1 task. The completed task returns a voice_id.
  3. suno-voice-regenerate — only needed when a validation phrase failed or expired.

The voice_id from step 2 is then used in the generation operations that accept a persona: pass it as persona_id with persona_model: "voice_persona".

Step 1 — Generate a validation phrase

POST /api/v1/audio/generations · model: "suno-voice-validate"

Analyses the vocal segment of a source recording and returns the phrase the speaker must read aloud to verify the voice.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-voice-validate.
voice_urlstringyesPublic http(s) URL of the source recording. Base64 / data: payloads are rejected.
vocal_start_sintegeryesStart time, in seconds, of the vocal segment to extract. 0 or greater.
vocal_end_sintegeryesEnd time, in seconds, of the vocal segment. Must be greater than vocal_start_s.
languagestringnoLanguage of the generated phrase. Upstream documents en, zh, es, fr, pt, de, ja, ko, hi, ru.
curl https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-voice-validate",
    "voice_url": "https://example.com/audio/source_voice.mp3",
    "vocal_start_s": 0,
    "vocal_end_s": 10,
    "language": "en"
  }'

Response — a structured text result. When the task completes, output.result.validate_info holds the phrase text to be read, and output.result.status holds the upstream state that made it terminal (wait_validating while the phrase awaits the reader, success once the whole flow has finished).

Notes — vocal_end_s must be strictly greater than vocal_start_s; equal or inverted values are rejected before the task is created. Keep the reapi task id (task_...) returned by this call: step 2 references it, and it is the only handle you have on the phrase — the upstream phrase id is never exposed.

Step 2 — Create the custom voice

POST /api/v1/audio/generations · model: "suno-voice-generate"

Submits the reader's verification recording against a completed validation task and produces a reusable custom voice.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-voice-generate.
task_idstringyesYour reapi task id (task_...) from step 1 (or from a step-3 regeneration). Must be your own task, in completed status, from the same surface, and from the voice flow.
verify_urlstringyesPublic http(s) URL of the recording of the person reading the validate_info phrase. Singing the phrase rather than speaking it produces a more accurate voice profile. Base64 / data: payloads are rejected.
voice_namestringnoDisplay name for the voice.
descriptionstringnoFree-text description of the voice.
stylestringnoVoice style, e.g. Pop, Female Vocal.
singer_skill_levelenumnoOne of beginner, intermediate, advanced, professional. Upstream default is beginner.
curl https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-voice-generate",
    "task_id": "task_abc123",
    "verify_url": "https://example.com/audio/verify_read.mp3",
    "voice_name": "My Voice",
    "description": "created from uploaded voice",
    "style": "Pop, Female Vocal",
    "singer_skill_level": "beginner"
  }'

Response — a structured text result: output.result.voice_id, the identifier of the finished custom voice.

Notes — feed voice_id back into a generation call as persona_id, together with persona_model: "voice_persona". The persona fields only apply in custom mode (custom_mode: true) on the V6 family. The task_id reference is resolved and rejected before any charge, so a bad or unfinished parent task costs nothing. A clean a-cappella take of the verification recording gives the most accurate voice profile.

Step 3 — Regenerate the validation phrase

POST /api/v1/audio/generations · model: "suno-voice-regenerate"

Asks upstream for a fresh validation phrase on an existing voice task, for when the previous phrase failed or expired.

Request

FieldTypeRequiredNotes
modelstringyesMust be suno-voice-regenerate.
task_idstringyesYour reapi task id (task_...) of an earlier voice-flow task. Same ownership / completed / voice-family checks as step 2.
curl https://reapi.ai/api/v1/audio/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "suno-voice-regenerate",
    "task_id": "task_abc123"
  }'

Response — a structured text result carrying the NEW phrase: the task completes with output.result.validate_info (and its status), the same shape step 1 returns.

Notes — this reissues the validation phrase, it does not produce a voice. Record yourself reading the new phrase and send that recording to step 2 (suno-voice-generate) with this task's id as task_id. Use it when the earlier phrase expired or the reading was rejected.

Synchronous helpers

These four operations do not run on /api/v1/audio/generations and have no task lifecycle — they answer inline on the same HTTP response, so there is nothing to poll. Each has its own route, accepts only the fields listed below (unknown fields are rejected), and returns id (the audit task id recording this call, task_...), credits (the credits charged), plus its result fields. A failed call is refunded in full. Pricing: reapi.ai/models/suno.

curl -X POST https://reapi.ai/api/v1/audio/suno/boost-style \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"Pop, Mysterious"}'

Boost music style

POST /api/v1/audio/suno/boost-style

Expands a short style description into a richer, generation-ready style prompt and returns the enhanced text inline.

Request

FieldTypeRequiredNotes
contentstringyesStyle description to enhance, min 1 character. Describe the music style you expect in concise, clear language — e.g. Pop, Mysterious.

Response — result: the enhanced style text. Feed it into the style field of a generation request.

Notes — the helper waits for the upstream job to settle before answering (usually a few seconds); a job that does not settle within about 50 seconds is reported as a provider failure and refunded.

Timestamped lyrics

POST /api/v1/audio/suno/timestamped-lyrics

Returns word-level time-aligned lyrics for one track of a completed song task.

Request

FieldTypeRequiredNotes
task_idstringyesYour reapi task id (task_...) of the completed song task the track belongs to, min 1 character.
audio_idstringyesIdentifier of the specific track, min 1 character. Take it from the parent task's output.tracks[].id.

Response

  • aligned_words: array of aligned words, each with word (the lyric token), success (boolean, whether that token aligned), startS / endS (word start and end time in seconds), and palign (alignment parameter).
  • waveform_data: array of numbers for audio visualisation, or null when upstream omits it.
  • hoot_cer: lyrics alignment accuracy score, or null.
  • is_streamed: whether the source is streaming audio, or null.

Notes — task_id must name a Suno-family task you own that has reached completed; a task that is still running, or one from outside the Suno family, is rejected before any charge. Which Suno operation produced it is not gated here — upstream expects a music-generating parent (song or extend) and answers for the rest. waveform_data is delivered inline only — it is deliberately not kept in the audit row, so a later GET /api/v1/tasks/{id} on this call's id returns the other three fields plus waveform_omitted: true.

Generate persona

POST /api/v1/audio/suno/persona

Analyses a segment of an existing track and creates a reusable persona, returning its persona_id.

Request

FieldTypeRequiredNotes
task_idstringyesYour reapi task id (task_...) of the completed song task to analyse, min 1 character.
audio_idstringyesIdentifier of the track to build the persona from, min 1 character. Take it from the parent task's output.tracks[].id.
namestringyesName for the persona, min 1 character — something that captures the musical style or character, e.g. Electronic Pop Singer.
descriptionstringyesDescription of the persona's musical characteristics, style and personality, min 1 character. Be specific about genre, mood, instrumentation and vocal qualities.
vocal_startnumbernoStart of the analysis segment in seconds, >= 0. Defaults to 0.
vocal_endnumbernoEnd of the analysis segment in seconds, >= 0. Defaults to 30.
stylestringnoSupplementary style tag for the persona, min 1 character — e.g. Electronic Pop, Jazz Trio.

Response — persona_id: the persona identifier, reusable in the persona_id field of the song, extend, upload-cover and upload-extend operations. name and description echo the request (each null if upstream omits it).

Notes — the analysis window is validated before charging: vocal_end - vocal_start must be between 10 and 30 seconds inclusive, using the defaults 0 and 30 for whichever bound you omit. Setting only vocal_start: 25 therefore fails (window is 5s), while vocal_start: 25, vocal_end: 40 succeeds. task_id must name a completed Suno task you own. Upstream allows one persona per source track; a second request for the same track is rejected with a conflict.

Check voice availability

POST /api/v1/audio/suno/check-voice

Reports whether a custom voice produced by a completed voice task is ready to use.

Request

FieldTypeRequiredNotes
task_idstringyesYour reapi task id (task_...) of the completed voice task to check, min 1 character.

Response — is_available: boolean, whether the generated voice is available.

Notes — task_id must resolve to a completed voice-family task you own — in practice the suno-voice-generate or suno-voice-regenerate task that produced the voice; a song task is rejected before any charge.

Output schema

Asynchronous results land on GET /api/v1/tasks/{id}:

{
  "id": "task_...",
  "status": "completed",
  "output": {
    "audio_urls": ["https://..."],
    "tracks": [
      {
        "id": "track id — reuse as audio_id",
        "url": "https://...",
        "title": "Midnight Drive",
        "duration": 128.5,
        "tags": "synthwave, dreamy",
        "lyrics": "..."
      }
    ]
  },
  "error": null
}

Music videos populate output.video_urls, cover art output.image_urls; lyric / MIDI / voice tasks return a structured text output.result (e.g. { "lyrics": [...] }, { "midi": ... }, { "voice_id": "..." }, { "validate_info": "..." }).

Pricing dimensions

Every operation bills a flat rate per request — nothing scales with duration or output length. Generation-class operations (music, extend, covers, vocals, mashup) share one rate covering both returned tracks; section replacement, stem separation (three tiers by type), music video, sound effects, lyrics, WAV conversion, and the utility operations each have their own flat rate. Bill formula: credits = price_usd × 1000 (1 credit = $0.001). Current rates: Suno model page.

Errors

Failures use the standard envelope { "error": { "code", "message", "request_id" } } — see the error catalog. Notable cases: content flagged by moderation returns a policy error (80006); malformed parameter combinations surface 80007 with the upstream reason; upstream generation failures (80003) are refunded automatically. A request that names a discontinued version fails upstream and is refunded the same way.

Tips

  • Start in inspiration mode (custom_mode: false) — one prompt line is enough. Switch to custom mode when you need exact lyrics.
  • style reads best as comma-separated genre + mood + vocal tags ("synthwave, dreamy, female vocal"). Use the boost-style helper to expand a rough idea.
  • Save output.tracks[].id — every downstream operation needs it.
  • For extensions, pick continue_at a beat before the natural end of the source so the transition lands cleanly.
  • Instrumental-only? Set instrumental: true and skip lyrics entirely.

Table of Contents