Skip to main content

Music Generation

Available Models

The full list of models can be viewed on the Models page or retrieved dynamically via the API endpoint: https://openai.bothub.chat/v1/music/models

BotHub generates songs with Suno models. Generation takes 1–3 minutes, so it works asynchronously: the request returns a job with status: "in_progress" right away, and you poll for the result by its ID. Each generation returns two tracks and is billed once, when it completes. A failed generation is not billed.


How It Works​

  1. Send a generation request — POST /v1/music/generations returns immediately with status: "in_progress" and a job id.
  2. Poll for status — Periodically call GET /v1/music/:musicId until status becomes "completed" or "failed".
  3. Download the tracks — On completion, data contains both tracks with links to MP3 files and covers.

Two Ways to Describe a Song​

ModeWhat to sendWhat happens
By descriptionprompt only (plus instrumental if needed)Suno writes the lyrics and picks the style itself. The written lyrics come back in data[].lyrics
Your own songlyrics, style, title and any fine-tuning fieldsSuno sings your lyrics exactly in the style you set
Do not mix the modes

prompt cannot be combined with lyrics, style, title or the fine-tuning fields: the request fails with MUSIC_PROMPT_WITH_CUSTOM_FIELDS. Otherwise Suno would sing your description word for word. To describe the style of your own song, use style.

An instrumental track in the second mode needs style or negative_tags: send instrumental: true and describe the music in style.


Endpoints​

POST /v1/music/generations​

Creates a new music generation. Returns immediately — generation happens asynchronously.

Base URL: https://openai.bothub.chat

Authentication: Authorization: Bearer YOUR_BOTHUB_API_KEY

Request Body​

FieldTypeDescription
modelstringModel ID, e.g. suno-v6 (see GET /v1/music/models)
external_idstringYour own job ID, up to 128 characters, unique within the account. A repeated request with the same value returns the existing job instead of starting a new one — see below
promptstringDescription of the song, up to 3000 characters. Suno writes the lyrics
lyricsstringWords to sing, up to 5000 characters. Mark sections like [Verse], [Chorus], [Bridge], [Outro]
stylestringGenre, mood, tempo, instruments, vocals — up to 1000 characters
titlestringTrack title, up to 80 characters. Defaults to the first line of the lyrics
instrumentalbooleantrue — no vocals. Default false
negative_tagsstringStyles to avoid, up to 1000 characters
vocal_genderstringmale or female
style_weightnumberHow closely to follow style, from 0 to 1
weirdness_constraintnumberHow experimental the result is, from 0 to 1
audio_weightnumberWeight of the audio guidance, from 0 to 1
durationintegerTarget length in seconds, from 10 to 360
varietyintegerVariety of the result, from 0 to 4

All fields except model are optional, but the request needs prompt, lyrics or instrumental: true.


GET /v1/music/{musicId}​

Returns the current status and result of a music generation.


GET /v1/music/models​

Returns the list of available music generation models.


A Song From Your Own Lyrics​

async function generateSong() {
const BASE_URL = 'https://openai.bothub.chat/v1';
const API_KEY = 'YOUR_BOTHUB_API_KEY';

// Step 1: Create the generation
const createRes = await fetch(`${BASE_URL}/music/generations`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${API_KEY}`,
},
body: JSON.stringify({
model: 'suno-v6',
lyrics: '[Verse]\nNeon light on the wet asphalt\nThe city never sleeps tonight\n\n[Chorus]\nNight city, lights until the dawn',
style: 'synthwave, 80s retro, 110 bpm, dreamy female vocals, analog synths',
title: 'Night City',
negative_tags: 'heavy metal, screaming',
vocal_gender: 'female',
duration: 180,
}),
});

const { id } = await createRes.json();
console.log('Generation created, id:', id);

// Step 2: Poll until completed
let music;
while (true) {
await new Promise((r) => setTimeout(r, 10000));
const statusRes = await fetch(`${BASE_URL}/music/${id}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
music = await statusRes.json();
console.log('Status:', music.status);
if (music.status === 'completed' || music.status === 'failed') break;
}

if (music.status === 'completed') {
music.data.forEach((track) => console.log(track.title, track.audio_url));
} else {
console.error('Generation failed:', music.error);
}
}

generateSong();

Response — Step 1 (creation):​

{
"id": "5f0c2a9e-3b7d-4c1a-9e2f-8d6b4a1c7e30",
"external_id": null,
"object": "music.generation",
"model": "suno-v6",
"status": "in_progress",
"created_at": 1761559200,
"completed_at": null,
"data": [],
"usage": null,
"error": null
}

Response — Step 2 (completed):​

{
"id": "5f0c2a9e-3b7d-4c1a-9e2f-8d6b4a1c7e30",
"external_id": null,
"object": "music.generation",
"model": "suno-v6",
"status": "completed",
"created_at": 1761559200,
"completed_at": 1761559318,
"data": [
{
"id": "c1d2e3f4-0000-4a5b-8c9d-0e1f2a3b4c5d",
"audio_url": "https://storage.bothub.chat/files/c1d2e3f4.mp3",
"image_url": "https://storage.bothub.chat/images/c1d2e3f4.jpeg",
"title": "Night City",
"tags": "synthwave, 80s retro, 110 bpm, dreamy female vocals, analog synths",
"lyrics": "[Verse]\nNeon light on the wet asphalt\n...",
"duration": 178
},
{
"id": "d2e3f4a5-0000-4b6c-9d0e-1f2a3b4c5d6e",
"audio_url": "https://storage.bothub.chat/files/d2e3f4a5.mp3",
"image_url": "https://storage.bothub.chat/images/d2e3f4a5.jpeg",
"title": "Night City",
"tags": "synthwave, 80s retro, 110 bpm, dreamy female vocals, analog synths",
"lyrics": "[Verse]\nNeon light on the wet asphalt\n...",
"duration": 182
}
],
"usage": {
"caps": 64530
},
"error": null
}

usage.caps is the amount charged for the generation.


A Song From a Description​

Suno writes the lyrics itself; they come back in data[].lyrics.

curl https://openai.bothub.chat/v1/music/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_BOTHUB_API_KEY" \
-d '{
"model": "suno-v6",
"prompt": "A cheerful acoustic song about a road trip to the sea with friends"
}'

For background music without vocals, add "instrumental": true.


Your Own Job ID and Safe Retries​

Pass your own ID, an order number for example, in external_id. It must be unique within your account and comes back in every response for this job.

external_id also makes retries safe. If the connection drops before you get the response, send the request again with the same external_id: BotHub does not start a second generation and returns the job created by the first request, with the same id. Nothing is charged twice. The other fields of the repeated request are not compared with the first one.

If the job with this external_id has failed, a repeated request starts the generation again and moves the external_id to the new job. A failed generation is not charged.

curl https://openai.bothub.chat/v1/music/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_BOTHUB_API_KEY" \
-d '{
"model": "suno-v6",
"external_id": "order-12345",
"prompt": "A cheerful acoustic song about a road trip to the sea with friends"
}'

List Available Models​

curl https://openai.bothub.chat/v1/music/models \
-H "Authorization: Bearer YOUR_BOTHUB_API_KEY"

Example Response:​

{
"object": "list",
"data": [
{ "id": "suno-v6", "object": "model", "created": 1758000000, "owned_by": "suno" }
]
}

Status Reference​

StatusDescription
in_progressGeneration is in progress
completedTracks are ready — see data
failedGeneration failed — see error. Nothing is charged

Errors​

Errors returned right away, with HTTP status 400, in the format {"status": "error", "error": {"code": "...", "message": "..."}}:

CodeReason
VALIDATION_ERRORA field has the wrong type or is out of range; error.data lists the fields
MUSIC_PROMPT_WITH_CUSTOM_FIELDSprompt was sent together with lyrics, style, title or fine-tuning fields
MUSIC_PROMPT_REQUIREDNone of prompt, lyrics or instrumental: true was sent
MUSIC_STYLE_REQUIREDAn instrumental track in the second mode needs style or negative_tags
MUSIC_PROMPT_TOO_LONGprompt is longer than 3000 characters
MUSIC_LYRICS_TOO_LONGlyrics is longer than 5000 characters
MODEL_NOT_SUPPORTED_FOR_ENDPOINTThe model does not generate music
MUSIC_ARTIST_NAMEThe request names a real artist — describe the style instead

error.code of a failed generation:

CodeReason
MUSIC_MODERATIONThe lyrics or description did not pass Suno moderation
MUSIC_ARTIST_NAMEThe request names a real artist
MUSIC_PROVIDER_ERRORSuno could not generate the track — try again

Tips​

  • Polling interval: Poll every 10–15 seconds. Most songs are ready within 1–3 minutes.
  • Song structure: Section tags in lyrics ([Verse], [Chorus], [Bridge]) help Suno build the song the way you wrote it.
  • Style without names: Describe genre, tempo, instruments and voice in style instead of naming artists — names are rejected by moderation.
  • Two takes: Both tracks in data are full versions of the same song; pick the one you like.
  • Retries: Send external_id so that a repeated request after a dropped connection does not start a second paid generation.