curl --request POST \
--url https://api.apimart.ai/v1/music/generations/download \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"]
}'
import requests
response = requests.post(
"https://api.apimart.ai/v1/music/generations/download",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
},
json={
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"],
},
)
print(response.json())
const response = await fetch(
"https://api.apimart.ai/v1/music/generations/download",
{
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "suno",
task_id: "task_01JGXXXXXXXXXXXX",
audio_index: 1,
formats: ["mp3", "wav"],
}),
},
);
console.log(await response.json());
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01JHXXXXXXXXXXXX"
}
]
}
{
"error": {
"message": "`formats` contains unsupported format `flac`. Supported: mp3 / m4a / wav",
"type": "invalid_request_error",
"code": "invalid_source_reference"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Check your API key.",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Try again later.",
"type": "rate_limit_error"
}
}
Suno
Download Audio Files
- Download Suno songs as MP3, M4A, or WAV files
- Request multiple formats at once and receive a URL for each file
- Select the source song with task_id and audio_index
- Submit asynchronously and query the music task endpoint for results
POST
/
v1
/
music
/
generations
/
download
curl --request POST \
--url https://api.apimart.ai/v1/music/generations/download \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"]
}'
import requests
response = requests.post(
"https://api.apimart.ai/v1/music/generations/download",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
},
json={
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"],
},
)
print(response.json())
const response = await fetch(
"https://api.apimart.ai/v1/music/generations/download",
{
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "suno",
task_id: "task_01JGXXXXXXXXXXXX",
audio_index: 1,
formats: ["mp3", "wav"],
}),
},
);
console.log(await response.json());
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01JHXXXXXXXXXXXX"
}
]
}
{
"error": {
"message": "`formats` contains unsupported format `flac`. Supported: mp3 / m4a / wav",
"type": "invalid_request_error",
"code": "invalid_source_reference"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Check your API key.",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Try again later.",
"type": "rate_limit_error"
}
}
The former
POST /v1/music/generations/wav endpoint is deprecated. It remains temporarily compatible and is equivalent to the new endpoint with formats: ["wav"]. New integrations should use POST /v1/music/generations/download.Select the source song: pass the
task_id returned by the task that created the source audio, then use audio_index to select a track from its music[] result. The index is 1-based and defaults to 1.curl --request POST \
--url https://api.apimart.ai/v1/music/generations/download \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"]
}'
import requests
response = requests.post(
"https://api.apimart.ai/v1/music/generations/download",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
},
json={
"model": "suno",
"task_id": "task_01JGXXXXXXXXXXXX",
"audio_index": 1,
"formats": ["mp3", "wav"],
},
)
print(response.json())
const response = await fetch(
"https://api.apimart.ai/v1/music/generations/download",
{
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "suno",
task_id: "task_01JGXXXXXXXXXXXX",
audio_index: 1,
formats: ["mp3", "wav"],
}),
},
);
console.log(await response.json());
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01JHXXXXXXXXXXXX"
}
]
}
{
"error": {
"message": "`formats` contains unsupported format `flac`. Supported: mp3 / m4a / wav",
"type": "invalid_request_error",
"code": "invalid_source_reference"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed. Check your API key.",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "Too many requests. Try again later.",
"type": "rate_limit_error"
}
}
Authentication
string
required
All endpoints require Bearer Token authentication. Get your key from the API Key page.
Authorization: Bearer YOUR_API_KEY
Request parameters
string
default:"suno"
Model name. Use
suno; omitted values default to suno.string
required
The task ID returned when the source song was created.The source task must belong to the current account, be completed, and contain a downloadable audio track. Music generation, extension, cover, and stem tasks can be used; text-only tasks such as lyrics or BPM analysis cannot.
integer
default:"1"
The track to download from the source task’s
music[] result.- 1-based index
- Default:
1 - Must not exceed the number of tracks in the source task
string[]
Array of requested file formats. At least one item is required.Supported values:
mp3m4awav
string
For a single format, this field can be used instead of
formats.Example: "format": "mp3"Use either
formats or format. Omitting both, or passing an empty format list, returns HTTP 400.Submission response
Successful submission returns a new download-tasktask_id:
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01JHXXXXXXXXXXXX"
}
]
}
data is an array; read data[0].task_id. This is the new download task ID, not the source-song task_id sent in the request.Query download results
Query with the download task ID from the submission response:GET /v1/music/tasks/{task_id}
completed nor failed, poll every 2 seconds for up to 60 seconds.
Completed
{
"code": 200,
"data": {
"id": "task_01JHXXXXXXXXXXXX",
"status": "completed",
"progress": 100,
"created": 1756800000,
"completed": 1756800003,
"actual_time": 3,
"cost": 0.01,
"credits_cost": 0.1,
"result": {
"music_id": "518c74ee-62ac-4ccd-b3d9-7003acd12ad7",
"files": [
{
"format": "mp3",
"url": "https://assets.apimart.ai/audio/example.mp3"
},
{
"format": "wav",
"url": "https://assets.apimart.ai/audio/example.wav"
}
],
"wavUrl": "https://assets.apimart.ai/audio/example.wav"
}
}
}
result.files[] to obtain downloads:
| Field | Type | Description |
|---|---|---|
format | string | mp3 / m4a / wav |
url | string | File download URL |
result.wavUrl only exists for compatibility with the legacy WAV endpoint. New code should always read result.files[].Processing
{
"code": 200,
"data": {
"id": "task_01JHXXXXXXXXXXXX",
"status": "processing",
"progress": 50,
"created": 1756800000
}
}
result yet. Continue polling.
Failed
{
"code": 200,
"data": {
"id": "task_01JHXXXXXXXXXXXX",
"status": "failed",
"progress": 100,
"cost": 0,
"error": {
"message": "Upstream request failed"
}
}
}
cost: 0. Display error.message and offer a retry.
File URLs
Results normally use APIMart’s file domain. If storage transfer fails, an upstream CDN URL may be returned and its lifetime is not guaranteed.Download and store the file promptly. Do not rely on a temporary URL for long-term storage.
Errors
Submission validation errors return HTTP 400 before task creation and billing:| Error text | Cause |
|---|---|
formats is required / must contain at least one | Missing format |
unsupported format | Value other than mp3 / m4a / wav |
task_id is required / invalid task_id format | Missing or malformed source task ID |
source task not found | Source task does not exist or belongs to another account |
audio_index N out of range | Track index exceeds the source result |
track #N has no music_id | Source task is unfinished or the selected track has no audio |
model_price_not_configured means suno@download pricing is not configured; contact platform support.
Billing and repeated downloads
The download endpoint is billed per request:- One request with multiple formats incurs one charge
- Submitting the same song again creates another charge, even for the same format
- Requesting another format in a later task incurs another charge
- Failed download tasks are refunded automatically
Reuse returned file URLs and disable the download button while a request is in progress to prevent duplicate submissions and charges.
Migrate from the legacy endpoint
| Item | Legacy | Current |
|---|---|---|
| Request path | /v1/music/generations/wav | /v1/music/generations/download |
| Formats | WAV only | MP3 / M4A / WAV; multiple allowed |
| New parameter | — | formats or format |
| Result | result.wavUrl | result.files[] |
| Compatibility | result.wavUrl | May also return result.wavUrl when WAV is requested |
/generations/download.
Response
integer
Response status code; 200 on success