Song media download and preview API
Endpoint description
This group of endpoints separates "getting a media address" from "actually downloading the file":
- To get an address you can play or download directly (for example to put into your own player, or to copy into object storage): use
POST /api/music/download-url, or theGET /api/music/downloadalready given in responses. - To let the browser save the file to disk: use
POST /api/music/download-file(single file) orPOST /api/music/download-all(archive). - If the song is still generating and you want to listen first: use
POST /api/music/generation-stream-url.
Billing: All free. Downloading and previewing only read media the platform already hosts; they do not call Suno and are not charged.
Recommended model: suno-v6. suno-v6, suno-v6-wild or suno-v6-mini are available.
Authentication
| Parameter | Type | Required | Notes |
|---|---|---|---|
| Authorization | string | yes | Bearer YOUR_API_KEY (GET /api/music/download also accepts a browser login session) |
| Content-Type | string | yes | application/json |
Supported media types (kind)
| kind | Notes |
|---|---|
song |
Audio (mp3 is an alias and the default; responses always write it back as song) |
wav |
WAV file; prepare it first with the WAV generation/retrieval API |
video |
Video (mp4 is an alias) |
midi |
Per-stem MIDI; only valid for stems whose separation has finished — see the MIDI retrieval API |
cover |
Cover image (image is an alias) |
lyrics |
Lyrics text (.txt); can only be fetched with download-file / GET /api/music/download — download-url does not return a lyrics address |
timestamped_lyrics |
Timestamped lyrics file (.lrc, alias lrc). Currently only some songs are supported; when it returns success:false, use the Timestamped lyrics API to get the timeline and build the file yourself |
1) Getting a media address
curl -X POST https://www.suno-api.io/api/music/download-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_id": "song_id", "kind": "song"}'
{
"code": 200,
"message": "success",
"data": {
"song_id": "song_id",
"kind": "song",
"url": "https://media.suno-api.io/assets/song_id-mp3.mp3",
"nav_url": "https://media.suno-api.io/assets/song_id-mp3.mp3?...&response-content-disposition=attachment..."
}
}
| Parameter | Type | Required | Notes |
|---|---|---|---|
| song_id | string | yes | Your own song ID |
| kind | string | no | See the table above; defaults to song |
| refresh | boolean | no | Passing true forces the resource to be prepared again (for example after the file on the CDN has been reclaimed) |
url is for playback or copying out yourself; nav_url carries Content-Disposition: attachment,
which suits pasting straight into a browser address bar to download (use it when some mobile browsers do not support blob downloads).
⚠️ Address validity: 7 days — copy the file out in time
url/nav_urlpoint at the platform's object storage and expire after 7 days by default (the files are reclaimed and the old address returns 404). Copy them into your own storage within those 7 days.After expiry you do not need to regenerate the song: call
POST /api/music/download-urlagain (or passrefresh: true) to get fresh valid addresses for that song. This group of endpoints is free and adds no charge.
2) Downloading a single file directly
curl -X POST https://www.suno-api.io/api/music/download-file \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_id": "song_id", "kind": "song"}' \
-o song.mp3
The response body is a file stream (not JSON), and Content-Disposition already carries the file name.
Lyrics and timestamped lyrics can only be fetched with this endpoint (download-url returns media addresses only, not lyrics).
The .lrc file is currently supported for only some songs; if it returns success:false, build the .lrc yourself with the
Timestamped lyrics API as shown in the next section, and do not retry.
How to get timestamped lyrics (.lrc)
Two steps are recommended, and they work for any song:
Step 1: fetch the per-word timeline (free)
curl -X POST https://www.suno-api.io/api/lyrics/timeline \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "suno-v6", "song_id": "song_id"}'
The return is a plain array (no data wrapper); each element looks like
{"word": "…", "start_s": 1.117, "end_s": 8.138, "success": true, "p_align": 0.99}.
word already contains newlines, so you can split it by line; for field meanings, filtering out instrumental sections and other caveats see
the "Fields" and "Usage notes" of the Timestamped lyrics API.
Step 2: build the .lrc yourself from start_s (time format [mm:ss.cc])
def to_lrc(segments):
lines = []
for seg in segments:
text = seg["word"].strip()
if not text:
continue
start = max(0.0, float(seg["start_s"]))
cs = int(start * 100 + 0.5)
lines.append(f"[{cs // 6000:02d}:{(cs % 6000) // 100:02d}.{cs % 100:02d}]{text}")
return "\n".join(lines)
GET /api/music/download?song_id=<id>&kind=lrc can also download the server-generated .lrc directly,
but currently only some songs are supported: if it returns success:false, generate it yourself as above —
no retry needed, and billing is unaffected either way.
3) Package download
curl -X POST https://www.suno-api.io/api/music/download-all \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_ids": ["song_id_1", "song_id_2"]}' \
-o songs.zip
Use either song_id (single) or song_ids (batch, up to 50 entries). The response body is a ZIP file stream.
4) Stable download address
GET /api/music/download?song_id=<id>&kind=<kind> is the download entry point given directly in song responses.
It accepts both an API key and a browser login session, behaves the same as download-file, and suits being hard-coded into a client or a third-party player.
5) Preview while generating
curl -X POST https://www.suno-api.io/api/music/generation-stream-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_ids": ["song_id_1", "song_id_2"]}'
{
"code": 200,
"message": "success",
"data": {
"items": [
{
"song_id": "song_id_1",
"url": "https://media.suno-api.io/assets/song_id_1-mp3.mp3",
"expires_at": 0,
"content_type": "audio/mpeg",
"playable_until_completed": false,
"mode": "mp3",
"ranges": true
}
]
}
}
| Parameter | Type | Required | Notes |
|---|---|---|---|
| song_id | string | no | A single song ID |
| song_ids | string[] | no | Batch, up to 24 entries (the maximum number of stems in an automatic separation batch) |
A playable_until_completed of true means this is a temporary preview address for a song still being generated; switch to the permanent address once the song completes.
If one song fails, that item carries an error field and the other songs are returned as usual.
Notes
- Every endpoint returns platform-hosted media addresses only; it never returns Suno's encrypted source or a temporary signed address.
- Addresses are not permanent — copy the files out yourself if you need to keep them long-term; use
download-filewhen you need the original file on disk. - A stem's MIDI requires that stem's separation to have finished, otherwise an error is returned.
Get an API key
Create an API key in the console after signing up. ¥0.6 per run returns 2 tracks, downloads are unlimited, and no phone number is required.
Get API key Back to overview