- 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
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.
Request example
curl --request POST \
--url https://api.openveer.com/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.openveer.com/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.openveer.com/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());Response example
{
"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
Authorization stringAll endpoints require Bearer Token authentication. Get your key from the API Key page.
Authorization: Bearer YOUR_API_KEYRequest parameters
model stringModel name. Use suno; omitted values default to suno.
task_id stringThe 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.
audio_index integerThe 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
formats string[]Array of requested file formats. At least one item is required.
Supported values:
mp3m4awav
Multiple formats may be requested together. Values are case-insensitive and duplicates are removed automatically. Result order matches request order.
format stringFor 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-task task_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}Files are usually prepared during submission, so query once immediately. If the status is neither 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.openveer.com/audio/example.mp3"
},
{
"format": "wav",
"url": "https://assets.openveer.com/audio/example.wav"
}
],
"wavUrl": "https://assets.openveer.com/audio/example.wav"
}
}
}Read 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
}
}There is no result yet. Continue polling.
Failed
{
"code": 200,
"data": {
"id": "task_01JHXXXXXXXXXXXX",
"status": "failed",
"progress": 100,
"cost": 0,
"error": {
"message": "Upstream request failed"
}
}
}Failed tasks are refunded automatically and return cost: 0. Display error.message and offer a retry.
File URLs
Results normally use OpenVeer'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 |
HTTP 403 with 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 |
The legacy endpoint remains temporarily available, but all new code should use /generations/download.
Response
code integerResponse status code; 200 on success
data arraystatus stringInitially submitted
task_id stringDownload task ID used to poll GET /v1/music/tasks/{task_id}
This documentation is built and hosted on Mintlify, a developer documentation platform.