Skip to main content

Basic generation

Send a POST request to /api/generate with a plain-language description of the music you want. Suno always produces two variations per request.
curl -X POST http://localhost:3000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A popular heavy metal song about war, sung by a deep-voiced male singer, slowly and melodiously. The lyrics depict the sorrow of people after the war.",
    "make_instrumental": false,
    "wait_audio": false
  }'

Request fields

prompt
string
required
A natural-language description of the music you want to generate. Suno uses this to write lyrics and choose a style automatically.
make_instrumental
boolean
When true, the generated track has no vocals. Defaults to false.
model
string
The Suno model to use. Defaults to chirp-v3-5 (the DEFAULT_MODEL constant). Pass a different model string to target a specific version.
wait_audio
boolean
When false (default), the request returns immediately with status "submitted". When true, the server waits up to 100 seconds for generation to finish before responding. See Polling for completion below.

The AudioInfo response

Both /api/generate and /api/get return an array of AudioInfo objects — one per clip.
[
  {
    "id": "a1b2c3d4-...",
    "title": "War's Lament",
    "image_url": "https://cdn.suno.ai/image/a1b2c3d4....jpeg",
    "lyric": "In the fields where silence reigns...",
    "audio_url": "https://cdn.suno.ai/a1b2c3d4....mp3",
    "video_url": "https://cdn.suno.ai/a1b2c3d4....mp4",
    "created_at": "2024-03-15T10:30:00.000Z",
    "model_name": "chirp-v3-5",
    "gpt_description_prompt": "A popular heavy metal song about war...",
    "prompt": "In the fields where silence reigns...",
    "status": "streaming",
    "type": "gen",
    "tags": "heavy metal, male vocalist, slow",
    "negative_tags": null,
    "duration": "180.5",
    "error_message": null
  }
]
FieldTypeDescription
idstringUnique identifier for the clip. Use this to poll for status or extend the track.
titlestring | nullTitle assigned by Suno.
image_urlstring | nullURL to the generated cover art.
lyricstring | nullThe full lyrics text.
audio_urlstring | nullDirect URL to the MP3 audio file. Populated once status is "streaming" or "complete".
video_urlstring | nullURL to a video version of the clip.
created_atstringISO 8601 timestamp of when the clip was created.
model_namestringThe model used, e.g. chirp-v3-5.
gpt_description_promptstring | nullThe original natural-language prompt sent to the generation API.
promptstring | nullThe lyric text used in the final generation.
statusstringCurrent state of the clip. See status values below.
typestring | nullInternal clip type (e.g. "gen").
tagsstring | nullGenre and style tags applied to the generation.
negative_tagsstring | nullStyles that were excluded from the generation.
durationstring | nullDuration of the audio in seconds.
error_messagestring | nullHuman-readable error detail when status is "error".

Status values

StatusMeaning
submittedRequest accepted; generation has not started yet.
queuedClip is waiting in Suno’s generation queue.
streamingAudio is being written; the file is already playable via audio_url.
completeGeneration finished; the full audio file is available.
errorGeneration failed. Check error_message for details.

Polling for completion

By default (wait_audio: false) the API returns immediately. The status will be "submitted" and audio_url will be empty. You need to poll /api/get until the audio is ready.

Default model

When you omit the model field, the API uses chirp-v3-5 — the value of the DEFAULT_MODEL constant defined in src/lib/SunoApi.ts. Pass a different string to target another model version.

Error handling

HTTP statusMeaningWhat to do
200SuccessRead the AudioInfo array.
402Payment required — account is out of creditsTop up your Suno credits or rotate to another account.
503Network error — could not reach Suno’s APICheck your internet connection and retry with exponential back-off.
500Internal server errorCheck the server logs. The response body includes an error field with details.
When a 402 is returned, the response body is {"error": "Payment required"} or a detail string from Suno. Use GET /api/get_limit to check remaining credits before generating in bulk.

Build docs developers (and LLMs) love