Overview
Retrieve the status and results of music generation tasks submitted to Suno AI . This endpoint allows you to monitor the progress of asynchronous music generation tasks and retrieve the generated audio URL once complete.
Related Guides: Suno API Documentation | Task Management Guide
After submitting a music generation request via the Text to Audio endpoint, use this endpoint to check the task status and retrieve the generated audio file.
Authentication
This endpoint requires authentication using a Bearer token.
Authorization
string
default: "sk-***********"
required
Your API key in the format: YOUR_API_KEY
Path Parameters
The task ID returned from the music generation request. Format: UUID string (e.g., “15410652-357c-47fa-8ad9-a4a145fbfa14”)
Request Example
curl --location 'https://gptproto.com/v1/suno/fetch/15410652-357c-47fa-8ad9-a4a145fbfa14' \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/json'
Response
Task completed successfully with generated audio {
"code" : "success" ,
"data" : [
{
"id" : "15410652-357c-47fa-8ad9-a4a145fbfa14" ,
"status" : "completed" ,
"audio_url" : "https://cdn1.suno.ai/6bcfbc4c-81c3-4043-aa6d-a078e64f59f6.mp3" ,
"video_url" : "https://cdn1.suno.ai/6bcfbc4c-81c3-4043-aa6d-a078e64f59f6.mp4" ,
"image_url" : "https://cdn1.suno.ai/6bcfbc4c-81c3-4043-aa6d-a078e64f59f6.jpeg" ,
"title" : "Battle Prelude" ,
"tags" : "orchestral, epic, dramatic" ,
"prompt" : "Generate tense prelude music for an ancient battlefield before battle" ,
"duration" : 30 ,
"created_at" : "2024-01-15T10:30:00Z" ,
"model_name" : "chirp-v3-5"
}
],
"message" : ""
}
Status code: "success" or "error"
Array containing task information Task status: queued, processing, completed, or failed
URL to download the generated MP3 audio file (only when completed)
URL to download the generated video with visualization (only when completed)
URL to the cover image/thumbnail (only when completed)
Song title (auto-generated or custom)
Original prompt used for generation
Audio duration in seconds (only when completed)
ISO 8601 timestamp of task creation
Model version used (e.g., “chirp-v3-5”)
Progress percentage 0-100 (only when processing)
Error description if failed
Error message if code is "error", empty string if successful
Task is currently being processed {
"code" : "success" ,
"data" : [
{
"id" : "15410652-357c-47fa-8ad9-a4a145fbfa14" ,
"status" : "processing" ,
"progress" : 45 ,
"created_at" : "2024-01-15T10:30:00Z"
}
],
"message" : "Task is still processing"
}
Task is waiting in queue {
"code" : "success" ,
"data" : [
{
"id" : "15410652-357c-47fa-8ad9-a4a145fbfa14" ,
"status" : "queued" ,
"created_at" : "2024-01-15T10:30:00Z"
}
],
"message" : "Task is queued"
}
Task Status Values
Status Description Next Action queuedTask is waiting in queue to be processed Continue polling processingTask is currently being processed Continue polling, check progress completedTask completed successfully, audio is ready Download audio from audio_url failedTask failed Check error_message, retry if needed
Error Responses
404 - Task not found
401 - Invalid API key
403 - Insufficient balance
429 - Rate limit exceeded
500 - Internal server error
{
"code" : "error" ,
"data" : null ,
"message" : "Task not found"
}
Polling for Completion
Python Example - Wait for Completion
import requests
import time
def wait_for_completion ( task_id , max_wait = 300 , poll_interval = 5 ):
"""
Poll task status until completion or timeout
Args:
task_id: The task ID to monitor
max_wait: Maximum time to wait in seconds (default 300s)
poll_interval: Time between polls in seconds (default 5s)
Returns:
Task data if successful, None if timeout or error
"""
url = f "https://gptproto.com/v1/suno/fetch/ { task_id } "
headers = {
"Authorization" : "YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
start_time = time.time()
while time.time() - start_time < max_wait:
try :
response = requests.get(url, headers = headers)
result = response.json()
if result[ "code" ] != "success" or not result[ "data" ]:
print ( f "Error: { result.get( 'message' , 'Unknown error' ) } " )
return None
task = result[ "data" ][ 0 ]
status = task[ "status" ]
elapsed = int (time.time() - start_time)
print ( f "[ { elapsed } s] Status: { status } " , end = "" )
if status == "completed" :
print ( f " \n ✓ Music generated successfully!" )
print ( f "Audio URL: { task[ 'audio_url' ] } " )
return task
elif status == "failed" :
error_msg = task.get( 'error_message' , 'Unknown error' )
print ( f " \n ✗ Generation failed: { error_msg } " )
return None
elif status == "processing" :
progress = task.get( 'progress' , 0 )
print ( f " - Progress: { progress } %" )
else : # queued
print ( " - Waiting in queue..." )
time.sleep(poll_interval)
except Exception as e:
print ( f " \n Error querying task: { e } " )
time.sleep(poll_interval)
print ( f " \n ✗ Timeout: Task did not complete within { max_wait } seconds" )
return None
# Usage
task_id = "15410652-357c-47fa-8ad9-a4a145fbfa14"
result = wait_for_completion(task_id)
if result:
print ( f "Title: { result.get( 'title' , 'Untitled' ) } " )
print ( f "Duration: { result.get( 'duration' , 0 ) } seconds" )
JavaScript Example - Wait for Completion
async function waitForCompletion ( taskId , maxWait = 300 , pollInterval = 5 ) {
const url = `https://gptproto.com/v1/suno/fetch/ ${ taskId } ` ;
const headers = {
'Authorization' : 'YOUR_API_KEY' ,
'Content-Type' : 'application/json'
};
const startTime = Date . now ();
while (( Date . now () - startTime ) / 1000 < maxWait ) {
try {
const response = await fetch ( url , { method: 'GET' , headers });
const result = await response . json ();
if ( result . code !== 'success' || ! result . data ) {
console . log ( `Error: ${ result . message || 'Unknown error' } ` );
return null ;
}
const task = result . data [ 0 ];
const elapsed = Math . floor (( Date . now () - startTime ) / 1000 );
process . stdout . write ( `[ ${ elapsed } s] Status: ${ task . status } ` );
if ( task . status === 'completed' ) {
console . log ( ' \n ✓ Music generated successfully!' );
console . log ( `Audio URL: ${ task . audio_url } ` );
return task ;
} else if ( task . status === 'failed' ) {
console . log ( ` \n ✗ Generation failed: ${ task . error_message || 'Unknown error' } ` );
return null ;
} else if ( task . status === 'processing' ) {
console . log ( ` - Progress: ${ task . progress || 0 } %` );
} else {
console . log ( ' - Waiting in queue...' );
}
await new Promise ( resolve => setTimeout ( resolve , pollInterval * 1000 ));
} catch ( error ) {
console . log ( ` \n Error querying task: ${ error } ` );
await new Promise ( resolve => setTimeout ( resolve , pollInterval * 1000 ));
}
}
console . log ( ` \n ✗ Timeout: Task did not complete within ${ maxWait } seconds` );
return null ;
}
// Usage
const taskId = '15410652-357c-47fa-8ad9-a4a145fbfa14' ;
waitForCompletion ( taskId ). then ( result => {
if ( result ) {
console . log ( `Title: ${ result . title || 'Untitled' } ` );
console . log ( `Duration: ${ result . duration || 0 } seconds` );
}
});
Complete Workflow Example
Here’s a complete example from submission to download:
import requests
import time
import os
class SunoMusicGenerator :
def __init__ ( self , api_key ):
self .api_key = api_key
self .base_url = "https://gptproto.com/v1/suno"
self .headers = {
"Authorization" : api_key,
"Content-Type" : "application/json"
}
def submit_task ( self , prompt , ** kwargs ):
"""Submit a music generation task"""
url = f " { self .base_url } /submit/music"
payload = { "prompt" : prompt, ** kwargs}
response = requests.post(url, headers = self .headers, json = payload)
result = response.json()
if result[ "code" ] == "success" :
print ( f "✓ Task submitted: { result[ 'data' ] } " )
return result[ "data" ]
else :
raise Exception ( f "Error: { result[ 'message' ] } " )
def query_task ( self , task_id ):
"""Query task status"""
url = f " { self .base_url } /fetch/ { task_id } "
response = requests.get(url, headers = self .headers)
result = response.json()
if result[ "code" ] == "success" and result[ "data" ]:
return result[ "data" ][ 0 ]
return None
def wait_for_completion ( self , task_id , max_wait = 300 , poll_interval = 5 ):
"""Wait for task to complete"""
start_time = time.time()
while time.time() - start_time < max_wait:
task = self .query_task(task_id)
if not task:
return None
elapsed = int (time.time() - start_time)
print ( f "[ { elapsed } s] { task[ 'status' ] } " , end = "" )
if task[ "status" ] == "completed" :
print ( " ✓" )
return task
elif task[ "status" ] == "failed" :
print ( f " ✗ { task.get( 'error_message' , 'Unknown error' ) } " )
return None
elif task[ "status" ] == "processing" :
print ( f " - { task.get( 'progress' , 0 ) } %" )
else :
print ( " - queued" )
time.sleep(poll_interval)
print ( f " \n ✗ Timeout after { max_wait } s" )
return None
def download_audio ( self , audio_url , output_path ):
"""Download the generated audio"""
response = requests.get(audio_url)
if response.status_code == 200 :
os.makedirs(os.path.dirname(output_path), exist_ok = True )
with open (output_path, 'wb' ) as f:
f.write(response.content)
print ( f "✓ Downloaded to: { output_path } " )
return True
return False
def generate_and_download ( self , prompt , output_dir = "./music" , ** kwargs ):
"""Complete workflow: submit, wait, and download"""
# Submit task
task_id = self .submit_task(prompt, ** kwargs)
# Wait for completion
task = self .wait_for_completion(task_id)
if not task:
print ( "✗ Generation failed or timed out" )
return None
# Download audio
title = task.get( "title" , "untitled" ).replace( " " , "_" )
output_path = os.path.join(output_dir, f " { title } .mp3" )
if self .download_audio(task[ "audio_url" ], output_path):
return {
"task_id" : task_id,
"audio_path" : output_path,
"task_data" : task
}
return None
# Usage
generator = SunoMusicGenerator( "YOUR_API_KEY" )
result = generator.generate_and_download(
prompt = "Epic orchestral battle music with dramatic crescendo" ,
tags = "orchestral, epic, cinematic" ,
make_instrumental = True
)
if result:
print ( f " \n { '=' * 50 } " )
print ( f "Task ID: { result[ 'task_id' ] } " )
print ( f "Audio File: { result[ 'audio_path' ] } " )
print ( f "Title: { result[ 'task_data' ][ 'title' ] } " )
print ( f "Duration: { result[ 'task_data' ][ 'duration' ] } s" )
print ( f " { '=' * 50 } " )
Best Practices
Polling Recommendations:
Initial Poll : Check immediately after submission
Queued Status : Poll every 5-10 seconds
Processing Status : Poll every 3-5 seconds
Rate Limiting : Don’t poll more than once per second
Timeout : Set reasonable timeouts (60-300 seconds depending on complexity)
Timeout Configuration
# Recommended timeouts based on complexity
TIMEOUT_MAP = {
"simple" : 60 , # 1 minute
"standard" : 120 , # 2 minutes
"complex" : 300 # 5 minutes
}
def smart_wait ( task_id , complexity = "standard" ):
timeout = TIMEOUT_MAP .get(complexity, 120 )
return wait_for_completion(task_id, max_wait = timeout)
Error Handling
def robust_query ( task_id , retries = 3 ):
"""Query with retry logic"""
for attempt in range (retries):
try :
response = requests.get(
f "https://gptproto.com/v1/suno/fetch/ { task_id } " ,
headers = headers,
timeout = 10
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
if attempt == retries - 1 :
raise
print ( f "Retry { attempt + 1 } / { retries } after error: { e } " )
time.sleep( 2 ** attempt) # Exponential backoff
return None
FAQs
How long does generation typically take?
Most tasks complete within 30-90 seconds. Complex or custom music may take up to 3-5 minutes.
How long are task results stored?
Completed tasks and their audio URLs are available for 24 hours after completion.
Can I download the same audio multiple times?
Yes, the audio URL remains valid for 24 hours after generation.
Generated audio is provided in MP3 format at 128-320 kbps quality.
Can I get a video with visualization?
Yes, use the video_url field for videos with audio visualization.
What if my task fails?
Check the error_message field for details. Common causes include invalid prompts or system errors. You can retry the request.
Text to Audio - Submit music generation tasks
Custom Music - Generate with lyrics and advanced options
Music Continuation - Extend existing tracks
Official Resources
Suno AI Documentation
GPT Proto Resources
Additional Resources