Skip to main content

What is Custom Mode?

By default, /api/generate lets Suno write the lyrics and pick a style based on your prompt. Custom Mode reverses this: you supply the lyrics, the musical style via tags, and the title, and Suno focuses on realising your creative brief rather than inventing one. Use POST /api/custom_generate instead of /api/generate.

Request fields

prompt
string
required
The full lyrics text. In Custom Mode, this field contains the actual song lyrics rather than a description. Suno uses section markers like [Verse], [Chorus], [Bridge] to understand song structure.
tags
string
required
A comma-separated string of musical style and genre descriptors. These guide the instrumentation, tempo, and vocal style. For example: "heavy metal, electric guitar, drums".
title
string
required
The title of the song. Appears in the returned AudioInfo object’s title field.
make_instrumental
boolean
When true, the lyrics in prompt are ignored and Suno generates a purely instrumental track matching the style tags. Defaults to false.
model
string
The Suno model to use. Defaults to chirp-v3-5.
wait_audio
boolean
When true, the server waits up to 100 seconds for generation to complete before responding. When false (default), returns immediately with status "submitted". See polling for completion.
negative_tags
string
Styles and elements to exclude from the generation. For example: "no piano, no drums".

Writing effective tags

Tags are the primary way to shape the sound of a Custom Mode generation. Think of them as a genre and production brief compressed into a short string.
Be specific. "upbeat pop, female vocalist, synth, 120bpm" will produce more consistent results than just "pop".
Some examples:
Desired soundTags
Radio-ready popupbeat pop, female vocalist, synth, catchy hook
Relaxed study musiclo-fi hip hop, chill, rain ambience, vinyl crackle
Film score feelepic orchestral, cinematic, strings, choir
Heavy rockheavy metal, electric guitar, drums, distortion
Acoustic singer-songwriteracoustic folk, fingerpicking, male vocalist, intimate
Separate each tag with a comma. Tags are case-insensitive.

Negative tags

Use negative_tags to prevent specific elements from appearing in the track. This is useful when a style tends to include sounds you want to exclude.
{
  "tags": "jazz, piano, upright bass",
  "negative_tags": "no drums, no trumpet"
}
Common negative tags:
  • no piano — remove piano from an otherwise piano-heavy genre
  • no drums — useful for ambient or solo instrument tracks
  • acoustic only — suppress electric instruments
  • no vocals — alternative to setting make_instrumental: true

Instrumental mode

Set make_instrumental: true to generate music without any lyrics or vocals. The prompt field is ignored when this flag is set — you only need to provide tags and title.
{
  "prompt": "",
  "tags": "epic orchestral, cinematic, strings, no vocals",
  "title": "Battle Theme",
  "make_instrumental": true,
  "model": "chirp-v3-5",
  "wait_audio": false
}

Extending a custom song

After you generate a clip, you can continue it with new content using POST /api/extend_audio. This is useful for building longer songs section by section.
audio_id
string
required
The id of the existing clip to extend.
prompt
string
Additional lyrics for the extension.
continue_at
number
Timestamp in seconds from which to branch the extension. Defaults to the end of the clip. Pass a value like 30 to branch from the 30-second mark instead.
tags
string
Style tags for the extension. Can differ from the original to transition the sound.
negative_tags
string
Styles to exclude from the extension.
title
string
Title for the extended clip.
model
string
Model to use. Defaults to chirp-v3-5.
wait_audio
boolean
Whether to wait for the extension to finish before responding.

Complete example

The following example generates a custom song and then polls for completion.
# Step 1 — generate
curl -X POST http://localhost:3000/api/custom_generate \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "[Verse]\nSilver stars above the sea\nWaves that carry you to me\n[Chorus]\nOcean deep and sky so wide\nYou are always by my side",
    "tags": "upbeat pop, female vocalist, synth, ocean vibes",
    "title": "Ocean Wide",
    "make_instrumental": false,
    "model": "chirp-v3-5",
    "wait_audio": false
  }'

# Step 2 — poll until streaming
curl "http://localhost:3000/api/get?ids=<id1>,<id2>"

Extending the generated clip

Python
import requests

base_url = 'http://localhost:3000'

def extend_audio(payload):
    url = f"{base_url}/api/extend_audio"
    response = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
    return response.json()

# Extend from the end of the original clip
extension = extend_audio({
    "audio_id": data[0]["id"],
    "prompt": "[Bridge]\nFar across the endless blue\nEvery tide brings me back to you",
    "tags": "upbeat pop, female vocalist, synth, ocean vibes",
    "title": "Ocean Wide (Extended)",
    "model": "chirp-v3-5",
    "wait_audio": False
})

print(extension)
extend_audio returns a new AudioInfo array with fresh clip IDs. Poll these new IDs the same way you poll the original generation.

Build docs developers (and LLMs) love