Documentation Index Fetch the complete documentation index at: https://old-docs.kie.ai/llms.txt
Use this file to discover all available pages before exploring further.
Welcome to Suno API
The Suno API enables you to create high-quality AI-generated music, lyrics, and audio content using state-of-the-art AI models. Whether you’re building a music app, automating creative workflows, or developing audio content, our API provides comprehensive tools for music generation and audio processing.
Generate Music Create original music tracks with or without lyrics
Extend Music Extend existing music tracks seamlessly
Generate Lyrics Create creative lyrics from text prompts
Music Videos Convert audio tracks into visual music videos
Upload & Cover Transform uploaded audio into new styles
Upload & Extend Upload audio files and extend them seamlessly
Add Instrumental Generate instrumental accompaniment for uploaded audio
Add Vocals Add vocal singing to uploaded audio files
Separate Vocals Separate vocals and instrumentals from music
Convert to WAV Convert audio to high-quality WAV format
Get Lyrics Retrieve timestamped synchronized lyrics
Authentication
All API requests require authentication using a Bearer token. Get your API key from the API Key Management Page .
Keep your API key secure and never share it publicly. If compromised, reset it immediately.
API Base URL
Authorization : Bearer YOUR_API_KEY
Quick Start Guide
Step 1: Generate Your First Music Track
Start with a simple music generation request:
curl -X POST "https://api.kie.ai/api/v1/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A calm and relaxing piano track with soft melodies",
"customMode": false,
"instrumental": true,
"model": "V3_5",
"callBackUrl": "https://your-app.com/callback"
}'
Step 2: Check Task Status
Use the returned task ID to check the generation status:
curl -X GET "https://api.kie.ai/api/v1/generate/record-info?taskId=YOUR_TASK_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
Successful Response:
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"taskId" : "5c79****be8e"
}
}
Task Status Response:
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"taskId" : "5c79****be8e" ,
"status" : "SUCCESS" ,
"response" : {
"sunoData" : [
{
"id" : "e231****-****-****-****-****8cadc7dc" ,
"audioUrl" : "https://example.cn/****.mp3" ,
"streamAudioUrl" : "https://example.cn/****" ,
"imageUrl" : "https://example.cn/****.jpeg" ,
"prompt" : "A calm and relaxing piano track" ,
"title" : "Peaceful Piano" ,
"tags" : "calm, relaxing, piano" ,
"duration" : 198.44 ,
"createTime" : "2025-01-01 00:00:00"
}
]
}
}
}
Core Features
Text-to-Music : Generate music from text descriptions with AI
Music Extension : Seamlessly extend existing audio tracks
Lyrics Generation : Create structured lyrical content from creative prompts
Audio Upload & Cover : Upload audio files and transform them into different musical styles
Add Instrumental : Generate instrumental accompaniment for uploaded audio files
Add Vocals : Add vocal singing to uploaded audio files with custom styles
Vocal Separation : Isolate vocals, instrumentals, and other audio components
Format Conversion : Support for WAV and other high-quality audio formats
Music Videos : Create visual content synchronized with your audio tracks
Audio Processing : Comprehensive tools for audio enhancement and manipulation
AI Models
Choose the right model for your needs:
V3_5 Better song structure Max 4 minutes, improved song organization
V4 Improved vocals Max 4 minutes, enhanced vocal quality
V4_5 Smart prompts Max 8 minutes, faster generation
V4_5PLUS Richer sound Max 8 minutes, new creative ways
V4_5ALL Smart and fast Max 8 minutes, smarter prompts, faster generations
V5 Faster generation Max 8 minutes, superior musicality, improved speed
Generation Modes
Controls parameter complexity:
false: Simple mode, only prompt required
true: Advanced mode, requires style and title
Determines if music includes vocals:
true: Instrumental only (no lyrics)
false: Include vocals/lyrics
Key Parameters
Text description of the desired music. Be specific about genre, mood, and instruments. Character Limits:
Non-custom mode: 500 characters
Custom mode (V3_5 & V4): 3000 characters
Custom mode (V4_5, V4_5PLUS & V5): 5000 characters
Music style specification (Custom Mode only). Examples: Jazz, Classical, Electronic, Pop, Rock, Hip-hopCharacter Limits:
V3_5 & V4: 200 characters
V4_5, V4_5PLUS & V5: 1000 characters
Title for the generated music track (Custom Mode only). Max length: 80 characters
Complete Workflow Example
Here’s a complete example that generates music with lyrics and waits for completion:
class SunoAPI {
constructor ( apiKey ) {
this . apiKey = apiKey ;
this . baseUrl = 'https://api.kie.ai/api/v1' ;
}
async generateMusic ( prompt , options = {}) {
const response = await fetch ( ` ${ this . baseUrl } /generate` , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ this . apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
prompt ,
customMode: options . customMode || false ,
instrumental: options . instrumental || false ,
model: options . model || 'V3_5' ,
style: options . style ,
title: options . title ,
negativeTags: options . negativeTags ,
callBackUrl: options . callBackUrl || 'https://your-app.com/callback'
})
});
const result = await response . json ();
if ( ! response . ok || result . code !== 200 ) {
throw new Error ( `Generation failed: ${ result . msg || 'Unknown error' } ` );
}
return result . data . taskId ;
}
async extendMusic ( audioId , options = {}) {
const response = await fetch ( ` ${ this . baseUrl } /generate/extend` , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ this . apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
audioId ,
defaultParamFlag: options . defaultParamFlag || false ,
model: options . model || 'V3_5' ,
prompt: options . prompt ,
style: options . style ,
title: options . title ,
continueAt: options . continueAt ,
callBackUrl: options . callBackUrl || 'https://your-app.com/callback'
})
});
const result = await response . json ();
if ( ! response . ok || result . code !== 200 ) {
throw new Error ( `Extension failed: ${ result . msg || 'Unknown error' } ` );
}
return result . data . taskId ;
}
async generateLyrics ( prompt , callBackUrl ) {
const response = await fetch ( ` ${ this . baseUrl } /lyrics` , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ this . apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
prompt ,
callBackUrl
})
});
const result = await response . json ();
if ( ! response . ok || result . code !== 200 ) {
throw new Error ( `Lyrics generation failed: ${ result . msg || 'Unknown error' } ` );
}
return result . data . taskId ;
}
async waitForCompletion ( taskId , maxWaitTime = 600000 ) { // 10 minutes max
const startTime = Date . now ();
while ( Date . now () - startTime < maxWaitTime ) {
const status = await this . getTaskStatus ( taskId );
switch ( status . status ) {
case 'SUCCESS' :
console . log ( 'All tracks generated successfully!' );
return status . response ;
case 'FIRST_SUCCESS' :
console . log ( 'First track generation completed!' );
return status . response ;
case 'TEXT_SUCCESS' :
console . log ( 'Lyrics/text generation successful!' );
return status . response ;
case 'PENDING' :
console . log ( 'Task is pending...' );
break ;
case 'CREATE_TASK_FAILED' :
const createError = status . errorMessage || 'Task creation failed' ;
console . error ( 'Error message:' , createError );
throw new Error ( createError );
case 'GENERATE_AUDIO_FAILED' :
const audioError = status . errorMessage || 'Audio generation failed' ;
console . error ( 'Error message:' , audioError );
throw new Error ( audioError );
case 'CALLBACK_EXCEPTION' :
const callbackError = status . errorMessage || 'Callback process error' ;
console . error ( 'Error message:' , callbackError );
throw new Error ( callbackError );
case 'SENSITIVE_WORD_ERROR' :
const sensitiveError = status . errorMessage || 'Content filtered due to sensitive words' ;
console . error ( 'Error message:' , sensitiveError );
throw new Error ( sensitiveError );
default :
console . log ( `Unknown status: ${ status . status } ` );
if ( status . errorMessage ) {
console . error ( 'Error message:' , status . errorMessage );
}
break ;
}
// Wait 10 seconds before next check
await new Promise ( resolve => setTimeout ( resolve , 10000 ));
}
throw new Error ( 'Generation timeout' );
}
async getTaskStatus ( taskId ) {
const response = await fetch ( ` ${ this . baseUrl } /generate/record-info?taskId= ${ taskId } ` , {
method: 'GET' ,
headers: {
'Authorization' : `Bearer ${ this . apiKey } `
}
});
const result = await response . json ();
if ( ! response . ok || result . code !== 200 ) {
throw new Error ( `Status check failed: ${ result . msg || 'Unknown error' } ` );
}
return result . data ;
}
}
// Usage Example
async function main () {
const api = new SunoAPI ( 'YOUR_API_KEY' );
try {
// Generate music with lyrics
console . log ( 'Starting music generation...' );
const taskId = await api . generateMusic (
'A nostalgic folk song about childhood memories' ,
{
customMode: true ,
instrumental: false ,
model: 'V4_5' ,
style: 'Folk, Acoustic, Nostalgic' ,
title: 'Childhood Dreams'
}
);
// Wait for completion
console . log ( `Task ID: ${ taskId } . Waiting for completion...` );
const result = await api . waitForCompletion ( taskId );
console . log ( 'Music generated successfully!' );
console . log ( 'Generated tracks:' );
result . sunoData . forEach (( track , index ) => {
console . log ( `Track ${ index + 1 } :` );
console . log ( ` Title: ${ track . title } ` );
console . log ( ` Audio URL: ${ track . audioUrl } ` );
console . log ( ` Duration: ${ track . duration } s` );
console . log ( ` Tags: ${ track . tags } ` );
});
// Extend the first track
const firstTrack = result . sunoData [ 0 ];
console . log ( ' \n Extending the first track...' );
const extendTaskId = await api . extendMusic ( firstTrack . id , {
defaultParamFlag: true ,
prompt: 'Continue with a hopeful chorus' ,
style: 'Folk, Uplifting' ,
title: 'Childhood Dreams Extended' ,
continueAt: 60 ,
model: 'V4_5'
});
const extendResult = await api . waitForCompletion ( extendTaskId );
console . log ( 'Music extended successfully!' );
console . log ( 'Extended track URL:' , extendResult . sunoData [ 0 ]. audioUrl );
} catch ( error ) {
console . error ( 'Error:' , error . message );
}
}
main ();
import requests
import time
class SunoAPI :
def __init__ ( self , api_key ):
self .api_key = api_key
self .base_url = 'https://api.kie.ai/api/v1'
self .headers = {
'Authorization' : f 'Bearer { api_key } ' ,
'Content-Type' : 'application/json'
}
def generate_music ( self , prompt , ** options ):
data = {
'prompt' : prompt,
'customMode' : options.get( 'customMode' , False ),
'instrumental' : options.get( 'instrumental' , False ),
'model' : options.get( 'model' , 'V3_5' ),
'callBackUrl' : options.get( 'callBackUrl' , 'https://your-app.com/callback' )
}
if options.get( 'style' ):
data[ 'style' ] = options[ 'style' ]
if options.get( 'title' ):
data[ 'title' ] = options[ 'title' ]
if options.get( 'negativeTags' ):
data[ 'negativeTags' ] = options[ 'negativeTags' ]
response = requests.post( f ' { self .base_url } /generate' ,
headers = self .headers, json = data)
result = response.json()
if not response.ok or result.get( 'code' ) != 200 :
raise Exception ( f "Generation failed: { result.get( 'msg' , 'Unknown error' ) } " )
return result[ 'data' ][ 'taskId' ]
def extend_music ( self , audio_id , ** options ):
data = {
'audioId' : audio_id,
'defaultParamFlag' : options.get( 'defaultParamFlag' , False ),
'model' : options.get( 'model' , 'V3_5' ),
'callBackUrl' : options.get( 'callBackUrl' , 'https://your-app.com/callback' )
}
if options.get( 'prompt' ):
data[ 'prompt' ] = options[ 'prompt' ]
if options.get( 'style' ):
data[ 'style' ] = options[ 'style' ]
if options.get( 'title' ):
data[ 'title' ] = options[ 'title' ]
if options.get( 'continueAt' ):
data[ 'continueAt' ] = options[ 'continueAt' ]
response = requests.post( f ' { self .base_url } /generate/extend' ,
headers = self .headers, json = data)
result = response.json()
if not response.ok or result.get( 'code' ) != 200 :
raise Exception ( f "Extension failed: { result.get( 'msg' , 'Unknown error' ) } " )
return result[ 'data' ][ 'taskId' ]
def generate_lyrics ( self , prompt , callback_url ):
data = {
'prompt' : prompt,
'callBackUrl' : callback_url
}
response = requests.post( f ' { self .base_url } /lyrics' ,
headers = self .headers, json = data)
result = response.json()
if not response.ok or result.get( 'code' ) != 200 :
raise Exception ( f "Lyrics generation failed: { result.get( 'msg' , 'Unknown error' ) } " )
return result[ 'data' ][ 'taskId' ]
def wait_for_completion ( self , task_id , max_wait_time = 600 ):
start_time = time.time()
while time.time() - start_time < max_wait_time:
status = self .get_task_status(task_id)
if status[ 'status' ] == 'SUCCESS' :
print ( "All tracks generated successfully!" )
return status[ 'response' ]
elif status[ 'status' ] == 'FIRST_SUCCESS' :
print ( "First track generation completed!" )
return status[ 'response' ]
elif status[ 'status' ] == 'TEXT_SUCCESS' :
print ( "Lyrics/text generation successful!" )
return status[ 'response' ]
elif status[ 'status' ] == 'PENDING' :
print ( "Task is pending..." )
elif status[ 'status' ] == 'CREATE_TASK_FAILED' :
error_msg = status.get( 'errorMessage' , 'Task creation failed' )
print ( f "Error message: { error_msg } " )
raise Exception (error_msg)
elif status[ 'status' ] == 'GENERATE_AUDIO_FAILED' :
error_msg = status.get( 'errorMessage' , 'Audio generation failed' )
print ( f "Error message: { error_msg } " )
raise Exception (error_msg)
elif status[ 'status' ] == 'CALLBACK_EXCEPTION' :
error_msg = status.get( 'errorMessage' , 'Callback process error' )
print ( f "Error message: { error_msg } " )
raise Exception (error_msg)
elif status[ 'status' ] == 'SENSITIVE_WORD_ERROR' :
error_msg = status.get( 'errorMessage' , 'Content filtered due to sensitive words' )
print ( f "Error message: { error_msg } " )
raise Exception (error_msg)
else :
print ( f "Unknown status: { status[ 'status' ] } " )
if status.get( 'errorMessage' ):
print ( f "Error message: { status[ 'errorMessage' ] } " )
time.sleep( 10 ) # Wait 10 seconds
raise Exception ( 'Generation timeout' )
def get_task_status ( self , task_id ):
response = requests.get( f ' { self .base_url } /generate/record-info?taskId= { task_id } ' ,
headers = { 'Authorization' : f 'Bearer { self .api_key } ' })
result = response.json()
if not response.ok or result.get( 'code' ) != 200 :
raise Exception ( f "Status check failed: { result.get( 'msg' , 'Unknown error' ) } " )
return result[ 'data' ]
# Usage Example
def main ():
api = SunoAPI( 'YOUR_API_KEY' )
try :
# Generate music with lyrics
print ( 'Starting music generation...' )
task_id = api.generate_music(
'A nostalgic folk song about childhood memories' ,
customMode = True ,
instrumental = False ,
model = 'V4_5' ,
style = 'Folk, Acoustic, Nostalgic' ,
title = 'Childhood Dreams'
)
# Wait for completion
print ( f 'Task ID: { task_id } . Waiting for completion...' )
result = api.wait_for_completion(task_id)
print ( 'Music generated successfully!' )
print ( 'Generated tracks:' )
for i, track in enumerate (result[ 'sunoData' ]):
print ( f "Track { i + 1 } :" )
print ( f " Title: { track[ 'title' ] } " )
print ( f " Audio URL: { track[ 'audioUrl' ] } " )
print ( f " Duration: { track[ 'duration' ] } s" )
print ( f " Tags: { track[ 'tags' ] } " )
# Extend the first track
first_track = result[ 'sunoData' ][ 0 ]
print ( ' \n Extending the first track...' )
extend_task_id = api.extend_music(
first_track[ 'id' ],
defaultParamFlag = True ,
prompt = 'Continue with a hopeful chorus' ,
style = 'Folk, Uplifting' ,
title = 'Childhood Dreams Extended' ,
continueAt = 60 ,
model = 'V4_5'
)
extend_result = api.wait_for_completion(extend_task_id)
print ( 'Music extended successfully!' )
print ( f "Extended track URL: { extend_result[ 'sunoData' ][ 0 ][ 'audioUrl' ] } " )
except Exception as error:
print ( f 'Error: { error } ' )
if __name__ == '__main__' :
main()
Advanced Features
Boost Music Style (V4_5 Models)
Enhance your style descriptions for better results:
const response = await fetch ( 'https://api.kie.ai/api/v1/style/generate' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
content: 'Pop, Mysterious'
})
});
const result = await response . json ();
console . log ( 'Enhanced style:' , result . data . result );
Audio Processing Features
Convert, separate, and enhance your generated music:
Convert to WAV
Separate Vocals
Create Music Video
const response = await fetch ( 'https://api.kie.ai/api/v1/wav/generate' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
taskId: 'YOUR_TASK_ID' ,
audioId: 'YOUR_AUDIO_ID' ,
callBackUrl: 'https://your-app.com/callback'
})
});
const response = await fetch ( 'https://api.kie.ai/api/v1/vocal-removal/generate' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
taskId: 'YOUR_TASK_ID' ,
audioId: 'YOUR_AUDIO_ID' ,
callBackUrl: 'https://your-app.com/callback'
})
});
const response = await fetch ( 'https://api.kie.ai/api/v1/mp4/generate' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
taskId: 'YOUR_TASK_ID' ,
audioId: 'YOUR_AUDIO_ID' ,
author: 'Your Name' ,
domainName: 'your-app.com' ,
callBackUrl: 'https://your-app.com/callback'
})
});
Async Processing with Callbacks
Set up webhook callbacks for automatic notifications:
const taskId = await api . generateMusic ( 'Upbeat electronic dance music' , {
customMode: false ,
instrumental: true ,
model: 'V4_5' ,
callBackUrl: 'https://your-server.com/suno-callback'
});
// Your callback endpoint will receive:
app . post ( '/suno-callback' , ( req , res ) => {
const { code , data } = req . body ;
if ( code === 200 && data . callbackType === 'complete' ) {
console . log ( 'Music ready:' , data . data );
data . data . forEach ( track => {
console . log ( 'Track:' , track . audio_url );
});
}
res . status ( 200 ). json ({ status: 'received' });
});
Learn More About Callbacks Complete guide to implementing and handling Suno API callbacks
Status Codes & Task States
Task is waiting to be processed or currently generating
Lyrics/text generation completed successfully
First track generation completed
All tracks generated successfully
Content filtered due to sensitive words
Best Practices
Be specific about genre, mood, and instruments
Use descriptive adjectives for better style control
Include tempo and energy level descriptions
Reference musical eras or specific artists for style guidance
V3_5: Best for structured songs with clear verse/chorus patterns
V4: Choose when vocal quality is most important
V4_5: Use for faster generation and smart prompt handling
V4_5PLUS: Select for the highest quality and longest tracks
V5: Faster generation with superior musicality and improved speed
Avoid copyrighted material in prompts
Use original lyrics and musical descriptions
Be mindful of content policies for lyrical content
Test prompt variations to avoid sensitive word filters
Error Handling
Content Policy Violations (Code 400)
try {
const taskId = await api . generateMusic ( 'copyrighted song lyrics' );
} catch ( error ) {
if ( error . data . code === 400 ) {
console . log ( 'Please use original content only' );
}
}
Insufficient Credits (Code 402)
try {
const taskId = await api . generateMusic ( 'original composition' );
} catch ( error ) {
if ( error . data . code === 402 ) {
console . log ( 'Please add more credits to your account' );
}
}
const delay = ( ms ) => new Promise ( resolve => setTimeout ( resolve , ms ));
async function generateWithRetry ( prompt , options , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
return await api . generateMusic ( prompt , options );
} catch ( error ) {
if ( error . data . code === 429 && i < maxRetries - 1 ) {
await delay ( Math . pow ( 2 , i ) * 1000 ); // Exponential backoff
continue ;
}
throw error ;
}
}
}
Support
Need help? Our technical support team is here to assist you.
Ready to start creating amazing AI music? Get your API key and begin composing today!