# File Upload API Quickstart
Source: https://docs.sunoapi.org/file-upload-api/quickstart
Get started with the File Upload API in minutes, supporting multiple upload methods
## Welcome to File Upload API
The File Upload API provides flexible and efficient file upload services, supporting multiple upload methods to meet diverse business needs. Whether it's remote file migration, large file transmission, or quick small file uploads, our API offers the best solutions for your requirements.
Base64 encoded file upload, suitable for small files
Efficient binary file stream upload, ideal for large files
Automatically download and upload files from remote URLs
**File uploads are free** - No charges apply for uploading files to our service. You can upload files without worrying about upload costs or fees.
**Important Notice**: Uploaded files are temporary and will be **automatically deleted after 3 days**. Please download or migrate important files promptly.
## Authentication
All API requests require authentication using Bearer tokens. Please obtain your API key from the [API Key Management Page](https://sunoapi.org/api-key).
Please keep your API key secure and never share it publicly. If you suspect your key has been compromised, reset it immediately.
### API Base URL
```
https://sunoapiorg.redpandaai.co
```
### Authentication Header
```http theme={null}
Authorization: Bearer YOUR_API_KEY
```
## Quick Start Guide
### Step 1: Choose Your Upload Method
Select the appropriate upload method based on your needs:
Suitable for downloading and uploading files from remote servers:
```bash cURL theme={null}
curl -X POST "https://sunoapiorg.redpandaai.co/api/file-url-upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fileUrl": "https://example.com/sample-image.jpg",
"uploadPath": "images",
"fileName": "my-image.jpg"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://sunoapiorg.redpandaai.co/api/file-url-upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileUrl: 'https://example.com/sample-image.jpg',
uploadPath: 'images',
fileName: 'my-image.jpg'
})
});
const result = await response.json();
console.log('Upload successful:', result);
```
```python Python theme={null}
import requests
url = "https://sunoapiorg.redpandaai.co/api/file-url-upload"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"fileUrl": "https://example.com/sample-image.jpg",
"uploadPath": "images",
"fileName": "my-image.jpg"
}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
print(f"Upload successful: {result}")
```
Suitable for directly uploading local files, especially large files:
```bash cURL theme={null}
curl -X POST "https://sunoapiorg.redpandaai.co/api/file-stream-upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@/path/to/your-file.jpg" \
-F "uploadPath=images/user-uploads" \
-F "fileName=custom-name.jpg"
```
```javascript JavaScript theme={null}
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('uploadPath', 'images/user-uploads');
formData.append('fileName', 'custom-name.jpg');
const response = await fetch('https://sunoapiorg.redpandaai.co/api/file-stream-upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
},
body: formData
});
const result = await response.json();
console.log('Upload successful:', result);
```
```python Python theme={null}
import requests
url = "https://sunoapiorg.redpandaai.co/api/file-stream-upload"
headers = {
"Authorization": "Bearer YOUR_API_KEY"
}
files = {
'file': ('your-file.jpg', open('/path/to/your-file.jpg', 'rb')),
'uploadPath': (None, 'images/user-uploads'),
'fileName': (None, 'custom-name.jpg')
}
response = requests.post(url, headers=headers, files=files)
result = response.json()
print(f"Upload successful: {result}")
```
Suitable for Base64 encoded file data:
```bash cURL theme={null}
curl -X POST "https://sunoapiorg.redpandaai.co/api/file-base64-upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"base64Data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"uploadPath": "images",
"fileName": "base64-image.png"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://sunoapiorg.redpandaai.co/api/file-base64-upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
base64Data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...',
uploadPath: 'images',
fileName: 'base64-image.png'
})
});
const result = await response.json();
console.log('Upload successful:', result);
```
```python Python theme={null}
import requests
import base64
# Read file and convert to base64
with open('/path/to/your-file.jpg', 'rb') as f:
file_data = base64.b64encode(f.read()).decode('utf-8')
base64_data = f'data:image/jpeg;base64,{file_data}'
url = "https://sunoapiorg.redpandaai.co/api/file-base64-upload"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"base64Data": base64_data,
"uploadPath": "images",
"fileName": "base64-image.jpg"
}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
print(f"Upload successful: {result}")
```
### Step 2: Handle Response
Upon successful upload, you'll receive a response containing file information:
```json theme={null}
{
"success": true,
"code": 200,
"msg": "File uploaded successfully",
"data": {
"fileId": "file_abc123456",
"fileName": "my-image.jpg",
"originalName": "sample-image.jpg",
"fileSize": 245760,
"mimeType": "image/jpeg",
"uploadPath": "images",
"fileUrl": "https://sunoapiorg.redpandaai.co/files/images/my-image.jpg",
"downloadUrl": "https://sunoapiorg.redpandaai.co/download/file_abc123456",
"uploadTime": "2025-01-15T10:30:00Z",
"expiresAt": "2025-01-18T10:30:00Z"
}
}
```
## Upload Method Comparison
Choose the most suitable upload method for your needs:
**Best for**: File migration, batch processing
**Advantages**:
* No local file required
* Automatic download handling
* Supports remote resources
**Limitations**:
* Requires publicly accessible URL
* 30-second download timeout
* Recommended ≤100MB
**Best for**: Large files, local files
**Advantages**:
* High transmission efficiency
* Supports large files
* Binary transmission
**Limitations**:
* Requires local file
* Server processing time
**Best for**: Small files, API integration
**Advantages**:
* JSON format transmission
* Easy integration
* Supports Data URL
**Limitations**:
* Data size increases by 33%
* Not suitable for large files
* Recommended ≤10MB
## Practical Examples
### Batch File Upload
Using file stream upload to handle multiple files:
```javascript theme={null}
class FileUploadAPI {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://sunoapiorg.redpandaai.co';
}
async uploadFile(file, uploadPath = '', fileName = null) {
const formData = new FormData();
formData.append('file', file);
if (uploadPath) formData.append('uploadPath', uploadPath);
if (fileName) formData.append('fileName', fileName);
const response = await fetch(`${this.baseUrl}/api/file-stream-upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`
},
body: formData
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return response.json();
}
async uploadFromUrl(fileUrl, uploadPath = '', fileName = null) {
const response = await fetch(`${this.baseUrl}/api/file-url-upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileUrl,
uploadPath,
fileName
})
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return response.json();
}
async uploadBase64(base64Data, uploadPath = '', fileName = null) {
const response = await fetch(`${this.baseUrl}/api/file-base64-upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
base64Data,
uploadPath,
fileName
})
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return response.json();
}
}
// Usage example
const uploader = new FileUploadAPI('YOUR_API_KEY');
// Batch upload files
async function uploadMultipleFiles(files) {
const results = [];
for (let i = 0; i < files.length; i++) {
try {
const result = await uploader.uploadFile(
files[i],
'user-uploads',
`file-${i + 1}-${files[i].name}`
);
results.push(result);
console.log(`File ${i + 1} uploaded successfully:`, result.data.fileUrl);
} catch (error) {
console.error(`File ${i + 1} upload failed:`, error.message);
}
}
return results;
}
// Batch upload from URLs
async function uploadFromUrls(urls) {
const results = [];
for (let i = 0; i < urls.length; i++) {
try {
const result = await uploader.uploadFromUrl(
urls[i],
'downloads',
`download-${i + 1}.jpg`
);
results.push(result);
console.log(`URL ${i + 1} uploaded successfully:`, result.data.fileUrl);
} catch (error) {
console.error(`URL ${i + 1} upload failed:`, error.message);
}
}
return results;
}
```
```python theme={null}
import requests
import base64
import os
from typing import List, Optional
class FileUploadAPI:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://sunoapiorg.redpandaai.co'
self.headers = {
'Authorization': f'Bearer {api_key}'
}
def upload_file(self, file_path: str, upload_path: str = '',
file_name: Optional[str] = None) -> dict:
"""File stream upload"""
files = {
'file': (os.path.basename(file_path), open(file_path, 'rb'))
}
data = {}
if upload_path:
data['uploadPath'] = upload_path
if file_name:
data['fileName'] = file_name
response = requests.post(
f'{self.base_url}/api/file-stream-upload',
headers=self.headers,
files=files,
data=data
)
if not response.ok:
raise Exception(f'Upload failed: {response.text}')
return response.json()
def upload_from_url(self, file_url: str, upload_path: str = '',
file_name: Optional[str] = None) -> dict:
"""URL file upload"""
payload = {
'fileUrl': file_url,
'uploadPath': upload_path,
'fileName': file_name
}
response = requests.post(
f'{self.base_url}/api/file-url-upload',
headers={**self.headers, 'Content-Type': 'application/json'},
json=payload
)
if not response.ok:
raise Exception(f'Upload failed: {response.text}')
return response.json()
def upload_base64(self, base64_data: str, upload_path: str = '',
file_name: Optional[str] = None) -> dict:
"""Base64 file upload"""
payload = {
'base64Data': base64_data,
'uploadPath': upload_path,
'fileName': file_name
}
response = requests.post(
f'{self.base_url}/api/file-base64-upload',
headers={**self.headers, 'Content-Type': 'application/json'},
json=payload
)
if not response.ok:
raise Exception(f'Upload failed: {response.text}')
return response.json()
# Usage example
def main():
uploader = FileUploadAPI('YOUR_API_KEY')
# Batch upload local files
file_paths = [
'/path/to/file1.jpg',
'/path/to/file2.png',
'/path/to/document.pdf'
]
print("Starting batch file upload...")
for i, file_path in enumerate(file_paths):
try:
result = uploader.upload_file(
file_path,
'user-uploads',
f'file-{i + 1}-{os.path.basename(file_path)}'
)
print(f"File {i + 1} uploaded successfully: {result['data']['fileUrl']}")
except Exception as e:
print(f"File {i + 1} upload failed: {e}")
# Batch upload from URLs
urls = [
'https://example.com/image1.jpg',
'https://example.com/image2.png'
]
print("\nStarting batch URL upload...")
for i, url in enumerate(urls):
try:
result = uploader.upload_from_url(
url,
'downloads',
f'download-{i + 1}.jpg'
)
print(f"URL {i + 1} uploaded successfully: {result['data']['fileUrl']}")
except Exception as e:
print(f"URL {i + 1} upload failed: {e}")
if __name__ == '__main__':
main()
```
## Error Handling
Common errors and handling methods:
```javascript theme={null}
// Check if API key is correct
if (response.status === 401) {
console.error('Invalid API key, please check Authorization header');
// Retrieve or update API key
}
```
```javascript theme={null}
// Check request parameters
if (response.status === 400) {
const error = await response.json();
console.error('Request parameter error:', error.msg);
// Check if required parameters are provided
// Check if file format is supported
// Check if URL is accessible
}
```
```javascript theme={null}
// Implement retry mechanism
async function uploadWithRetry(uploadFunction, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await uploadFunction();
} catch (error) {
if (i === maxRetries - 1) throw error;
// Exponential backoff
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
```
## Best Practices
* **Small files** (≤1MB): Recommended to use Base64 upload
* **Medium files** (1MB-10MB): Recommended to use file stream upload
* **Large files** (>10MB): Must use file stream upload
* **Remote files**: Use URL upload, note 100MB limit
* **Random generation**: If no fileName is provided, the system will automatically generate a random filename
* **File overwriting**: If you provide a fileName that already exists, the old file will be overwritten
* **Cache behavior**: Due to caching mechanisms, file overwrites may not be immediately visible
* **Best practice**: Use unique filenames with timestamps to avoid conflicts (e.g., `image-2024-01-15-10-30.jpg`)
* Implement concurrency control to avoid uploading too many files simultaneously
* Consider chunked upload strategies for large files
* Use appropriate retry mechanisms to handle network issues
* Monitor upload progress and provide user feedback
* Keep API keys secure and rotate them regularly
* Validate file types and sizes
* Consider encrypted transmission for sensitive files
* Download important files promptly to avoid 3-day deletion
* Implement comprehensive error handling logic
* Log uploads for troubleshooting
* Provide user-friendly error messages
* Offer retry options for failed uploads
## File Storage Information
**Important Notice**: All uploaded files are temporary and will be **automatically deleted after 3 days**.
* Files are immediately accessible and downloadable after upload
* File URLs remain valid for 3 days
* The system provides an `expiresAt` field in the response indicating expiration time
* It's recommended to download or migrate important files before expiration
* Use the `downloadUrl` field to get direct download links
## Status Codes
Request processed successfully, file upload completed
Request parameters are incorrect or missing required parameters
Authentication credentials are missing or invalid
Request method is not supported, please check HTTP method
An unexpected error occurred while processing the request, please retry or contact support
## Next Steps
Learn how to upload files from remote URLs
Master efficient file stream upload methods
Understand Base64 encoded file uploads
## Support
Need help? Our technical support team is here to assist you.
* **Email**: [support@sunoapi.org](mailto:support@sunoapi.org)
* **Documentation**: [docs.sunoapi.org](https://docs.sunoapi.org)
* **API Status**: Check our status page for real-time API health
***
Ready to start uploading files? [Get your API key](https://sunoapi.org/api-key) and begin using the file upload service immediately!
# Base64 File Upload
Source: https://docs.sunoapi.org/file-upload-api/upload-file-base-64
file-upload-api/file-upload-api.json POST /api/file-base64-upload
Upload temporary files via Base64 encoded data. Note: Uploaded files are temporary and automatically deleted after 3 days.
Upload temporary files via Base64 encoded data. Note: Uploaded files are temporary and automatically deleted after 3 days.
### Features
* Supports Base64 encoded data and data URL format
* Automatic MIME type recognition and file extension inference
* Support for custom file names or auto-generation
* Returns complete file information and download links
* API Key authentication protection
* Uploaded files are temporary and automatically deleted after 3 days
### Supported Formats
* **Pure Base64 String**: `iVBORw0KGgoAAAANSUhEUgAA...`
* **Data URL Format**: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...`
### Usage Recommendations
* Recommended for small files like images
* For large files (>10MB), use the file stream upload API
* Base64 encoding increases data transmission by approximately 33%
# File Stream Upload
Source: https://docs.sunoapi.org/file-upload-api/upload-file-stream
file-upload-api/file-upload-api.json POST /api/file-stream-upload
Upload temporary files via multipart/form-data format. Note: Uploaded files are temporary and automatically deleted after 3 days.
### Features
* Supports binary stream upload for various file types
* Suitable for large file uploads with high transmission efficiency
* Automatic MIME type recognition
* Support for custom file names or using original file names
* Returns complete file information and download links
* API Key authentication protection
* Uploaded files are temporary and automatically deleted after 3 days
### Usage Recommendations
* Recommended for large files (>10MB)
* Supports various formats: images, videos, documents, etc.
* Transmission efficiency is approximately 33% higher than Base64 format
### Example Command
```bash theme={null}
curl -X POST https://sunoapiorg.redpandaai.co/api/file-stream-upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@/path/to/your-file.jpg" \
-F "uploadPath=images/user-uploads" \
-F "fileName=custom-name.jpg"
```
# URL File Upload
Source: https://docs.sunoapi.org/file-upload-api/upload-file-url
file-upload-api/file-upload-api.json POST /api/file-url-upload
Download files from URLs and upload them as temporary files. Note: Uploaded files are temporary and automatically deleted after 3 days.
### Features
* Supports HTTP and HTTPS file links
* Automatically downloads remote files and uploads them
* Automatically extracts file names from URLs or uses custom file names
* Automatic MIME type recognition
* Returns complete file information and download links
* API Key authentication protection
* Uploaded files are temporary and automatically deleted after 3 days
### Supported Protocols
* **HTTP**: `http://example.com/file.jpg`
* **HTTPS**: `https://example.com/file.jpg`
### Use Cases
* Migrating files from other services
* Batch downloading and storing web resources
* Backing up remote files
* Caching external resources
### Important Notes
* Ensure the provided URL is publicly accessible
* Download timeout is 30 seconds
* Recommended file size limit is 100MB
# Suno API Documentation
Source: https://docs.sunoapi.org/index
Complete Suno API documentation - Your gateway to affordable and stable AI music API services
# Welcome to Suno API Documentation
This documentation provides comprehensive guides and references for integrating [Suno API](https://sunoapi.org/), a platform offering affordable and stable AI music API services that seamlessly integrate into your projects.
## About Suno API
Suno API delivers advanced AI music capabilities through easy-to-integrate APIs, including music generation, lyrics creation, audio processing, and video production. Our platform is designed for developers and businesses who need:
* **99.9% Uptime** - Reliable and stable API performance
* **Affordable Pricing** - Transparent, usage-based pricing system
* **20-Second Streaming Output** - Fast delivery with streaming response
* **High Concurrency** - Scalable solutions that grow with your needs
* **24/7 Support** - Professional technical assistance
* **Watermark-Free** - Commercial-ready music generation
## Quick Start Guides
Get started quickly with our comprehensive API quick start guides:
### 🎵 Music Generation APIs
Create high-quality music from text descriptions using advanced AI models with support for various styles and genres.
Extend existing music tracks with AI-powered continuation, maintaining musical coherence and style.
Transform existing audio with new styles and arrangements using AI music processing.
Upload your own audio files and extend them with AI-generated content.
Generate vocal tracks for instrumental music using advanced AI models.
Create instrumental accompaniment for vocal tracks with AI-powered arrangements.
Reinterpret existing music in different styles and arrangements using AI technology.
### ✍️ Lyrics Creation APIs
Create AI-powered lyrics for your songs with customizable themes and styles.
Retrieve lyrics with precise timestamps for synchronization with audio tracks.
### 🔊 Audio Processing APIs
Extract vocals and instrumental tracks separately using advanced AI audio separation.
Convert generated music to high-quality WAV format for professional use.
Enhance and refine music styles with AI-powered audio processing.
### 🎬 Music Video APIs
Generate visual music videos from audio tracks using AI video generation technology.
### 🛠️ Utility APIs
Monitor and retrieve detailed information about your music generation tasks.
Check your account credit balance and usage statistics.
Track the status and details of your lyrics generation requests.
Monitor WAV format conversion tasks and download status.
Check the progress of vocal separation tasks and access separated audio files.
Track music video generation progress and retrieve download links.
Monitor the status of music cover tasks and get cover results.
## Documentation Features
* **Interactive Examples** - Test APIs directly in our documentation
* **Code Samples** - Ready-to-use examples in multiple programming languages
* **Comprehensive Guides** - Step-by-step integration instructions
* **API Reference** - Complete parameter documentation and response schemas
* **Best Practices** - Optimization tips and common use cases
* **Callback Documentation** - Webhook integration guides for all endpoints
## Key Features
### 🚀 Latest AI Music Models
We provide APIs for the latest AI music models, including Suno V5\_5, V5, V4.5 Plus, V4.5 All, V4.5, and V4, offering high-quality music generation. Supports creation of both vocal and instrumental tracks, music extension, and multi-format downloads.
### 💎 Watermark-Free Commercial Use
All music generated through our API is watermark-free, making it immediately suitable for commercial projects. This removes the need for additional fees, enabling creators and developers to effortlessly integrate high-quality tracks into their workflows.
### ⚡ 20-Second Streaming Output
We ensure rapid delivery with streaming output, enabling developers to integrate AI-generated music seamlessly into their workflows without delays. This feature supports real-time applications and live content creation.
### 🏗️ High-Concurrency Architecture
Our API is built to handle multiple simultaneous requests, ensuring reliable performance even under heavy traffic. This makes it ideal for large-scale applications and high-demand platforms.
### 💰 Transparent and Affordable Pricing
We offer cost-effective and transparent pricing plans, making it accessible to creators and enterprises. Our transparent, usage-based model ensures predictable costs.
### 🔧 Comprehensive Developer Support
We streamline integration with detailed, developer-friendly API documentation, ensuring a hassle-free implementation process. Supported by an experienced technical team.
## Getting Started
1. **Sign Up** - Create your free account at [Suno API](https://sunoapi.org/)
2. **Get API Key** - Obtain your authentication credentials from the [API Key Management Page](https://sunoapi.org/api-key)
3. **Choose Your API** - Select from our comprehensive API collection
4. **Follow Quick Start** - Use our [Quick Start Guide](/suno-api/quickstart) for rapid integration
5. **Test & Deploy** - Verify your integration and go live
## AI Model Versions
Choose the right model for your needs:
### V4 - Improved Vocals
Enhanced vocal quality and refined audio processing, up to 4 minutes. Ideal choice when vocal clarity is paramount.
### V4\_5 - Smart Prompts
Excellent prompt understanding with faster generation speeds, up to 8 minutes. Our advanced model for complex music requests.
### V4\_5PLUS - Richer Tones
Most advanced model with enhanced tonal variation and new creative approaches, up to 8 minutes. Best choice for highest quality and longest tracks.
### V4\_5ALL - Better Song Structure
V4.5-all is better song structure, max 8 min. Perfect for well-structured musical pieces.
### V5 - Latest Model
Cutting-edge model with enhanced quality and capabilities. Our newest offering for advanced music generation.
### V5\_5 - Voice-Customized Model
Unleash Your Voice: Custom Models Tailored to Your Unique Taste.
## Use Cases
### 🎮 Game Developers
Generate dynamic background music, sound effects, and adaptive audio for gaming experiences using our music generation and extension APIs.
### 🎬 Content Creators
Create royalty-free music for videos, podcasts, and social media content with our watermark-free output, enjoying unlimited commercial use rights.
### 🏢 Businesses
Integrate AI music generation into apps, websites, and services using our high-concurrency API to enhance user experiences.
### 🎭 Music Producers
Prototype songs, generate ideas, and create full compositions with professional-quality output. Use vocal separation for remixing and audio processing.
### 🎤 Karaoke & Entertainment
Leverage timestamped lyrics and vocal separation features for karaoke applications and interactive music experiences.
## Support & Community
* **24/7 Support** - Contact our technical team anytime
* **Email Support** - [support@sunoapi.org](mailto:support@sunoapi.org)
* **Documentation Updates** - Regular improvements and new features
* **API Status** - Monitor real-time service status
* **Developer Resources** - Comprehensive guides and best practices
## Callback Integration
All major endpoints support webhook callbacks for real-time notifications:
* [Music Generation Callbacks](/suno-api/generate-music-callbacks)
* [Lyrics Generation Callbacks](/suno-api/generate-lyrics-callbacks)
* [Music Extension Callbacks](/suno-api/extend-music-callbacks)
* [Audio Processing Callbacks](/suno-api/separate-vocals-from-music-callbacks)
* [Music Video Callbacks](/suno-api/create-music-video-callbacks)
* [WAV Conversion Callbacks](/suno-api/convert-to-wav-format-callbacks)
* [Cover Callbacks](/suno-api/cover-suno-callbacks)
* [Upload and Cover Callbacks](/suno-api/upload-and-cover-audio-callbacks)
* [Upload and Extend Callbacks](/suno-api/upload-and-extend-audio-callbacks)
* [Add Vocals Callbacks](/suno-api/add-vocals-callbacks)
* [Add Instrumental Callbacks](/suno-api/add-instrumental-callbacks)
## API Base URL
All API requests should be sent to:
```
https://api.sunoapi.org
```
## Authentication
All API requests require authentication using a Bearer token:
```http theme={null}
Authorization: Bearer YOUR_API_KEY
```
Obtain your API key from the [API Key Management Page](https://sunoapi.org/api-key).
***
Ready to get started? Choose an API above and follow the quick start guide to begin integrating powerful AI music capabilities into your projects. Visit [Suno API](https://sunoapi.org/) to create your account and start generating amazing music today!
# Add Instrumental
Source: https://docs.sunoapi.org/suno-api/add-instrumental
suno-api/suno-api.json POST /api/v1/generate/add-instrumental
This endpoint generates a musical accompaniment tailored to an uploaded audio file — typically a vocal stem or melody track. It helps users instantly flesh out their vocal ideas with high-quality backing music, all without needing a producer.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### **Key Capabilities**
* Accepts uploadUrl of an existing audio file (usually vocals or stems).
* Supports fine-grained customization via parameters such as:
* tags and negativeTags (musical style controls)
* styleWeight, audioWeight, weirdnessConstraint (stylistic & creative blending)
* vocalGender, title, callBackUrl for metadata & workflow control .
* Returns a taskId for tracking, and results are retained for 14 days. Callback workflow includes three stages: text, first, and complete .
### **Typical Use Cases**
* Singers or melody writers who want instant fuller arrangements around their vocal inputs.
* Applications like karaoke platforms, demo-generation tools, or co-creation interfaces that allow users to experiment with accompaniment styles easily.
### Parameter Details
* **Required fields**: `uploadUrl`, `title`, `negativeTags`, `tags`, `callBackUrl`
* **Upload URL**: Must be a valid, publicly accessible audio file URL
* **Title**: Used as the title for the generated instrumental track
* **Tags**: Describe the desired style, mood, and instruments for the instrumental track
* **Negative Tags**: Music styles or traits to exclude from the generated instrumental
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Preferred vocal gender for any vocal elements. Allowed values: `m` (male), `f` (female)
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* model (string): Model version used for generation. Current values: `V6` (default), `V6_WILD`, `V6_MINI`. Deprecated: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`.
### Developer Notes
* Callback process has three stages: `text` (text generation), `first` (first track complete), `complete` (all tracks complete)
* In some cases, `text` and `first` stages may be skipped, directly returning `complete`
* See [Add Instrumental Callbacks](./add-instrumental-callbacks) for detailed callback format
* Monitor task progress using [Get Music Generation Details](./get-music-generation-details)
# Add Instrumental Callbacks
Source: https://docs.sunoapi.org/suno-api/add-instrumental-callbacks
When instrumental generation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Add Instrumental API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Instrumental generation task completed successfully
* Instrumental generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Instrumental] Relaxing piano melody",
"model_name": "chirp-v3-5",
"title": "Relaxing Piano Instrumental",
"tags": "relaxing, piano, instrumental",
"createTime": "2025-01-01 00:00:00",
"duration": 198.44
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Instrumental generation failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------ |
| 200 | Success - Instrumental generation completed |
| 400 | Bad Request - Parameter error, content violation, etc. |
| 451 | Download Failed - Unable to download related files |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First track completed
* `complete`: All tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Instrumental generation result information, returned on success
Audio unique identifier (audioId)
Generated instrumental audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming instrumental audio URL
Original streaming instrumental audio URL
Cover image URL
Original cover image URL
Generation prompt describing the instrumental
Model name used for generation
Instrumental track title
Instrumental track tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/add-instrumental-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received instrumental generation callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Instrumental generation completed');
const instrumentalData = data.data || [];
console.log(`Generated ${instrumentalData.length} instrumental tracks:`);
instrumentalData.forEach((instrumental, index) => {
console.log(`Instrumental ${index + 1}:`);
console.log(` Title: ${instrumental.title}`);
console.log(` Duration: ${instrumental.duration} seconds`);
console.log(` Tags: ${instrumental.tags}`);
console.log(` Audio URL: ${instrumental.audio_url}`);
console.log(` Cover URL: ${instrumental.image_url}`);
});
// Process generated instrumental
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Instrumental generation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('File download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/add-instrumental-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
instrumental_data = callback_data.get('data', [])
print(f"Received instrumental generation callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Instrumental generation completed")
print(f"Generated {len(instrumental_data)} instrumental tracks:")
for i, instrumental in enumerate(instrumental_data):
print(f"Instrumental {i + 1}:")
print(f" Title: {instrumental.get('title')}")
print(f" Duration: {instrumental.get('duration')} seconds")
print(f" Tags: {instrumental.get('tags')}")
print(f" Audio URL: {instrumental.get('audio_url')}")
print(f" Cover URL: {instrumental.get('image_url')}")
# Download audio file example
try:
audio_url = instrumental.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"generated_instrumental_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Instrumental saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Instrumental generation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("File download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$instrumental) {
error_log("Instrumental " . ($index + 1) . ":");
error_log(" Title: " . ($instrumental['title'] ?? ''));
error_log(" Duration: " . ($instrumental['duration'] ?? 0) . " seconds");
error_log(" Tags: " . ($instrumental['tags'] ?? ''));
error_log(" Audio URL: " . ($instrumental['audio_url'] ?? ''));
error_log(" Cover URL: " . ($instrumental['image_url'] ?? ''));
// Download audio file example
try {
$audioUrl = $instrumental['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "generated_instrumental_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Instrumental saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Instrumental generation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("File download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Add Vocals
Source: https://docs.sunoapi.org/suno-api/add-vocals
suno-api/suno-api.json POST /api/v1/generate/add-vocals
This endpoint layers AI-generated vocals on top of an existing instrumental. Given a prompt (e.g., lyrical concept or musical mood) and optional audio, it produces vocal output harmonized with the provided track.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### **Key Capabilities**
* Accepts an existing instrumental via uploadUrl, with optional prompt-based stylistic input.
* Supports control parameters including:
* prompt, style, tags, negativeTags (define lyrical content and vocal style)
* vocalGender, styleWeight, weirdnessConstraint, audioWeight, callBackUrl .
* Returns a taskId, supports the same 14-day retention and three-stage callback model as the instrumental endpoint .
### **Typical Use Cases**
* Music platforms or tools enabling topline creation and rapid prototyping of lyrical ideas.
* Collaborative songwriting or co-creation workflows, where lyrics or vocal styles are iteratively tested over instrumental drafts.
### Parameter Details
* **Required fields**: `uploadUrl`, `callBackUrl`, `prompt`, `title`, `negativeTags`, `style`
* **Upload URL**: Must be a valid, publicly accessible audio file URL
* **Style**: Describes the overall genre and vocal approach (Jazz, Classical, Electronic, Pop)
* **Negative Tags**: Music styles or vocal traits to exclude from generation
* **Title**: Used as the title for the generated vocal track
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Preferred vocal gender. Allowed values: `m` (male), `f` (female)
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* model (string): Model version used for generation. Current values: `V6` (default), `V6_WILD`, `V6_MINI`. Deprecated: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`.
### Developer Notes
* Callback process has three stages: `text` (text generation), `first` (first track complete), `complete` (all tracks complete)
* In some cases, `text` and `first` stages may be skipped, directly returning `complete`
* See [Add Vocals Callbacks](./add-vocals-callbacks) for detailed callback format
* Monitor task progress using [Get Music Generation Details](./get-music-generation-details)
# Add Vocals Callbacks
Source: https://docs.sunoapi.org/suno-api/add-vocals-callbacks
When vocal generation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Add Vocals API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Vocal generation task completed successfully
* Vocal generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Calm and relaxing melodies with soothing vocals",
"model_name": "chirp-v3-5",
"title": "Relaxing Piano with Vocals",
"tags": "relaxing, piano, vocals, jazz",
"createTime": "2025-01-01 00:00:00",
"duration": 198.44
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Vocal generation failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------ |
| 200 | Success - Vocal generation completed |
| 400 | Bad Request - Parameter error, content violation, etc. |
| 451 | Download Failed - Unable to download related files |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First track completed
* `complete`: All tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Vocal generation result information, returned on success
Audio unique identifier (audioId)
Generated vocal audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming vocal audio URL
Original streaming vocal audio URL
Cover image URL
Original cover image URL
Generation prompt/lyrics describing the vocals
Model name used for generation
Vocal track title
Vocal track tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/add-vocals-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received vocal generation callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Vocal generation completed');
const vocalData = data.data || [];
console.log(`Generated ${vocalData.length} vocal tracks:`);
vocalData.forEach((vocal, index) => {
console.log(`Vocal ${index + 1}:`);
console.log(` Title: ${vocal.title}`);
console.log(` Duration: ${vocal.duration} seconds`);
console.log(` Tags: ${vocal.tags}`);
console.log(` Audio URL: ${vocal.audio_url}`);
console.log(` Cover URL: ${vocal.image_url}`);
});
// Process generated vocals
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Vocal generation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('File download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/add-vocals-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
vocal_data = callback_data.get('data', [])
print(f"Received vocal generation callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Vocal generation completed")
print(f"Generated {len(vocal_data)} vocal tracks:")
for i, vocal in enumerate(vocal_data):
print(f"Vocal {i + 1}:")
print(f" Title: {vocal.get('title')}")
print(f" Duration: {vocal.get('duration')} seconds")
print(f" Tags: {vocal.get('tags')}")
print(f" Audio URL: {vocal.get('audio_url')}")
print(f" Cover URL: {vocal.get('image_url')}")
# Download audio file example
try:
audio_url = vocal.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"generated_vocal_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Vocal saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Vocal generation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("File download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$vocal) {
error_log("Vocal " . ($index + 1) . ":");
error_log(" Title: " . ($vocal['title'] ?? ''));
error_log(" Duration: " . ($vocal['duration'] ?? 0) . " seconds");
error_log(" Tags: " . ($vocal['tags'] ?? ''));
error_log(" Audio URL: " . ($vocal['audio_url'] ?? ''));
error_log(" Cover URL: " . ($vocal['image_url'] ?? ''));
// Download audio file example
try {
$audioUrl = $vocal['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "generated_vocal_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Vocal saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Vocal generation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("File download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Boost Music Style
Source: https://docs.sunoapi.org/suno-api/boost-music-style
suno-api/suno-api.json POST /api/v1/style/generate
This is an exclusive capability of V4\_5. The style functionality of V4\_5 has been significantly enhanced, as stated on the official website:
> One of the many advantages of the new 4.5 model is its ability to accommodate more detailed style instructions. In previous models, it was necessary to prioritize specific genre and style details, but now instructions can incorporate a more conversational prompt.
>
> Previously, optimal results might have been achieved with a prompt like: 'deep house, emotional, melodic.'
>
> Now, you can provide a prompt such as: 'Create a melodic, emotional deep house song featuring organic textures and hypnotic rhythms. Begin with soft ambient layers, natural sounds, and a deep, steady groove. Gradually build with flowing melodic synths, warm basslines, and intricate, subtle percussion.'
The 'Boost Your Style' feature will significantly enhance users' ability to describe and control style. It is recommended for use.
### Parameter Description
* content: Required, string type. Style description is required.
# Convert to WAV Format
Source: https://docs.sunoapi.org/suno-api/convert-to-wav-format
suno-api/suno-api.json POST /api/v1/wav/generate
Convert existing music tracks to high-quality WAV format.
### Usage Guide
* Provide either taskId or audioId to identify the source track
* WAV format is ideal for professional audio editing and production
* The conversion preserves full audio quality
### Developer Notes
1. Generated WAV files are retained for 15 days
2. WAV files are significantly larger than MP3 files
3. This format is recommended for further audio processing or professional use
4. Callback provides a single download URL when conversion is complete
# WAV Format Conversion Callbacks
Source: https://docs.sunoapi.org/suno-api/convert-to-wav-format-callbacks
When WAV format conversion tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the WAV Format Conversion API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* WAV format conversion task completed successfully
* WAV format conversion task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "success",
"data": {
"audioWavUrl": "https://example.com/s/04e6****e727.wav",
"task_id": "988e****c8d3"
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "WAV format conversion failed",
"data": {
"audioWavUrl": null,
"task_id": "988e****c8d3"
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------- |
| 200 | Success - WAV format conversion completed |
| 400 | Bad Request - Parameter error, unsupported source audio file format, etc. |
| 451 | Download Failed - Unable to download source audio file |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Task ID, consistent with the taskId returned when you submitted the task
Converted WAV audio file download URL, returned on success
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/wav-conversion-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received WAV format conversion callback:', {
taskId: data.task_id,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('WAV format conversion completed');
console.log(`WAV file URL: ${data.audioWavUrl}`);
// Download WAV file
if (data.audioWavUrl) {
const https = require('https');
const fs = require('fs');
const filename = `wav_${data.task_id}.wav`;
const file = fs.createWriteStream(filename);
https.get(data.audioWavUrl, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
console.log(`WAV file saved as ${filename}`);
});
}).on('error', (err) => {
console.error('WAV file download failed:', err.message);
});
}
} else {
// Task failed
console.log('WAV format conversion failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or unsupported source file format');
} else if (code === 451) {
console.log('Source audio file download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/wav-conversion-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
audioWavUrl = callback_data.get('audioWavUrl')
print(f"Received WAV format conversion callback: {task_id}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("WAV format conversion completed")
print(f"WAV file URL: {audioWavUrl}")
# Download WAV file example
if audioWavUrl:
try:
response = requests.get(audioWavUrl)
if response.status_code == 200:
filename = f"wav_{task_id}.wav"
with open(filename, "wb") as f:
f.write(response.content)
print(f"WAV file saved as {filename}")
except Exception as e:
print(f"WAV file download failed: {e}")
else:
# Task failed
print(f"WAV format conversion failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or unsupported source file format")
elif code == 451:
print("Source audio file download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
getMessage());
}
}
} else {
// Task failed
error_log("WAV format conversion failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or unsupported source file format");
} elseif ($code === 451) {
error_log("Source audio file download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **File Processing**: WAV file download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated WAV file URLs may have time limits, recommend downloading and saving promptly
* WAV files are typically larger than MP3 files, pay attention to storage space and download time
* Ensure sufficient disk space to save WAV files
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that WAV file URLs are accessible
* Check file download permissions and network connections
* Verify file save paths and permissions
* Note WAV file size, ensure sufficient storage space
* Confirm source audio file format is supported
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get WAV conversion details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Generate Music Cover
Source: https://docs.sunoapi.org/suno-api/cover-suno
suno-api/suno-api.json POST /api/v1/suno/cover/generate
Create personalized cover images for generated music.
### Usage Guide
* Use this interface to create personalized cover images for generated music
* Requires the taskId of the original music task
* Each music task can only generate a Cover once; duplicate requests will return the existing taskId
* Results will be notified through the callback URL upon completion
### Parameter Details
* `taskId` identifies the unique identifier of the original music generation task
* `callBackUrl` receives callback address for completion notifications
### Developer Notes
* Cover image file URLs will be retained for 14 days
* If a Cover has already been generated for this music task, a 400 status code and existing taskId will be returned
* It's recommended to call this interface after music generation is complete
* Usually generates 2 different style images for selection
# Music Cover Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/cover-suno-callbacks
When music cover generation is complete, the system will call this callback to notify results.
When you submit a cover generation task to the Suno API, you can use the `callBackUrl` parameter to set the callback URL. When the task is complete, the system will automatically push results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will actively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Cover generation task completed successfully
* Cover generation task failed
* Error occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is complete, the system will send a POST request to your `callBackUrl`:
```json Success Callback theme={null}
{
"code": 200,
"data": {
"images": [
"https://tempfile.aiquickdraw.com/s/1753958521_6c1b3015141849d1a9bf17b738ce9347.png",
"https://tempfile.aiquickdraw.com/s/1753958524_c153143acc6340908431cf0e90cbce9e.png"
],
"taskId": "21aee3c3c2a01fa5e030b3799fa4dd56"
},
"msg": "success"
}
```
```json Failure Callback theme={null}
{
"code": 501,
"msg": "Cover generation failed",
"data": {
"taskId": "21aee3c3c2a01fa5e030b3799fa4dd56",
"images": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ---------------------------------------------------------------------------------------------------------- |
| 200 | Success - Request processed successfully |
| 400 | Validation error - Request parameters invalid |
| 408 | Rate limited - Timeout |
| 500 | Server error - Unexpected error occurred while processing request |
| 501 | Cover generation failed |
| 531 | Server error - Sorry, generation failed due to an issue. Your credits have been refunded. Please try again |
Status message providing more detailed status description
Task ID, consistent with the taskId returned when you submitted the task
Array of generated cover image URLs, returned on success. Usually contains 2 different style cover images
## Callback Reception Examples
Here are example codes for receiving callbacks in common programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/suno-cover-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received cover generation callback:', {
taskId: data.taskId,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Cover generation completed');
const images = data.images;
if (images && images.length > 0) {
console.log('Generated cover images:');
images.forEach((imageUrl, index) => {
console.log(`Cover ${index + 1}: ${imageUrl}`);
});
// Process cover images
// Can download images, save locally, update database, etc.
downloadImages(images, data.taskId);
}
} else {
// Task failed
console.log('Cover generation failed:', msg);
// Handle failure cases...
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
// Download images function
async function downloadImages(imageUrls, taskId) {
const fs = require('fs');
const path = require('path');
const https = require('https');
// Create directory
const dir = `covers/${taskId}`;
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
for (let i = 0; i < imageUrls.length; i++) {
const url = imageUrls[i];
const filename = path.join(dir, `cover_${i + 1}.png`);
try {
await downloadFile(url, filename);
console.log(`Cover saved: ${filename}`);
} catch (error) {
console.error(`Download failed: ${error.message}`);
}
}
}
function downloadFile(url, filename) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(filename);
https.get(url, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
resolve();
});
}).on('error', (err) => {
fs.unlink(filename, () => {}); // Delete failed file
reject(err);
});
});
}
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
import os
from urllib.parse import urlparse
app = Flask(__name__)
@app.route('/suno-cover-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('taskId')
images = callback_data.get('images')
print(f"Received cover generation callback: {task_id}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Cover generation completed")
if images:
print("Generated cover images:")
for i, image_url in enumerate(images, 1):
print(f"Cover {i}: {image_url}")
# Download cover images
download_images(images, task_id)
else:
# Task failed
print(f"Cover generation failed: {msg}")
# Handle failure cases...
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
def download_images(image_urls, task_id):
"""Download cover images"""
# Create directory
dir_path = f"covers/{task_id}"
os.makedirs(dir_path, exist_ok=True)
for i, url in enumerate(image_urls, 1):
try:
# Get file extension
parsed_url = urlparse(url)
file_ext = os.path.splitext(parsed_url.path)[1] or '.png'
filename = os.path.join(dir_path, f"cover_{i}{file_ext}")
# Download file
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Cover saved: {filename}")
else:
print(f"Download failed {url}: HTTP {response.status_code}")
except Exception as e:
print(f"Download failed {url}: {e}")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```java theme={null}
/**
* @param request Callback request
* @return ResponseEntity
* @author zj
* @description Handle Suno Cover generation callback
* @date 2025/1/15
**/
@PostMapping("/suno-cover-callback")
@Operation(summary = "Suno Cover generation callback", description = "Receive Cover generation completion notification")
public ResponseEntity
```php theme={null}
0) {
error_log("Generated cover images: " . implode(', ', $images));
// Download cover images
downloadCoverImages($taskId, $images);
}
} else {
// Task failed
error_log("Cover generation failed: $msg");
// Handle failure cases...
}
/**
* Download cover images
* @param string $taskId Task ID
* @param array $imageUrls Image URL array
*/
function downloadCoverImages($taskId, $imageUrls) {
// Create directory
$dir = "covers/$taskId";
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
foreach ($imageUrls as $index => $url) {
$filename = $dir . "/cover_" . ($index + 1) . ".png";
try {
$imageContent = file_get_contents($url);
if ($imageContent !== false) {
file_put_contents($filename, $imageContent);
error_log("Cover saved: $filename");
} else {
error_log("Download failed: $url");
}
} catch (Exception $e) {
error_log("Download failed $url: " . $e->getMessage());
}
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure callback URL uses HTTPS protocol for data transmission security
2. **Verify Source**: Verify the legitimacy of request sources in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return 200 status code quickly to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Image Management**: Download and save images promptly, noting URL validity period
7. **Error Retry**: Implement retry mechanism for failed image downloads
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure stability of callback processing logic to avoid callback failures due to exceptions
* Cover image URLs may have validity periods, recommend downloading and saving promptly
* Usually generates 2 different style cover images for selection
* Note handling exceptions for failed image downloads
## Troubleshooting
If you don't receive callback notifications, please check the following:
* Confirm callback URL is accessible from the public internet
* Check firewall settings to ensure inbound requests are not blocked
* Verify domain name resolution is correct
* Ensure server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify interface path and HTTP method are correct
* Confirm received POST request body is in JSON format
* Check if Content-Type is application/json
* Verify JSON parsing is correct
* Confirm image URLs are accessible
* Check image download permissions and network connection
* Verify file save path and permissions
* Note image URL validity period limitations
## Alternative Solutions
If you cannot use the callback mechanism, you can also use polling:
Use the Get Cover Details endpoint to periodically query task status. We recommend querying every 30 seconds.
# Create Music Video
Source: https://docs.sunoapi.org/suno-api/create-music-video
suno-api/suno-api.json POST /api/v1/mp4/generate
Generate an MP4 video with visualizations for a music track.
### Usage Guide
* This endpoint creates a visual representation of your music track as an MP4 video
* Both taskId and audioId are required to identify the specific track
* Optional author and domainName parameters can be used to add branding
### Developer Notes
1. Generated video files are retained for 15 days
2. Videos include visual effects synchronized with the music
3. This feature is ideal for social media sharing, music promotion, or creating visual content
4. Videos maintain the same audio quality as the original track
# Music Video Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/create-music-video-callbacks
When music video generation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Music Video Generation API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Music video generation task completed successfully
* Music video generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "MP4 generated successfully.",
"data": {
"task_id": "taskId_774b9aa0422f",
"video_url": "https://example.com/videos/video_847715e66259.mp4"
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Music video generation failed",
"data": {
"task_id": "taskId_774b9aa0422f",
"video_url": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------------------ |
| 200 | Success - Music video generation completed |
| 400 | Bad Request - Parameter error, unsupported audio file format, etc. |
| 451 | Download Failed - Unable to download source audio file |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Task ID, consistent with the taskId returned when you submitted the task
Generated MP4 video file download URL, returned on success
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/music-video-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received music video generation callback:', {
taskId: data.task_id,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Music video generation completed');
console.log(`Video URL: ${data.video_url}`);
// Download video file
if (data.video_url) {
const https = require('https');
const fs = require('fs');
const filename = `music_video_${data.task_id}.mp4`;
const file = fs.createWriteStream(filename);
https.get(data.video_url, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
console.log(`Video file saved as ${filename}`);
});
}).on('error', (err) => {
console.error('Video file download failed:', err.message);
});
}
} else {
// Task failed
console.log('Music video generation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or unsupported audio file format');
} else if (code === 451) {
console.log('Source audio file download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/music-video-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
video_url = callback_data.get('video_url')
print(f"Received music video generation callback: {task_id}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Music video generation completed")
print(f"Video URL: {video_url}")
# Download video file example
if video_url:
try:
response = requests.get(video_url)
if response.status_code == 200:
filename = f"music_video_{task_id}.mp4"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Video file saved as {filename}")
except Exception as e:
print(f"Video file download failed: {e}")
else:
# Task failed
print(f"Music video generation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or unsupported audio file format")
elif code == 451:
print("Source audio file download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
getMessage());
}
}
} else {
// Task failed
error_log("Music video generation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or unsupported audio file format");
} elseif ($code === 451) {
error_log("Source audio file download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Video Processing**: Video file download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated video file URLs may have time limits, recommend downloading and saving promptly
* MP4 video files are large, pay attention to storage space and download time
* Ensure sufficient disk space to save video files
* Video generation may take longer, please be patient for callback notifications
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that video file URLs are accessible
* Check video download permissions and network connections
* Verify video save paths and permissions
* Note video file size, ensure sufficient storage space
* Confirm source audio file format is supported
* Check network bandwidth is sufficient for downloading large files
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music video details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Extend Music
Source: https://docs.sunoapi.org/suno-api/extend-music
suno-api/suno-api.json POST /api/v1/generate/extend
Extend or modify existing music tracks.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Parameter Usage Guide
* **model** (string, required): `V6`, `V6_WILD`, `V6_MINI`. Deprecated: `V4_5ALL`, `V4`, `V4_5`, `V4_5PLUS`, `V5`, `V5_5`.
* When defaultParamFlag is true (Custom Parameters):
* If `instrumental` is `false` or omitted: `prompt`, `style`, `title`, and `continueAt` are required
* If `instrumental` is `true`: `style`, `title`, and `continueAt` are required; do not provide `prompt` or `vocalGender`
* Character limits by model:
* **V4 (Deprecated)**: `prompt` max 3000, `style` max 200, `title` max 80
* **V4\_5ALL (Deprecated)**: `prompt` max 5000, `style` max 1000, `title` max 80
* **V4\_5, V4\_5PLUS, V5, V5\_5 (Deprecated)**: `prompt` max 5000, `style` max 1000, `title` max 100
* **V6, V6\_WILD & V6\_MINI**: `prompt` max 5000, `style` max 1000, `title` max 100
* When defaultParamFlag is false (Use Default Parameters):
* Only `audioId` is required for the parameter set; **`model`** and **`callBackUrl`** remain required by the API
* `taskId` is optional and can be provided to identify the original generation task
* Other creative parameters use the original audio's values
### Optional parameters
The following fields are optional controls available for this endpoint:
* taskId (string): Unique identifier of the original music generation task that produced the source audio. Can be a taskId returned from Generate Music or a previous Extend Music request.
* instrumental (boolean): Whether to extend the track as instrumental music. Defaults to `false`. When `true`, `prompt` and `vocalGender` must not be provided.
* vocalGender (string): Preferred vocal gender. Allowed values: `m` (male), `f` (female). Must not be provided when `instrumental` is `true`.
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* personaId (string): Persona ID or Suno Voice `voiceId` to apply when using custom parameters. If you use a Voice-generated ID, set `personaModel` to `voice_persona`.
* personaModel (string): Persona type. Use `style_persona` for Generate Persona IDs, or `voice_persona` for Suno Voice IDs.
```json JSON body theme={null}
{
"defaultParamFlag": true,
"instrumental": false,
"audioId": "e231****-****-****-****-****8cadc7dc",
"taskId": "5c79****be8e",
"prompt": "Extend with a mellow bridge and outro",
"style": "Indie Pop",
"title": "Evening Sky (Extended)",
"continueAt": 60,
"model": "V6",
"callBackUrl": "https://example.com/callback",
"vocalGender": "m",
"styleWeight": 0.61,
"weirdnessConstraint": 0.72,
"audioWeight": 0.65
}
```
### Developer Notes
1. Generated files are retained for 15 days
2. Model version must be consistent with the source music
3. This feature is ideal for creating longer compositions by extending existing tracks
# Music Extension Callbacks
Source: https://docs.sunoapi.org/suno-api/extend-music-callbacks
When music extension tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Music Extension API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Music extension task completed successfully
* Music extension task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v3-5",
"title": "Iron Man",
"tags": "electrifying, rock",
"createTime": "2025-01-01 00:00:00",
"duration": 228.28
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Music extension failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------ |
| 200 | Success - Music extension completed |
| 400 | Bad Request - Parameter error, content violation, etc. |
| 451 | Download Failed - Unable to download related files |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First music track completed
* `complete`: All music tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Music extension result information, returned on success
Music unique identifier
Extended audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming audio URL
Original streaming audio URL
Cover image URL
Original cover image URL
Generation prompt/lyrics
Model name used
Music title
Music tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/extend-music-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received music extension callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Music extension completed');
const musicData = data.data || [];
console.log(`Extended ${musicData.length} music tracks:`);
musicData.forEach((music, index) => {
console.log(`Music ${index + 1}:`);
console.log(` Title: ${music.title}`);
console.log(` Duration: ${music.duration} seconds`);
console.log(` Audio URL: ${music.audio_url}`);
console.log(` Cover URL: ${music.image_url}`);
});
// Process extended music
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Music extension failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('File download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/extend-music-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
music_data = callback_data.get('data', [])
print(f"Received music extension callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Music extension completed")
print(f"Extended {len(music_data)} music tracks:")
for i, music in enumerate(music_data):
print(f"Music {i + 1}:")
print(f" Title: {music.get('title')}")
print(f" Duration: {music.get('duration')} seconds")
print(f" Audio URL: {music.get('audio_url')}")
print(f" Cover URL: {music.get('image_url')}")
# Download audio file example
try:
audio_url = music.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"extended_music_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Audio saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Music extension failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("File download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$music) {
error_log("Music " . ($index + 1) . ":");
error_log(" Title: " . ($music['title'] ?? ''));
error_log(" Duration: " . ($music['duration'] ?? 0) . " seconds");
error_log(" Audio URL: " . ($music['audio_url'] ?? ''));
error_log(" Cover URL: " . ($music['image_url'] ?? ''));
// Download audio file example
try {
$audioUrl = $music['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "extended_music_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Audio saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Music extension failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("File download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Generate Lyrics
Source: https://docs.sunoapi.org/suno-api/generate-lyrics
suno-api/suno-api.json POST /api/v1/lyrics
Create lyrics for music using AI models without generating audio tracks.
### Usage Guide
* This endpoint generates only lyrics content based on your prompt
* Multiple lyrics variations will be returned for you to choose from
* Generated lyrics typically include song structure markers (e.g., \[Verse], \[Chorus])
### Developer Notes
1. Generated lyrics are retained for 15 days
2. Callback has only one stage: complete (generation complete)
3. Use this endpoint when you only need lyrics creation without music
4. Results can be used as input for the Generate Music endpoint in custom mode
# Lyrics Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/generate-lyrics-callbacks
When lyrics generation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Lyrics Generation API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Lyrics generation task completed successfully
* Lyrics generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"taskId": "11dc****8b0f",
"data": [
{
"text": "[Verse]\nWalking through the city's darkest night\nWith dreams burning like a blazing fire",
"title": "Iron Man",
"status": "complete",
"errorMessage": ""
},
{
"text": "[Verse]\nWind is calling out my name\nSteel armor shining in the light",
"title": "Iron Man",
"status": "complete",
"errorMessage": ""
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Lyrics generation failed",
"data": {
"callbackType": "error",
"taskId": "11dc****8b0f",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------ |
| 200 | Success - Lyrics generation completed |
| 400 | Bad Request - Parameter error, content violation, etc. |
| 451 | Download Failed - Unable to download related files |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `complete`: Lyrics generation completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Lyrics generation result information, returns multiple lyrics variants on success
Generated lyrics content, including song structure markers (e.g., \[Verse], \[Chorus], etc.)
Lyrics title
Lyrics generation status:
* `complete`: Generation completed
* `failed`: Generation failed
Error message, contains specific error description when status is failed
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/generate-lyrics-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received lyrics generation callback:', {
taskId: data.taskId,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Lyrics generation completed');
const lyricsData = data.data || [];
console.log(`Generated ${lyricsData.length} lyrics variants:`);
lyricsData.forEach((lyrics, index) => {
console.log(`Lyrics variant ${index + 1}:`);
console.log(` Title: ${lyrics.title}`);
console.log(` Status: ${lyrics.status}`);
if (lyrics.status === 'complete') {
console.log(` Lyrics content:\n${lyrics.text}`);
} else {
console.log(` Error message: ${lyrics.errorMessage}`);
}
});
// Process generated lyrics
// Can save to database, files, etc.
} else {
// Task failed
console.log('Lyrics generation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('File download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/generate-lyrics-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('taskId')
callback_type = callback_data.get('callbackType')
lyrics_data = callback_data.get('data', [])
print(f"Received lyrics generation callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Lyrics generation completed")
print(f"Generated {len(lyrics_data)} lyrics variants:")
for i, lyrics in enumerate(lyrics_data):
print(f"Lyrics variant {i + 1}:")
print(f" Title: {lyrics.get('title')}")
print(f" Status: {lyrics.get('status')}")
if lyrics.get('status') == 'complete':
print(f" Lyrics content:\n{lyrics.get('text')}")
# Save lyrics to file example
try:
filename = f"lyrics_{task_id}_{i + 1}.txt"
with open(filename, "w", encoding="utf-8") as f:
f.write(f"Title: {lyrics.get('title')}\n\n")
f.write(lyrics.get('text'))
print(f"Lyrics saved as {filename}")
except Exception as e:
print(f"Lyrics save failed: {e}")
else:
print(f" Error message: {lyrics.get('errorMessage')}")
else:
# Task failed
print(f"Lyrics generation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("File download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$lyrics) {
error_log("Lyrics variant " . ($index + 1) . ":");
error_log(" Title: " . ($lyrics['title'] ?? ''));
error_log(" Status: " . ($lyrics['status'] ?? ''));
if (($lyrics['status'] ?? '') === 'complete') {
error_log(" Lyrics content:\n" . ($lyrics['text'] ?? ''));
// Save lyrics to file example
try {
$filename = "lyrics_{$taskId}_" . ($index + 1) . ".txt";
$content = "Title: " . ($lyrics['title'] ?? '') . "\n\n" . ($lyrics['text'] ?? '');
file_put_contents($filename, $content);
error_log("Lyrics saved as $filename");
} catch (Exception $e) {
error_log("Lyrics save failed: " . $e->getMessage());
}
} else {
error_log(" Error message: " . ($lyrics['errorMessage'] ?? ''));
}
}
} else {
// Task failed
error_log("Lyrics generation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("File download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Lyrics Storage**: Lyrics content should be saved to database or file system promptly
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Pay attention to content policy compliance to avoid generation failures due to policy violations
* Lyrics content may contain special characters, pay attention to encoding handling
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Note that lyrics content may contain line breaks and special characters
* Ensure text encoding is handled correctly (recommend using UTF-8)
* Verify lyrics save paths and permissions
* Note whether lyrics content complies with content policies
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get lyrics generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Generate Mashup
Source: https://docs.sunoapi.org/suno-api/generate-mashup
suno-api/suno-api.json POST /api/v1/generate/mashup
Mix two audio files to generate a new mashup work using AI models.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Usage Guide
* This endpoint creates mashup music from up to 2 uploaded audio files
* Combines elements from multiple tracks into a cohesive new composition
* You can control detail level with custom mode and instrumental settings
### Parameter Details
* `uploadUrlList` is required and must contain exactly 2 audio file URLs
* **model** (string, required): `V6`, `V6_WILD`, `V6_MINI`. Deprecated: `V4`, `V4_5`, `V4_5PLUS`, `V4_5ALL`, `V5`, `V5_5`.
* In Custom Mode (`customMode: true`):
* Character limits vary by model:
* **V4, V4\_5, V4\_5PLUS, V4\_5ALL, V5 & V5\_5 (Deprecated)**: `prompt` 3000–5000 characters and `style` 200–1000 characters according to the legacy model.
* **V6, V6\_WILD & V6\_MINI**: `prompt` 5000 characters, `style` 1000 characters
* `title` length limit: 80 characters (all models)
* In Non-custom Mode (`customMode: false`):
* `prompt` length limit: 500 characters
* `instrumental`: whether to generate instrumental music
* Other parameters should be left empty
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Preferred vocal gender. Allowed values: `m` (male), `f` (female)
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
```json JSON body theme={null}
{
"uploadUrlList": [
"https://example.com/audio1.mp3",
"https://example.com/audio2.mp3"
],
"customMode": true,
"prompt": "A dynamic mashup blending electronic and rock elements",
"style": "Electronic Dance Music",
"title": "Mashup Work",
"model": "V6",
"callBackUrl": "https://example.com/callback",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.72,
"audioWeight": 0.65
}
```
### Developer Notes
* Recommendation for new users: Start with `customMode: false` for simpler usage
* Generated files are retained for 14 days
* Callback process has three stages: `text` (text generation), `first` (first track complete), `complete` (all tracks complete)
* The two audio files in `uploadUrlList` must be valid and accessible URLs
* Audio files should be in supported formats (MP3, WAV, etc.)
# Generate MIDI from Audio
Source: https://docs.sunoapi.org/suno-api/generate-midi
suno-api/suno-api.json POST /api/v1/midi/generate
Convert separated audio tracks into MIDI format with detailed note information for each instrument.
### Usage Guide
* Convert separated audio tracks into structured MIDI data containing pitch, timing, and velocity information
* Requires a completed vocal separation task ID (from the Vocal Removal API)
* Generates MIDI note data for multiple detected instruments including drums, bass, guitar, keyboards, and more
* Ideal for music transcription, notation, remixing, or educational analysis
* Best results on clean, well-separated audio tracks with clear instrument parts
### Prerequisites
You must first use the [Vocal & Instrument Stem Separation](/suno-api/separate-vocals-from-music) API to separate your audio before generating MIDI.
### Parameter Reference
| Name | Type | Description |
| :------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `taskId` | string | **Required.** Task ID from a completed vocal separation |
| `callBackUrl` | string | **Required.** URL to receive MIDI generation completion notifications |
| `audioId` | string | **Optional.** Specifies which separated audio track to generate MIDI from. This audioId can be obtained from the `originData` array in the [Get Vocal Separation Details](/suno-api/get-vocal-separation-details) endpoint response. Each item in `originData` contains an `id` field that can be used here. If not provided, MIDI will be generated from all separated tracks. |
### Developer Notes
* The callback will contain detailed note data for each detected instrument
* Each note includes: `pitch` (MIDI note number), `start` (seconds), `end` (seconds), `velocity` (0-1)
* Not all instruments may be detected - depends on audio content
* **Billing:** Check current per-call credit costs at [**https://sunoapi.org/dashboard**](https://sunoapi.org/dashboard)
# MIDI Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/generate-midi-callbacks
System will call this callback when MIDI generation from separated audio is complete.
When you submit a MIDI generation task to the Suno API, you can use the `callBackUrl` parameter to set a callback URL. The system will automatically push the results to your specified address when the task is completed.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* MIDI generation task completed successfully
* MIDI generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl`:
```json Success Callback theme={null}
{
"task_id": "5c79****be8e",
"code": 200,
"msg": "success",
"data": {
"state": "complete",
"instruments": [
{
"name": "Drums",
"notes": [
{
"pitch": 73,
"start": "0.036458333333333336",
"end": "0.18229166666666666",
"velocity": 1
},
{
"pitch": 61,
"start": 0.046875,
"end": "0.19270833333333334",
"velocity": 1
},
{
"pitch": 73,
"start": 0.1875,
"end": "0.4895833333333333",
"velocity": 1
}
]
},
{
"name": "Electric Bass (finger)",
"notes": [
{
"pitch": 44,
"start": 7.6875,
"end": "7.911458333333333",
"velocity": 1
},
{
"pitch": 56,
"start": 7.6875,
"end": "7.911458333333333",
"velocity": 1
},
{
"pitch": 51,
"start": 7.6875,
"end": "7.911458333333333",
"velocity": 1
}
]
}
]
}
}
```
```json Failure Callback theme={null}
{
"task_id": "5c79****be8e",
"code": 500,
"msg": "MIDI generation failed",
"data": null
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ---------------------------------------------------- |
| 200 | Success - MIDI generation completed successfully |
| 500 | Internal Error - Please try again or contact support |
Status message providing detailed status description
Task ID, consistent with the task\_id returned when you submitted the task
MIDI generation result information, returned on success
## Success Response Fields
Processing state. Value: `complete` when successful
Array of detected instruments with their MIDI note data
Instrument name (e.g., "Drums", "Electric Bass (finger)", "Acoustic Grand Piano")
Array of MIDI notes for this instrument
MIDI note number (0-127). Middle C = 60. [MIDI note reference](https://inspiredacoustics.com/en/MIDI_note_numbers_and_center_frequencies)
Note start time in seconds from beginning of audio
Note end time in seconds from beginning of audio
Note velocity/intensity (0-1 range). 1 = maximum velocity
## Callback Reception Examples
Below are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/suno-midi-callback', (req, res) => {
const { code, msg, task_id, data } = req.body;
console.log('Received MIDI generation callback:', {
taskId: task_id,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('MIDI generation completed');
if (data && data.instruments) {
console.log(`Detected ${data.instruments.length} instruments`);
data.instruments.forEach(instrument => {
console.log(`\nInstrument: ${instrument.name}`);
console.log(` Note count: ${instrument.notes.length}`);
// Process each note
instrument.notes.forEach((note, idx) => {
if (idx < 3) { // Show first 3 notes as example
console.log(` Note ${idx + 1}: Pitch ${note.pitch}, ` +
`Start ${note.start}s, End ${note.end}s, ` +
`Velocity ${note.velocity}`);
}
});
});
// Save MIDI data to database or file
// processMidiData(task_id, data);
}
} else {
// Task failed
console.log('MIDI generation failed:', msg);
// Handle failure scenarios...
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/suno-midi-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
task_id = data.get('task_id')
callback_data = data.get('data', {})
print(f"Received MIDI generation callback: {task_id}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("MIDI generation completed")
if callback_data and 'instruments' in callback_data:
instruments = callback_data['instruments']
print(f"Detected {len(instruments)} instruments")
for instrument in instruments:
name = instrument.get('name')
notes = instrument.get('notes', [])
print(f"\nInstrument: {name}")
print(f" Note count: {len(notes)}")
# Process each note
for idx, note in enumerate(notes[:3]): # Show first 3 notes
print(f" Note {idx + 1}: Pitch {note['pitch']}, "
f"Start {note['start']}s, End {note['end']}s, "
f"Velocity {note['velocity']}")
# Save MIDI data to file
with open(f"midi_{task_id}.json", "w") as f:
json.dump(callback_data, f, indent=2)
print(f"MIDI data saved to midi_{task_id}.json")
else:
# Task failed
print(f"MIDI generation failed: {msg}")
# Handle failure scenarios...
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$note) {
error_log(sprintf(
" Note %d: Pitch %d, Start %ss, End %ss, Velocity %s",
$idx + 1,
$note['pitch'],
$note['start'],
$note['end'],
$note['velocity']
));
}
}
// Save MIDI data to file
$filename = "midi_$taskId.json";
file_put_contents($filename, json_encode($callbackData, JSON_PRETTY_PRINT));
error_log("MIDI data saved to $filename");
}
} else {
// Task failed
error_log("MIDI generation failed: $msg");
// Handle failure scenarios...
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure callback URL uses HTTPS protocol for secure data transmission
2. **Verify Origin**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same task\_id may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return 200 status code quickly to avoid timeout
5. **Asynchronous Processing**: Complex business logic (like MIDI file conversion) should be processed asynchronously
6. **Handle Missing Instruments**: Not all instruments may be detected - handle empty or missing instrument arrays gracefully
7. **Store Raw Data**: Save the complete JSON response for future reference and reprocessing
### Important Reminders
* Callback URL must be publicly accessible
* Server must respond within 15 seconds, otherwise will be considered timeout
* If 3 consecutive retry attempts fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* MIDI data is retained for 14 days - download and save promptly if needed long-term
* The number and types of instruments detected depends on audio content
* Note times (start/end) may be strings or numbers - handle both types
## Troubleshooting
If you are not receiving callback notifications, please check the following:
* Confirm callback URL is accessible from public internet
* Check firewall settings to ensure inbound requests are not blocked
* Verify domain name resolution is correct
* Ensure server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify endpoint path and HTTP method are correct
* Confirm received POST request body is in JSON format
* Check if Content-Type is application/json
* Verify JSON parsing is correct
* Handle both string and number types for timing values
* Some instruments may have empty note arrays
* Not all audio will detect all instrument types
* Verify the original vocal separation used `split_stem` type (not `separate_vocal`)
* Check that the source taskId is from a successfully completed separation
## Alternative Solutions
If you cannot use the callback mechanism, you can also use polling:
Use the Get MIDI Generation Details endpoint to periodically query task status. We recommend querying every 10-30 seconds.
# Generate Music
Source: https://docs.sunoapi.org/suno-api/generate-music
suno-api/suno-api.json POST /api/v1/generate
Generate music with or without lyrics using AI models.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Usage Guide
* This endpoint creates music based on your text prompt
* Multiple variations will be generated for each request
* You can control detail level with custom mode and instrumental settings
### Parameter Details
* In Custom Mode (`customMode: true`):
* If `instrumental: true`: `style` and `title` are required
* If `instrumental: false`: `style`, `prompt`, and `title` are required
* Character limits vary by model:
* **V4 (Deprecated)**: `prompt` 3000 characters, `style` 200 characters
* **V4\_5, V4\_5PLUS, V5, V5\_5 & V4\_5ALL (Deprecated)**: `prompt` 5000 characters, `style` 1000 characters (**V5\_5**: Unleash Your Voice: Custom Models Tailored to Your Unique Taste — same limits as **V5**)
* **V6, V6\_WILD & V6\_MINI**: `prompt` 5000 characters, `style` 1000 characters
* `title` length limit: 80 characters (all models)
* In Non-custom Mode (`customMode: false`):
* Only `prompt` is required regardless of `instrumental` setting
* `prompt` length limit: 3000 characters
* Other parameters should be left empty
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Preferred vocal gender. Allowed values: `m` (male), `f` (female)
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* personaId (string): Persona ID or Suno Voice `voiceId` to apply in Custom Mode. If you use a Voice-generated ID, set `personaModel` to `voice_persona`.
* personaModel (string): Persona type. Use `style_persona` for Generate Persona IDs, or `voice_persona` for Suno Voice IDs.
```json JSON body theme={null}
{
"customMode": false,
"instrumental": false,
"prompt": "A chill lo-fi beat with soft vocals",
"model": "V6",
"callBackUrl": "https://example.com/callback",
"vocalGender": "m",
"styleWeight": 0.61,
"weirdnessConstraint": 0.72,
"audioWeight": 0.65
}
```
### Developer Notes
* Recommendation for new users: Start with `customMode: false` for simpler usage
* Generated files are retained for 14 days
* Callback process has three stages: `text` (text generation), `first` (first track complete), `complete` (all tracks complete)
# Music Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/generate-music-callbacks
When music generation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Music Generation API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Music generation task completed successfully
* Music generation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v3-5",
"title": "Iron Man",
"tags": "electrifying, rock",
"createTime": "2025-01-01 00:00:00",
"duration": 198.44
},
{
"id": "bd15****1873",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v3-5",
"title": "Iron Man",
"tags": "electrifying, rock",
"createTime": "2025-01-01 00:00:00",
"duration": 228.28
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Music generation failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------ |
| 200 | Success - Music generation completed |
| 400 | Bad Request - Parameter error, content violation, etc. |
| 451 | Download Failed - Unable to download related files |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First music track completed
* `complete`: All music tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Music generation result information, returned on success
Music unique identifier
Generated audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming audio URL
Original streaming audio URL
Cover image URL
Original cover image URL
Generation prompt/lyrics
Model name used
Music title
Music tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/generate-music-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received music generation callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Music generation completed');
const musicData = data.data || [];
console.log(`Generated ${musicData.length} music tracks:`);
musicData.forEach((music, index) => {
console.log(`Music ${index + 1}:`);
console.log(` Title: ${music.title}`);
console.log(` Duration: ${music.duration} seconds`);
console.log(` Tags: ${music.tags}`);
console.log(` Audio URL: ${music.audio_url}`);
console.log(` Cover URL: ${music.image_url}`);
});
// Process generated music
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Music generation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('File download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/generate-music-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
music_data = callback_data.get('data', [])
print(f"Received music generation callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Music generation completed")
print(f"Generated {len(music_data)} music tracks:")
for i, music in enumerate(music_data):
print(f"Music {i + 1}:")
print(f" Title: {music.get('title')}")
print(f" Duration: {music.get('duration')} seconds")
print(f" Tags: {music.get('tags')}")
print(f" Audio URL: {music.get('audio_url')}")
print(f" Cover URL: {music.get('image_url')}")
# Download audio file example
try:
audio_url = music.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"generated_music_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Audio saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Music generation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("File download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$music) {
error_log("Music " . ($index + 1) . ":");
error_log(" Title: " . ($music['title'] ?? ''));
error_log(" Duration: " . ($music['duration'] ?? 0) . " seconds");
error_log(" Tags: " . ($music['tags'] ?? ''));
error_log(" Audio URL: " . ($music['audio_url'] ?? ''));
error_log(" Cover URL: " . ($music['image_url'] ?? ''));
// Download audio file example
try {
$audioUrl = $music['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "generated_music_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Audio saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Music generation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("File download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Generate Persona
Source: https://docs.sunoapi.org/suno-api/generate-persona
suno-api/suno-api.json POST /api/v1/generate/generate-persona
Create a personalized music Persona based on generated music, giving the music a unique identity and characteristics.
### Usage Guide
* Use this endpoint to create Personas (music characters) for generated music
* Requires the taskId from supported music generation endpoints (generate, extend, mashup) and audio ID
* Customize the Persona name and description to give music unique personality
* Generated Personas can be used for subsequent music creation and style transfer
* Optionally specify vocalStart and vocalEnd to define the time range (10-30 seconds) for analysis. If not provided, defaults to 0.0 and 30.0 respectively
### Parameter Details
* `taskId`: Required parameter, can be obtained from the following endpoints:
* [Generate Music](./generate-music) (`/api/v1/generate`)
* [Extend Music](./extend-music) (`/api/v1/generate/extend`)
* `audioId`: Required parameter, specifies the audio ID to create Persona for
* `name`: Required parameter, assigns an easily recognizable name to the Persona
* `description`: Required parameter, describes the Persona's musical characteristics, style, and personality
* `vocalStart`: Optional parameter, start time (in seconds) of the audio segment to analyze. Default value is 0.0. Must be between 0 and the audio duration, and the segment length (vocalEnd - vocalStart) must be between 10-30 seconds.
* `vocalEnd`: Optional parameter, end time (in seconds) of the audio segment to analyze. Default value is 30.0. Must be between 0 and the audio duration, and the segment length (vocalEnd - vocalStart) must be between 10-30 seconds.
* `style`: Optional parameter, music style label to help categorize the Persona
### Developer Notes
* **Important**: Ensure the music generation task is fully completed before calling this endpoint. If the music is still generating, this endpoint will return a failure
* **Model Requirement**: Persona generation supports taskId from music generated with models V4 and above
* It is recommended to provide detailed descriptions for Personas to better capture musical characteristics
* The returned `personaId` can be used in subsequent music generation requests to create music with similar style characteristics
* You can apply the `personaId` to the following endpoints:
* [Generate Music](./generate-music)
* [Extend Music](./extend-music)
* [Upload And Cover Audio](./upload-and-cover-audio)
* [Upload And Extend Audio](./upload-and-extend-audio)
* Each audio ID can only generate a Persona once
### Parameter Example
```json With Default Values theme={null}
{
"taskId": "5c79****be8e",
"audioId": "e231****-****-****-****-****8cadc7dc",
"name": "Electronic Pop Singer",
"description": "A modern electronic music style pop singer, skilled in dynamic rhythms and synthesizer tones",
"style": "Electronic Pop"
}
```
```json With Custom Time Range theme={null}
{
"taskId": "5c79****be8e",
"audioId": "e231****-****-****-****-****8cadc7dc",
"name": "Electronic Pop Singer",
"description": "A modern electronic music style pop singer, skilled in dynamic rhythms and synthesizer tones",
"vocalStart": 10,
"vocalEnd": 30,
"style": "Electronic Pop"
}
```
Ensure that the music generation task corresponding to the taskId is complete and the audioId is valid.
Providing detailed and specific descriptions for Personas helps the system more accurately capture musical style characteristics.
# Generate Sounds
Source: https://docs.sunoapi.org/suno-api/generate-sounds
suno-api/suno-api.json POST /api/v1/generate/sounds
Create a sound generation task with loop, tempo, key, and optional lyrics subtitle capture settings.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
Used for creating a sound generation task (Sounds Task). It supports settings for looping, tempo (BPM), pitch (Key), as well as lyrics subtitle capture, etc.
## 🚀 User Guide
* By using this interface, you can generate corresponding audio content based on the input `prompt`.
* It supports setting up loop playback effect, which is suitable for background music, ambient sounds, and other scenarios.
* It allows specifying BPM (beats per minute) and pitch (Key) to facilitate control over the style of the generated result.
* Optional feature to enable lyric subtitle capture for easier display or processing of lyric content later.
* Supports asynchronous reception of task completion notifications through callback address.
### `model` parameter
* Allowed values: `V6`, `V6_WILD`, `V6_MINI`. Deprecated: `V5`, `V5_5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`.
## 📌 Usage Scenarios
* 🎧 Background music creation
* 🎮 Game sound effects or looped ambient sounds generation
* 🌐 Integration of audio content platforms and creative tools
# Get Music Cover Details
Source: https://docs.sunoapi.org/suno-api/get-cover-suno-details
suno-api/suno-api.json GET /api/v1/suno/cover/record-info
Get detailed information about music cover generation tasks.
### Usage Guide
* Use this interface to check Cover generation task status
* Access generated cover image URLs upon completion
* Track processing progress and any errors that may occur
* Supports polling to get task results, recommend querying every 30 seconds
### Developer Notes
* Cover image URLs are only available upon successful completion
* Error codes and messages are provided for failed tasks
* After successful processing, cover images are retained for 14 days
* Usually generates 2 different style cover images
# Get Lyrics Generation Details
Source: https://docs.sunoapi.org/suno-api/get-lyrics-generation-details
suno-api/suno-api.json GET /api/v1/lyrics/record-info
Retrieve detailed information about a lyrics generation task, including status, parameters, and results.
### Status Descriptions
* PENDING: Task is waiting to be processed
* SUCCESS: Lyrics generated successfully
* CREATE\_TASK\_FAILED: Failed to create the task
* GENERATE\_LYRICS\_FAILED: Failed to generate lyrics
* CALLBACK\_EXCEPTION: Error occurred during callback
* SENSITIVE\_WORD\_ERROR: Content contains prohibited words
### Developer Notes
* Use this endpoint to check task status instead of waiting for callbacks
* This returns all generated lyrics variations from a single task
* Each lyrics variation includes a title and complete lyrics text
# Get MIDI Generation Details
Source: https://docs.sunoapi.org/suno-api/get-midi-details
suno-api/suno-api.json GET /api/v1/midi/record-info
Retrieve detailed information about a MIDI generation task including complete note data for all detected instruments.
### Usage Guide
* Use this endpoint to check the status of a MIDI generation task
* Access complete MIDI note data once processing is complete
* Retrieve detailed instrument and note information
* Track processing progress and any errors that may have occurred
### Query Parameters
| Parameter | Type | Required | Description |
| :-------- | :----- | :------- | :---------------------------------------------------- |
| `taskId` | string | Yes | The task ID returned from the MIDI generation request |
### Developer Notes
* The `midiData` field contains the complete MIDI data as a structured object with instruments and notes
* MIDI data includes all detected instruments with pitch, timing, and velocity for each note
* MIDI generation records are retained for 14 days
* **Important**: When using [vocal separation](/suno-api/separate-vocals-from-music) with `type: split_stem`, the `midiData` may be empty.
# Get Music Generation Details
Source: https://docs.sunoapi.org/suno-api/get-music-generation-details
suno-api/suno-api.json GET /api/v1/generate/record-info
Retrieve detailed information about a music generation task, including status, parameters, and results.
### Status Descriptions
* PENDING: Task is waiting to be processed
* TEXT\_SUCCESS: Lyrics/text generation completed successfully
* FIRST\_SUCCESS: First track generation completed successfully
* SUCCESS: All tracks generated successfully
* CREATE\_TASK\_FAILED: Failed to create the generation task
* GENERATE\_AUDIO\_FAILED: Failed to generate music tracks
* CALLBACK\_EXCEPTION: Error occurred during callback
* SENSITIVE\_WORD\_ERROR: Content contains prohibited words
### Developer Notes
* For instrumental tracks (instrumental=true), no lyrics data will be included in the response
* Use this endpoint to check task status instead of waiting for callbacks
# Get Music Video Details
Source: https://docs.sunoapi.org/suno-api/get-music-video-details
suno-api/suno-api.json GET /api/v1/mp4/record-info
Retrieve detailed information about a music video generation task, including status and download link.
### Status Descriptions
* PENDING: Task is waiting to be processed
* SUCCESS: Video generation completed successfully
* CREATE\_TASK\_FAILED: Failed to create the video task
* GENERATE\_MP4\_FAILED: MP4 generation failed
* CALLBACK\_EXCEPTION: Callback exception
# Get Recovery Audio Details
Source: https://docs.sunoapi.org/suno-api/get-recovery-audio-details
suno-api/suno-api.json GET /api/v1/suno/recovery/record-info
Query the status and recovered audio links of a recovery task.
Query a recovery task created by [Recovery Audio](/suno-api/recovery-audio) and read the recovered audio links.
### Status Descriptions
* `201` — the recovery task is still running, keep polling
* `200` — the recovery finished and at least one track was recovered successfully
* `500` — every track failed to recover
### Per-track `status`
* `success` — `audio_url` carries the recovered playable link
* `failed` — `audio_url` is empty and `error` explains the reason
Common `error` values:
| Value | Meaning |
| ----------------------- | --------------------------------------------------- |
| `no_audio_id_mappings` | The track cannot be found for this task |
| `account_missing` | The source account is unavailable |
| `get_tokens_failed` | Failed to authenticate against the upstream service |
| `feed_failed` | Failed to query the track from the upstream service |
| `clip_error` | The upstream track is in an error state |
| `clip_not_complete` | The upstream track is not finished yet |
| `mango_transfer_failed` | Failed to transfer the recovered file |
### Developer Notes
* Poll this endpoint instead of waiting for the callback when you cannot expose a public callback URL. A 2 second interval is recommended.
* `data` is `null` while `code` is `201`.
* A recovered `audio_url` may be an `.m4a` file — do not assume `.mp3` when saving it.
# Get Remaining Credits
Source: https://docs.sunoapi.org/suno-api/get-remaining-credits
suno-api/suno-api.json GET /api/v1/generate/credit
Retrieve the current balance of available credits for your account.
### Usage Guide
* Credits are consumed when generating music, lyrics, or using other processing features.
* This endpoint allows you to check your current credit balance before initiating tasks.
* Returns a single integer value representing your available credits.
* No parameters required; authentication via API key is sufficient.
### Developer Notes
1. Monitor your credit balance regularly to avoid service interruptions.
2. If credits are insufficient, generation tasks will fail with error code 429.
3. Consider integrating this check before starting expensive generation operations.
4. This endpoint is lightweight and can be called frequently as needed.
# Get Timestamped Lyrics
Source: https://docs.sunoapi.org/suno-api/get-timestamped-lyrics
suno-api/suno-api.json POST /api/v1/generate/get-timestamped-lyrics
Retrieve timestamped lyrics for synchronized display during audio playback.
### Parameter Selection Logic
1. audioId parameter:
* The audioId parameter is required to identify the exact track
* Provides a unique identifier for the audio track within the generation task
### Developer Notes
1. Timestamp values are in seconds
2. Returned waveform data can be used for audio visualization
3. For instrumental tracks (generated with instrumental=true), no lyrics data will be available
4. Typical use case: Karaoke-style lyrics display in music player interfaces
# Get Audio Separation Details
Source: https://docs.sunoapi.org/suno-api/get-vocal-separation-details
suno-api/suno-api.json GET /api/v1/vocal-removal/record-info
Retrieve detailed information about a vocal separation task, including status and download links.
### Status Descriptions
* PENDING: Task is waiting to be processed
* SUCCESS: Vocal separation completed successfully
* CREATE\_TASK\_FAILED: Failed to create the separation task
* GENERATE\_AUDIO\_FAILED: Failed to perform vocal separation
* CALLBACK\_EXCEPTION: Error occurred during callback
### Return Data Description
Based on the separation type you selected during generation, the audio URL fields included in the response will vary:
#### separate\_vocal Type Return Fields
When status is SUCCESS, the response includes the following download URLs:
* `originUrl`: Original mixed track
* `instrumentalUrl`: Instrumental track without vocals
* `vocalUrl`: Isolated vocals only track
#### split\_stem Type Return Fields
When status is SUCCESS, the response includes the following download URLs:
* `originUrl`: Original mixed track
* `vocalUrl`: Isolated vocals only track
* `backingVocalsUrl`: Isolated backing vocals track
* `drumsUrl`: Isolated drums track
* `bassUrl`: Isolated bass track
* `guitarUrl`: Isolated guitar track
* `keyboardUrl`: Isolated keyboard track
* `percussionUrl`: Isolated percussion track
* `stringsUrl`: Isolated strings track
* `synthUrl`: Isolated synthesizer track
* `fxUrl`: Isolated effects track
* `brassUrl`: Isolated brass track
* `woodwindsUrl`: Isolated woodwinds track
### Developer Notes
* Use this endpoint to check separation status instead of waiting for callbacks
* Task creation and completion times are included in the response
* Different separation types return different combinations of audio fields
* Audio URLs are only returned when the task is successfully completed
* Audio file URLs have time limits, recommend downloading and saving promptly
* `separate_vocal` type returns `instrumentalUrl` and `vocalUrl` fields, other instrument fields are null
* `split_stem` type returns detailed instrument separation fields, `instrumentalUrl` is null
# Get WAV Conversion Details
Source: https://docs.sunoapi.org/suno-api/get-wav-conversion-details
suno-api/suno-api.json GET /api/v1/wav/record-info
Retrieve detailed information about a WAV format conversion task, including status and download link.
### Status Descriptions
* PENDING: Task is waiting to be processed
* SUCCESS: WAV conversion completed successfully
* CREATE\_TASK\_FAILED: Failed to create the conversion task
* GENERATE\_WAV\_FAILED: Failed to convert to WAV format
* CALLBACK\_EXCEPTION: Error occurred during callback
### Developer Notes
* Use this endpoint to check conversion status instead of waiting for callbacks
* The response includes the WAV file download URL when status is SUCCESS
* Task creation and completion times are included in the response
# Suno API Quick Start
Source: https://docs.sunoapi.org/suno-api/quickstart
Get started with Suno API in minutes to generate high-quality AI music, lyrics, and audio processing
## Welcome to Suno API
Suno API is powered by advanced AI models to provide comprehensive music generation and audio processing services. Whether you need music creation, lyrics generation, audio editing, or vocal separation, our API meets all your creative needs.
Generate high-quality music from text descriptions
Create AI-powered lyrics for your songs
Extend, convert, and separate audio tracks
Generate visual music videos from audio
## Authentication
All API requests require authentication using a Bearer token. Please obtain your API key from the [API Key Management page](https://sunoapi.org/api-key).
Keep your API key secure and never share it publicly. If you suspect your key has been compromised, reset it immediately.
### API Base URL
```
https://api.sunoapi.org
```
### Authentication Header
```http theme={null}
Authorization: Bearer YOUR_API_KEY
```
## Quick Start Guide
### Step 1: Generate Your First Song
Start with a simple music generation request:
```bash cURL theme={null}
curl -X POST "https://api.sunoapi.org/api/v1/generate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A peaceful acoustic guitar melody with soft vocals, folk style",
"customMode": false,
"instrumental": false,
"model": "V4_5ALL",
"callBackUrl": "https://your-server.com/callback"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.sunoapi.org/api/v1/generate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'A peaceful acoustic guitar melody with soft vocals, folk style',
customMode: false,
instrumental: false,
model: 'V4_5ALL',
callBackUrl: 'https://your-server.com/callback'
})
});
const data = await response.json();
console.log('Task ID:', data.data.taskId);
```
```python Python theme={null}
import requests
url = "https://api.sunoapi.org/api/v1/generate"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"prompt": "A peaceful acoustic guitar melody with soft vocals, folk style",
"customMode": False,
"instrumental": False,
"model": "V4_5ALL",
"callBackUrl": "https://your-server.com/callback"
}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
print(f"Task ID: {result['data']['taskId']}")
```
```php PHP theme={null}
'A peaceful acoustic guitar melody with soft vocals, folk style',
'customMode' => false,
'instrumental' => false,
'model' => 'V4_5ALL',
'callBackUrl' => 'https://your-server.com/callback'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo "Task ID: " . $result['data']['taskId'];
?>
```
### Step 2: Check Task Status
Use the returned task ID to check generation status:
```bash cURL theme={null}
curl -X GET "https://api.sunoapi.org/api/v1/generate/record-info?taskId=YOUR_TASK_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
```
```javascript JavaScript theme={null}
const response = await fetch(`https://api.sunoapi.org/api/v1/generate/record-info?taskId=${taskId}`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const result = await response.json();
if (result.data.status === 'SUCCESS') {
console.log('Generation complete!');
console.log('Audio URLs:', result.data.response.data);
} else if (result.data.status === 'GENERATING') {
console.log('Still generating...');
} else {
console.log('Generation failed:', result.data.status);
}
```
```python Python theme={null}
import requests
import time
def check_task_status(task_id, api_key):
url = f"https://api.sunoapi.org/api/v1/generate/record-info?taskId={task_id}"
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(url, headers=headers)
result = response.json()
status = result['data']['status']
if status == 'SUCCESS':
print("Generation complete!")
audio_data = result['data']['response']['data']
for i, audio in enumerate(audio_data):
print(f"Track {i+1}: {audio['audio_url']}")
return audio_data
elif status == 'GENERATING':
print("Still generating...")
return None
else:
print(f"Generation failed: {status}")
return None
# Poll until completion
task_id = "YOUR_TASK_ID"
while True:
audio_data = check_task_status(task_id, "YOUR_API_KEY")
if audio_data:
break
time.sleep(30) # Wait 30 seconds before checking again
```
### Response Format
**Success Response:**
```json theme={null}
{
"code": 200,
"msg": "success",
"data": {
"taskId": "suno_task_abc123"
}
}
```
**Task Status Response:**
```json theme={null}
{
"code": 200,
"msg": "success",
"data": {
"taskId": "suno_task_abc123",
"status": "SUCCESS",
"response": {
"data": [
{
"id": "audio_123",
"audio_url": "https://example.com/generated-music.mp3",
"title": "Generated Song",
"tags": "folk, acoustic",
"duration": 180.5
}
]
}
}
}
```
## Core Features
### Music Generation
Create complete songs from text descriptions:
```json theme={null}
{
"prompt": "An upbeat electronic dance track with synth leads",
"customMode": true,
"style": "Electronic Dance",
"title": "Digital Dreams",
"instrumental": false,
"model": "V4_5"
}
```
### Lyrics Creation
Generate AI-powered lyrics independently:
```json theme={null}
{
"prompt": "A song about overcoming challenges and finding inner strength",
"callBackUrl": "https://your-server.com/lyrics-callback"
}
```
### Audio Extension
Extend existing music tracks:
```json theme={null}
{
"audioId": "e231****-****-****-****-****8cadc7dc",
"defaultParamFlag": true,
"prompt": "Continue with a guitar solo",
"continueAt": 120,
"model": "V4_5ALL"
}
```
### Upload and Cover
Transform existing audio with new styles:
```json theme={null}
{
"uploadUrl": "https://example.com/original-audio.mp3",
"customMode": true,
"style": "Jazz",
"title": "Jazz Version",
"prompt": "Transform into smooth jazz style"
}
```
## Model Versions
Choose the right model for your needs:
**High Quality**
Best audio quality with refined song structure, up to 4 minutes
**Advanced**
Superior genre blending with smarter prompts, up to 8 minutes
**Richer Sound**
Enhanced musicality with new creative ways, up to 8 minutes
**Better Structure**
V4.5-all is better song structure, max 8 min
**Faster Generation**
Superior musicality with improved speed, up to 8 minutes
**Unleash Your Voice**
Unleash Your Voice: Custom Models Tailored to Your Unique Taste.
## Key Parameters
Text description for music generation. Provide detailed, specific descriptions for better results.
**Character limits by model:**
* V4: Maximum 3000 characters
* V4\_5, V4\_5PLUS, V4\_5ALL, V5, V5\_5: Maximum 5000 characters
**Prompt Tips:**
* Describe musical style and genre
* Include mood and atmosphere
* Specify instruments and vocals
* Add tempo and energy descriptions
Model version to use:
* `V4` - Best audio quality, up to 4 minutes
* `V4_5` - Advanced features, up to 8 minutes
* `V4_5PLUS` - Richer sound, up to 8 minutes
* `V4_5ALL` - V4.5-all is better song structure, max 8 min
* `V5` - Faster generation with superior musicality, up to 8 minutes
* `V5_5` - Unleash Your Voice: Custom Models Tailored to Your Unique Taste.
Enable custom parameter mode for advanced control. When `true`, requires additional parameters like `style` and `title`.
Generate instrumental-only music without vocals. Default is `false`.
Music style or genre (required in custom mode). Examples: "Jazz", "Rock", "Classical", "Electronic"
**Character limits by model:**
* V4: Maximum 200 characters
* V4\_5, V4\_5PLUS, V4\_5ALL, V5, V5\_5: Maximum 1000 characters
Song title (required in custom mode). Character limits by model:
* V4 & V4\_5ALL: Maximum 80 characters
* V4\_5, V4\_5PLUS, V5, V5\_5: Maximum 100 characters
URL to receive completion notifications. See callback documentation for details.
## Complete Workflow Example
Here's a complete music generation and processing example:
```javascript theme={null}
class SunoAPI {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.sunoapi.org/api/v1';
}
async generateMusic(options) {
const response = await fetch(`${this.baseUrl}/generate`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(options)
});
const result = await response.json();
if (result.code !== 200) {
throw new Error(`Generation failed: ${result.msg}`);
}
return result.data.taskId;
}
async generateLyrics(prompt) {
const response = await fetch(`${this.baseUrl}/lyrics`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt,
callBackUrl: 'https://your-server.com/lyrics-callback'
})
});
const result = await response.json();
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);
if (status.status === 'SUCCESS') {
return status.response;
} else if (status.status === 'FAILED') {
throw new Error(`Generation failed: ${status.errorMessage}`);
}
// Wait 30 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 30000));
}
throw new Error('Generation timeout');
}
async getTaskStatus(taskId) {
const response = await fetch(`${this.baseUrl}/generate/record-info?taskId=${taskId}`, {
headers: {
'Authorization': `Bearer ${this.apiKey}`
}
});
const result = await response.json();
return result.data;
}
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,
...options
})
});
const result = await response.json();
return result.data.taskId;
}
async separateVocals(taskId, audioId) {
const response = await fetch(`${this.baseUrl}/vocal-removal/generate`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
taskId,
audioId,
callBackUrl: 'https://your-server.com/vocal-callback'
})
});
const result = await response.json();
return result.data.taskId;
}
async getRemainingCredits() {
const response = await fetch(`${this.baseUrl}/get-credits`, {
headers: {
'Authorization': `Bearer ${this.apiKey}`
}
});
const result = await response.json();
return result.data.credits;
}
}
// Usage example
async function main() {
const api = new SunoAPI('YOUR_API_KEY');
try {
// Check remaining credits
const credits = await api.getRemainingCredits();
console.log(`Remaining credits: ${credits}`);
// Generate lyrics first
console.log('Generating lyrics...');
const lyricsTaskId = await api.generateLyrics(
'A song about adventure and discovery, uplifting and inspiring'
);
const lyricsResult = await api.waitForCompletion(lyricsTaskId);
console.log('Lyrics generated:', lyricsResult.data[0].text);
// Generate music with custom parameters
console.log('Generating music...');
const musicTaskId = await api.generateMusic({
prompt: lyricsResult.data[0].text,
customMode: true,
style: 'Folk Pop',
title: 'Adventure Song',
instrumental: false,
model: 'V4_5',
callBackUrl: 'https://your-server.com/music-callback'
});
// Wait for completion
const musicResult = await api.waitForCompletion(musicTaskId);
console.log('Music generated successfully!');
musicResult.data.forEach((track, index) => {
console.log(`Track ${index + 1}:`);
console.log(` Title: ${track.title}`);
console.log(` Duration: ${track.duration}s`);
console.log(` Audio URL: ${track.audio_url}`);
});
// Extend the first track
const originalTrack = musicResult.data[0];
console.log('Extending music...');
const extendTaskId = await api.extendMusic(originalTrack.id, {
defaultParamFlag: true,
prompt: 'Continue with a beautiful instrumental outro',
continueAt: originalTrack.duration - 30, // Extend from 30s before end
model: 'V4_5'
});
const extendedResult = await api.waitForCompletion(extendTaskId);
console.log('Extended version created:', extendedResult.data[0].audio_url);
// Separate vocals
console.log('Separating vocals...');
const separationTaskId = await api.separateVocals(musicTaskId, originalTrack.id);
const separationResult = await api.waitForCompletion(separationTaskId);
console.log('Vocal separation completed:');
console.log(` Instrumental: ${separationResult.vocal_removal_info.instrumental_url}`);
console.log(` Vocals only: ${separationResult.vocal_removal_info.vocal_url}`);
} catch (error) {
console.error('Error:', error.message);
}
}
main();
```
```python theme={null}
import requests
import time
class SunoAPI:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://api.sunoapi.org/api/v1'
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
def generate_music(self, **options):
response = requests.post(f'{self.base_url}/generate',
headers=self.headers, json=options)
result = response.json()
if result['code'] != 200:
raise Exception(f"Generation failed: {result['msg']}")
return result['data']['taskId']
def generate_lyrics(self, prompt):
response = requests.post(f'{self.base_url}/lyrics',
headers=self.headers,
json={
'prompt': prompt,
'callBackUrl': 'https://your-server.com/lyrics-callback'
})
result = response.json()
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':
return status['response']
elif status['status'] == 'FAILED':
raise Exception(f"Generation failed: {status.get('errorMessage')}")
time.sleep(30) # Wait 30 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}'})
return response.json()['data']
def extend_music(self, audio_id, **options):
response = requests.post(f'{self.base_url}/generate/extend',
headers=self.headers,
json={'audioId': audio_id, **options})
return response.json()['data']['taskId']
def separate_vocals(self, task_id, audio_id):
response = requests.post(f'{self.base_url}/vocal-removal/generate',
headers=self.headers,
json={
'taskId': task_id,
'audioId': audio_id,
'callBackUrl': 'https://your-server.com/vocal-callback'
})
return response.json()['data']['taskId']
def get_remaining_credits(self):
response = requests.get(f'{self.base_url}/get-credits',
headers={'Authorization': f'Bearer {self.api_key}'})
return response.json()['data']['credits']
# Usage example
def main():
api = SunoAPI('YOUR_API_KEY')
try:
# Check remaining credits
credits = api.get_remaining_credits()
print(f'Remaining credits: {credits}')
# Generate lyrics first
print('Generating lyrics...')
lyrics_task_id = api.generate_lyrics(
'A song about adventure and discovery, uplifting and inspiring'
)
lyrics_result = api.wait_for_completion(lyrics_task_id)
print('Lyrics generated:', lyrics_result['data'][0]['text'])
# Generate music with custom parameters
print('Generating music...')
music_task_id = api.generate_music(
prompt=lyrics_result['data'][0]['text'],
customMode=True,
style='Folk Pop',
title='Adventure Song',
instrumental=False,
model='V4_5',
callBackUrl='https://your-server.com/music-callback'
)
# Wait for completion
music_result = api.wait_for_completion(music_task_id)
print('Music generated successfully!')
for i, track in enumerate(music_result['data']):
print(f'Track {i + 1}:')
print(f' Title: {track["title"]}')
print(f' Duration: {track["duration"]}s')
print(f' Audio URL: {track["audio_url"]}')
# Extend the first track
original_track = music_result['data'][0]
print('Extending music...')
extend_task_id = api.extend_music(
original_track['id'],
defaultParamFlag=True,
prompt='Continue with a beautiful instrumental outro',
continueAt=original_track['duration'] - 30,
model='V4_5'
)
extended_result = api.wait_for_completion(extend_task_id)
print('Extended version created:', extended_result['data'][0]['audio_url'])
# Separate vocals
print('Separating vocals...')
separation_task_id = api.separate_vocals(music_task_id, original_track['id'])
separation_result = api.wait_for_completion(separation_task_id)
print('Vocal separation completed:')
vocal_info = separation_result['vocal_removal_info']
print(f' Instrumental: {vocal_info["instrumental_url"]}')
print(f' Vocals only: {vocal_info["vocal_url"]}')
except Exception as error:
print(f'Error: {error}')
if __name__ == '__main__':
main()
```
## Advanced Features
### Upload and Extend
Upload your own audio and extend it with AI:
```javascript theme={null}
const extendTaskId = await api.generateMusic({
uploadUrl: 'https://example.com/my-song.mp3',
defaultParamFlag: true,
prompt: 'Add a rock guitar solo section',
continueAt: 60,
model: 'V4_5'
});
```
### Audio Format Conversion
Convert music to high-quality WAV format:
```javascript theme={null}
const wavTaskId = await api.convertToWav({
taskId: 'original_task_id',
audioId: 'e231****-****-****-****-****8cadc7dc',
callBackUrl: 'https://your-server.com/wav-callback'
});
```
### Music Video Generation
Create visual music videos:
```javascript theme={null}
const videoTaskId = await api.createMusicVideo({
taskId: 'music_task_id',
audioId: 'e231****-****-****-****-****8cadc7dc',
author: 'Artist Name',
domainName: 'your-brand.com',
callBackUrl: 'https://your-server.com/video-callback'
});
```
### Using Callbacks
Set up webhook callbacks for automatic notifications:
```javascript theme={null}
// Your callback endpoint
app.post('/music-callback', (req, res) => {
const { code, data } = req.body;
if (code === 200) {
console.log('Music ready:', data.data);
data.data.forEach(track => {
console.log(`Title: ${track.title}`);
console.log(`Audio: ${track.audio_url}`);
});
} else {
console.log('Generation failed:', req.body.msg);
}
res.status(200).json({ status: 'received' });
});
```
Set up webhook callbacks to receive automatic notifications when your music is ready.
## Task Status Explanation
Task is being processed
Task completed successfully
Task failed to complete
Task is queued for processing
## Best Practices
* Use detailed, specific descriptions for music style and mood
* Include instrument specifications and vocal requirements
* Specify tempo, energy level, and song structure
* Avoid conflicting or overly complex descriptions
* Choose V4 for highest audio quality in standard lengths
* Select V4\_5 for advanced features and longer tracks
* V4\_5PLUS offers richer sound with new creative ways
* Use V4\_5ALL for better song structure (max 8 min)
* V5 provides faster generation with superior musicality
* Consider your specific use case and quality requirements
* Use callbacks instead of frequent polling
* Implement proper retry logic for failed requests
* Monitor your credit usage and plan accordingly
* Cache results to avoid regenerating similar content
* Implement appropriate retry logic for transient failures
* Monitor task status and handle timeout scenarios
* Validate input parameters before making requests
* Log errors for debugging and monitoring
## File Storage and Access
Generated audio files are stored for **15 days** before automatic deletion. Download URLs may have limited validity periods.
* Audio files remain accessible for 15 days after generation
* Download and save important files to your own storage
* Use the API to regenerate content if needed after expiration
* Consider implementing local backup strategies for critical content
## Next Steps
Complete API reference for music generation
AI-powered lyrics generation
Extend, convert, and separate audio
Set up automatic notifications
## Support
Need help? Our technical support team is here to assist you.
* **Email**: [support@sunoapi.org](mailto:support@sunoapi.org)
* **Documentation**: [docs.sunoapi.org](https://docs.sunoapi.org)
* **API Status**: Check our status page for real-time API health
***
Ready to start creating amazing AI music? [Get your API key](https://sunoapi.org/api-key) and begin composing today!
# Recovery Audio
Source: https://docs.sunoapi.org/suno-api/recovery-audio
suno-api/suno-api.json POST /api/v1/suno/recovery
Recover playable audio links for an existing music generation task.
Used to recover playable audio links for a music generation task that has already completed. Submit the `sunoTaskId` of the original task and the service regenerates accessible audio URLs for every track that belongs to it.
## 🚀 User Guide
* Suno's original links are only valid for a limited period of time. Once they expire, the audio can no longer be played or downloaded from those URLs.
* Submit the `sunoTaskId` of the original music generation task — all tracks of that task are recovered together.
* This endpoint only creates the task: it returns a recovery `task_id` immediately and the recovery itself runs asynchronously.
* The result is pushed to `callBackUrl` when the task finishes, and can also be read by polling [Get Recovery Audio Details](/suno-api/get-recovery-audio-details).
**`source_audio_url` is deprecated.**
`source_audio_url` in the generation responses and callbacks points to Suno's original file. That link expires after a period of time and is no longer maintained, so it must not be stored for long-term use. Call this endpoint to obtain a fresh playable link instead.
## 📌 Usage Scenarios
* 🔗 Restoring playback for songs that were generated a long time ago
* 📦 Refreshing audio links before archiving or migrating your own library
* 🛠️ Repairing broken audio URLs reported by your end users
## ⚠️ Notes
* `sunoTaskId` in the request body is the **music generation task ID** (for example the one returned by [Generate Music](/suno-api/generate-music)), not the ID returned by this endpoint.
* The `task_id` in the response is the **recovery task ID** and is only accepted by [Get Recovery Audio Details](/suno-api/get-recovery-audio-details).
* `callBackUrl` is required. The recovery result is pushed to it once the task finishes.
* Creating the task successfully does not guarantee that every track can be recovered — check the final result for the per-track `status`.
## 📩 Callback
Once the recovery task finishes, a `POST` request is sent to `callBackUrl`:
```json theme={null}
{
"code": 200,
"msg": "success",
"task_id": "bbbb****0f7b",
"data": [
{
"id": "3bc3****48fc",
"audio_url": "https://example.com/****.m4a",
"title": "Sunrise Love",
"status": "success",
"error": ""
}
]
}
```
The task level `code` is `200` when at least one track was recovered, and `500` when all of them failed. The order of `data` matches the tracks of the original task.
# Replace Music Section
Source: https://docs.sunoapi.org/suno-api/replace-section
suno-api/suno-api.json POST /api/v1/generate/replace-section
Replace a specific time segment within existing music.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Parameter Usage Guide
This endpoint supports two modes for specifying the source audio:
**Mode 1: Replace section using existing audio**
* `taskId` and `audioId` are required
* `uploadUrl` and `model` must NOT be provided
**Mode 2: Replace section using uploaded custom audio**
* `uploadUrl` and `model` are required
* `taskId` and `audioId` must NOT be provided
### Common Required Parameters
* **prompt** (string, required): Replaced lyrics
* **tags** (string, required): Music style tags, such as jazz, electronic, etc.
* **title** (string, required): Music title
* **infillStartS** (number, required): Start time point for replacement (seconds), 2 decimal places. Must be less than infillEndS. The time interval (infillEndS - infillStartS) must be at least 10 seconds.
* **infillEndS** (number, required): End time point for replacement (seconds), 2 decimal places. Must be greater than infillStartS. The time interval (infillEndS - infillStartS) must be at least 10 seconds.
* **fullLyrics** (string, required): Complete lyrics after modification, combining both modified and unmodified lyrics
### Optional Parameters
The following fields are optional controls available for this endpoint:
* negativeTags (string): Excluded music styles, used to avoid specific style elements in the replacement segment
* callBackUrl (string): Callback URL for task completion notification. For detailed callback format, see [Replace Music Section Callbacks](/suno-api/replace-section-callbacks).
### Time Range Instructions
* `infillStartS` must be less than `infillEndS`
* Time values are precise to 2 decimal places, e.g., `10.50` seconds
* The replacement time must be at least **10 seconds**.
* Replacement duration should not exceed **50%** of the original music's total duration
```json Replace using existing audio theme={null}
{
"taskId": "2fac****9f72",
"audioId": "e231****-****-****-****-****8cadc7dc",
"prompt": "A calm and relaxing piano track.",
"tags": "Jazz",
"title": "Relaxing Piano",
"negativeTags": "Rock",
"infillStartS": 10.5,
"infillEndS": 20.75,
"fullLyrics": "[Verse 1]\nOriginal lyrics here\n[Chorus]\nModified lyrics for this section\n[Verse 2]\nMore original lyrics",
"callBackUrl": "https://example.com/callback"
}
```
```json Replace using uploaded audio theme={null}
{
"uploadUrl": "https://example.com/audio.mp3",
"model": "V6",
"prompt": "A calm and relaxing piano track.",
"tags": "Jazz",
"title": "Relaxing Piano",
"negativeTags": "Rock",
"infillStartS": 10.5,
"infillEndS": 20.75,
"fullLyrics": "[Verse 1]\nOriginal lyrics here\n[Chorus]\nModified lyrics for this section\n[Verse 2]\nMore original lyrics",
"callBackUrl": "https://example.com/callback"
}
```
### Developer Notes
1. Replacement segments will be regenerated based on the provided `prompt` and `tags`
2. Generated replacement segments will automatically blend with the original music's preceding and following parts
3. Generated files will be retained for **14 days**
4. Query task status using the same interface as generating music: [Get Music Details](/suno-api/get-music-generation-details)
# Replace Music Section Callbacks
Source: https://docs.sunoapi.org/suno-api/replace-section-callbacks
Understand the callback mechanism for replace music section tasks
When you submit a replace music section task to the API, you can provide a `callBackUrl` to receive real-time notifications about task progress and completion.
## Callback Mechanism
### When Callbacks Are Sent
The system sends callbacks at the following times:
* **Complete**: When the replacement task is fully completed
### Callback Method
* **HTTP Method**: POST
* **Content-Type**: application/json
* **Timeout**: 10 seconds
* **Retry Policy**: Up to 3 attempts with exponential backoff
## Request Format
### Success Callback
When the replacement task completes successfully:
```json theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] The city at night is ablaze with lights.",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"duration": 198.44,
"tags": "electrifying, rock",
"source_audio_url":"https://example.cn/****.jpeg",
"source_image_url":"https://example.cn/****.mp3",
"source_stream_audio_url":"https://example.cn/****"
},
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] The city at night is ablaze with lights.",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"duration": 198.44,
"tags": "electrifying, rock",
"source_audio_url":"https://example.cn/****.jpeg",
"source_image_url":"https://example.cn/****.mp3",
"source_stream_audio_url":"https://example.cn/****"
}
]
}
}
```
### Failure Callback
When the replacement task fails:
```json theme={null}
{
"code": 501,
"msg": "Audio generation failed.",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"error": "Generation failed due to technical issues"
}
}
```
## Status Codes
| Code | Description |
| ---- | -------------------------------------------------- |
| 200 | Success - Task completed successfully |
| 400 | Validation error - Parameter validation failed |
| 408 | Timeout - Request timeout |
| 500 | Server error - Unexpected error occurred |
| 501 | Audio generation failed |
| 531 | Server error - Generation failed, credits refunded |
## Response Fields
### Success Response Fields
Status code indicating the result of the replacement task
Status message describing the result
Container for callback data
Type of callback: `complete` or `error`
The task ID for the replacement request
Array of replaced music data (only present on success)
Unique identifier for the music segment
Direct URL to the audio file
Streaming URL for the audio
URL to the cover image
The prompt used for generating the replacement
Name of the AI model used
Title of the music
Style tags for the music
Creation timestamp
Duration of the audio in seconds
Source audio file URL.
Source cover image URL.
Source streaming audio URL.
## Implementation Examples
```javascript Node.js (Express) theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/replace-section-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Replace section callback received:', {
code,
msg,
taskId: data.task_id,
callbackType: data.callbackType
});
if (code === 200 && data.callbackType === 'complete') {
// Handle successful replacement
console.log('Replacement completed successfully');
data.data.forEach((music, index) => {
console.log(`Music ${index + 1}:`, {
id: music.id,
title: music.title,
duration: music.duration,
audioUrl: music.audio_url
});
});
} else {
// Handle failure
console.log('Replacement failed:', msg);
}
// Always respond with success to acknowledge receipt
res.json({ code: 200, msg: 'success' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python Python (Flask) theme={null}
from flask import Flask, request, jsonify
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/replace-section-callback', methods=['POST'])
def replace_section_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
logging.info(f"Replace section callback received: code={code}, msg={msg}")
if code == 200 and callback_data.get('callbackType') == 'complete':
# Handle successful replacement
logging.info("Replacement completed successfully")
music_data = callback_data.get('data', [])
for i, music in enumerate(music_data):
logging.info(f"Music {i + 1}: {music.get('title')} - {music.get('duration')}s")
else:
# Handle failure
logging.error(f"Replacement failed: {msg}")
# Always respond with success
return jsonify({"code": 200, "msg": "success"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php PHP theme={null}
400, 'msg' => 'Invalid JSON']);
exit;
}
$code = $data['code'] ?? null;
$msg = $data['msg'] ?? '';
$callbackData = $data['data'] ?? [];
error_log("Replace section callback received: code=$code, msg=$msg");
if ($code === 200 && ($callbackData['callbackType'] ?? '') === 'complete') {
// Handle successful replacement
error_log("Replacement completed successfully");
$musicData = $callbackData['data'] ?? [];
foreach ($musicData as $index => $music) {
$title = $music['title'] ?? 'Unknown';
$duration = $music['duration'] ?? 0;
error_log("Music " . ($index + 1) . ": $title - {$duration}s");
}
} else {
// Handle failure
error_log("Replacement failed: $msg");
}
// Always respond with success
echo json_encode(['code' => 200, 'msg' => 'success']);
?>
```
## Callback Security
### Verification Recommendations
1. **IP Whitelist**: Restrict callback endpoints to known IP addresses
2. **HTTPS Only**: Always use HTTPS for callback URLs in production
3. **Request Validation**: Validate the structure and content of callback requests
4. **Timeout Handling**: Implement proper timeout handling for callback processing
### Example Security Implementation
```javascript theme={null}
const crypto = require('crypto');
function verifyCallback(req, res, next) {
// Verify request structure
const { code, msg, data } = req.body;
if (typeof code !== 'number' || typeof msg !== 'string' || !data) {
return res.status(400).json({ code: 400, msg: 'Invalid callback format' });
}
// Verify task ID format
const taskId = data.task_id;
if (!taskId || !/^[a-f0-9\*]{12}$/.test(taskId)) {
return res.status(400).json({ code: 400, msg: 'Invalid task ID' });
}
next();
}
app.post('/replace-section-callback', verifyCallback, (req, res) => {
// Process verified callback
// ... callback handling logic
});
```
## Troubleshooting
### Common Issues
**Q: Callbacks are not being received**
* Verify your callback URL is publicly accessible
* Check that your server is responding within 10 seconds
* Ensure your endpoint accepts POST requests with JSON content
**Q: Receiving duplicate callbacks**
* This can happen due to network issues or timeouts
* Implement idempotency using the task\_id to handle duplicates
**Q: Callback data is missing or incomplete**
* Check the `callbackType` field to understand the callback stage
* For error callbacks, check the error message for details
**Q: How to handle callback failures?**
* Always return a 200 status code to acknowledge receipt
* Use the [Get Music Details](/suno-api/get-music-generation-details) endpoint to poll task status as a fallback
### Best Practices
1. **Always Acknowledge**: Return HTTP 200 even if your processing fails
2. **Implement Retry Logic**: Handle temporary failures gracefully
3. **Log Everything**: Keep detailed logs for debugging
4. **Use Fallback Polling**: Don't rely solely on callbacks for critical workflows
5. **Validate Data**: Always validate callback data before processing
# Vocal & Instrument Stem Separation
Source: https://docs.sunoapi.org/suno-api/separate-vocals-from-music
suno-api/suno-api.json POST /api/v1/vocal-removal/generate
Use Suno's official get‑stem API to split tracks created on our platform into clean vocal, accompaniment, or per‑instrument stems with state‑of‑the‑art source‑separation AI.
### Usage Guide
* Separate a platform‑generated mix into vocal, instrumental, and individual instrument components.
* Three processing modes are available:
* `separate_vocal` — 2‑stem split (Vocals + Instrumental)
* `split_stem` — up to 12‑stem split
* `split_stem_advanced` — advanced multi‑stem separation with specific instrument selection
* Ideal for karaoke creation, remixes, sample extraction, or detailed post‑production.
* Best results on professionally mixed AI tracks with clear vocal and instrumental layers.
* **Billing notice:** Each call consumes credits; **re‑calling the same track is charged again** (no server‑side caching).
* **Pricing:** Check current per‑call credit costs at [**https://sunoapi.org/billing**](https://sunoapi.org/billing).
### Separation Mode Details
| **Mode (type)** | **Stems Returned** | **Typical Use** | **Credit Cost** |
| :--------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------- | :-------------- |
| `separate_vocal` *(default)* | **2 stems** – Vocals + Instrumental | Quick vocal removal, karaoke, basic remixes | **10 Credits** |
| `split_stem` | **Up to 12 stems** – Vocals, Backing Vocals, Drums, Bass, Guitar, Keyboard, Strings, Brass, Woodwinds, Percussion, Synth, FX/Other | Advanced mixing, remixing, sound design | **50 Credits** |
| `split_stem_advanced` | **Specified instrument stems** — extract specific instruments via `stemName` | Precise instrument extraction, professional post‑production | **20 Credits** |
### Parameter Reference
| **Name** | **Type** | **Required** | **Description** |
| :------------ | :------- | :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `taskId` | string | Conditional | Unique identifier of the music generation task. Should be the taskId returned by the "Generate Music" or "Extend Music" endpoint. **Required when using existing audio.** |
| `audioUrl` | string | Conditional | URL of the audio file uploaded by the user. Maximum file size: 20MB. **Required when using user-uploaded audio.** Cannot be used together with `audioId`. |
| `audioId` | string | Conditional | Unique identifier of the specific audio track to process. This ID is returned in the callback data after music generation completes. **Required when using existing audio.** Cannot be used together with `audioUrl`. |
| `type` | string | Optional | Separation type: `separate_vocal` (default), `split_stem`, or `split_stem_advanced` |
| `stemName` | string | Conditional | Only used when `type` is `split_stem_advanced`, specifies the name of the specific track/instrument to separate. Supported instruments include: Lead Vocal, Drum Kit, Piano, Guitar, Bass, Synth, Percussion, etc. |
| `callBackUrl` | string | Required | URL for receiving vocal separation task completion updates |
### Developer Notes
* All returned audio-file URLs remain accessible for **14 days**.
* Separation quality depends on the complexity and mixing of the original track.
* `separate_vocal` returns **2 stems** — vocals + instrumental.
* `split_stem` returns **up to 12 independent stems** — vocals, backing vocals, drums, bass, guitar, keyboard, strings, brass, woodwinds, percussion, synth, FX/other.
* `split_stem_advanced` returns independent stems for specified instruments. Use the `stemName` parameter to specify the instrument name.
* **Billing:** Every request is charged. Re‑submitting the same track triggers **a new credit deduction** (no server‑side caching).
# Audio Separation Callbacks
Source: https://docs.sunoapi.org/suno-api/separate-vocals-from-music-callbacks
When vocal separation tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Vocal Separation API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Vocal separation task completed successfully
* Vocal separation task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send different format callback data based on the separation type you selected:
```json separate_vocal Type Success Callback theme={null}
{
"code": 200,
"data": {
"task_id": "3e63b4cc88d52611159371f6af5571e7",
"vocal_removal_info": {
"instrumental_url": "https://file.aiquickdraw.com/s/d92a13bf-c6f4-4ade-bb47-f69738435528_Instrumental.mp3",
"origin_url": "",
"vocal_url": "https://file.aiquickdraw.com/s/3d7021c9-fa8b-4eda-91d1-3b9297ddb172_Vocals.mp3"
}
},
"msg": "vocal Removal generated successfully."
}
```
```json split_stem Type Success Callback theme={null}
{
"code": 200,
"data": {
"task_id": "e649edb7abfd759285bd41a47a634b10",
"vocal_removal_info": {
"origin_url": "",
"backing_vocals_url": "https://file.aiquickdraw.com/s/aadc51a3-4c88-4c8e-a4c8-e867c539673d_Backing_Vocals.mp3",
"bass_url": "https://file.aiquickdraw.com/s/a3c2da5a-b364-4422-adb5-2692b9c26d33_Bass.mp3",
"brass_url": "https://file.aiquickdraw.com/s/334b2d23-0c65-4a04-92c7-22f828afdd44_Brass.mp3",
"drums_url": "https://file.aiquickdraw.com/s/ac75c5ea-ac77-4ad2-b7d9-66e140b78e44_Drums.mp3",
"fx_url": "https://file.aiquickdraw.com/s/a8822c73-6629-4089-8f2a-d19f41f0007d_FX.mp3",
"guitar_url": "https://file.aiquickdraw.com/s/064dd08e-d5d2-4201-9058-c5c40fb695b4_Guitar.mp3",
"keyboard_url": "https://file.aiquickdraw.com/s/adc934e0-df7d-45da-8220-1dba160d74e0_Keyboard.mp3",
"percussion_url": "https://file.aiquickdraw.com/s/0f70884d-047c-41f1-a6d0-7044618b7dc6_Percussion.mp3",
"strings_url": "https://file.aiquickdraw.com/s/49829425-a5b0-424e-857a-75d4c63a426b_Strings.mp3",
"synth_url": "https://file.aiquickdraw.com/s/56b2d94a-eb92-4d21-bc43-3460de0c8348_Synth.mp3",
"vocal_url": "https://file.aiquickdraw.com/s/07420749-29a2-4054-9b62-e6a6f8b90ccb_Vocals.mp3",
"woodwinds_url": "https://file.aiquickdraw.com/s/d81545b1-6f94-4388-9785-1aaa6ecabb02_Woodwinds.mp3"
}
},
"msg": "vocal Removal generated successfully."
}
```
````json split_stem_advanced Type Success Callback theme={null}
{
"code": 200,
"msg": "vocal Removal generated successfully.",
"data": {
"task_id": "7220be2955295dda60de46ec6e4ead4c",
"vocal_removal_info": {
"origin_data": [
{
"extract": {
"duration": 194.92,
"audio_url": "https://tempfile.aiquickdraw.com/r/eb7d0f18-8349-4735-a65e-1812705d5ddf_Lead Vocal.mp3",
"stem_type_group_name": "Lead Vocal",
"id": "eb7d0f18-8349-4735-a65e-1812705d5ddf"
},
"remove": {
"duration": 194.92,
"audio_url": "https://tempfile.aiquickdraw.com/r/706d32df-e988-412e-bce4-42c9302e5478_Lead Vocal.mp3",
"stem_type_group_name": "Lead Vocal",
"id": "706d32df-e988-412e-bce4-42c9302e5478"
}
},
{
"extract": {
"duration": 194.92,
"audio_url": "https://tempfile.aiquickdraw.com/r/a7c503f6-1265-4f7e-bf5d-c50fb3b07238_Lead Vocal.mp3",
"stem_type_group_name": "Lead Vocal",
"id": "a7c503f6-1265-4f7e-bf5d-c50fb3b07238"
},
"remove": {
"duration": 194.92,
"audio_url": "https://tempfile.aiquickdraw.com/r/a3a0c954-1980-410f-9b34-8539b8eb23f8_Lead Vocal.mp3",
"stem_type_group_name": "Lead Vocal",
"id": "a3a0c954-1980-410f-9b34-8539b8eb23f8"
}
}
]
}
}
}
```json Failure Callback
{
"code": 400,
"msg": "Vocal separation failed",
"data": {
"task_id": "5e72d367bdfbe44785e28d72cb1697c7",
"vocal_removal_info": null
}
}
````
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------------------ |
| 200 | Success - Vocal separation completed |
| 400 | Bad Request - Parameter error, unsupported audio file format, etc. |
| 451 | Download Failed - Unable to download source audio file |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Task ID, consistent with the taskId returned when you submitted the task
Vocal separation result information, returned on success
## separate\_vocal Type Field Description
Original mixed audio file URL
Instrumental-only audio file URL (vocals removed)
Vocals-only audio file URL (instrumental removed)
## split\_stem Type Field Description
Original mixed audio file URL
Vocals-only audio file URL
Backing vocals audio file URL
Drums audio file URL
Bass audio file URL
Guitar audio file URL
Keyboard audio file URL
Percussion audio file URL
Strings audio file URL
Synthesizer audio file URL
Effects audio file URL
Brass audio file URL
Woodwinds audio file URL
### split\_stem\_advanced Type Field Description
An array of separation results for the original audio, containing extraction and removal information for multiple stem groups. Each element represents an independent stem group (e.g., Lead Vocal).
Information about the extracted target stem (isolates this stem while removing others).
The duration of the extracted audio, in seconds.
The download URL of the extracted target stem audio file.
The stem type group name (e.g., Lead Vocal), indicating which type of stem this group extracts.
The unique identifier for the extracted audio.
Information about the remaining audio after removing the target stem (removes this stem while keeping others).
The duration of the audio after removal, in seconds.
The download URL of the remaining audio file after the target stem has been removed.
The stem type group name (e.g., Lead Vocal), consistent with the corresponding extract entry.
The unique identifier for the remaining audio.
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/vocal-separation-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received vocal separation callback:', {
taskId: data.task_id,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Vocal separation completed');
const vocalInfo = data.vocal_removal_info;
if (vocalInfo) {
console.log('Separation results:');
console.log(` Original audio: ${vocalInfo.origin_url}`);
// Handle different separation types
if (vocalInfo.instrumental_url) {
// separate_vocal type
console.log(` Instrumental only: ${vocalInfo.instrumental_url}`);
console.log(` Vocals only: ${vocalInfo.vocal_url}`);
} else {
// split_stem type
console.log(` Vocals: ${vocalInfo.vocal_url}`);
console.log(` Backing vocals: ${vocalInfo.backing_vocals_url}`);
console.log(` Drums: ${vocalInfo.drums_url}`);
console.log(` Bass: ${vocalInfo.bass_url}`);
console.log(` Guitar: ${vocalInfo.guitar_url}`);
console.log(` Keyboard: ${vocalInfo.keyboard_url}`);
console.log(` Percussion: ${vocalInfo.percussion_url}`);
console.log(` Strings: ${vocalInfo.strings_url}`);
console.log(` Synthesizer: ${vocalInfo.synth_url}`);
console.log(` Effects: ${vocalInfo.fx_url}`);
console.log(` Brass: ${vocalInfo.brass_url}`);
console.log(` Woodwinds: ${vocalInfo.woodwinds_url}`);
}
// Download separated audio files
const https = require('https');
const fs = require('fs');
const downloadFile = (url, filename) => {
if (!url) return;
const file = fs.createWriteStream(filename);
https.get(url, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
console.log(`Saved: ${filename}`);
});
}).on('error', (err) => {
console.error(`Download failed ${filename}:`, err.message);
});
};
// Download all available audio files
Object.keys(vocalInfo).forEach(key => {
if (vocalInfo[key] && key.endsWith('_url')) {
const filename = `${data.task_id}_${key.replace('_url', '')}.mp3`;
downloadFile(vocalInfo[key], filename);
}
});
}
} else {
// Task failed
console.log('Vocal separation failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or unsupported audio format');
} else if (code === 451) {
console.log('Source audio file download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/vocal-separation-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
vocal_info = callback_data.get('vocal_removal_info')
print(f"Received vocal separation callback: {task_id}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Vocal separation completed")
if vocal_info:
print("Separation results:")
print(f" Original audio: {vocal_info.get('origin_url')}")
# Handle different separation types
if vocal_info.get('instrumental_url'):
# separate_vocal type
print(f" Instrumental only: {vocal_info.get('instrumental_url')}")
print(f" Vocals only: {vocal_info.get('vocal_url')}")
else:
# split_stem type
print(f" Vocals: {vocal_info.get('vocal_url')}")
print(f" Backing vocals: {vocal_info.get('backing_vocals_url')}")
print(f" Drums: {vocal_info.get('drums_url')}")
print(f" Bass: {vocal_info.get('bass_url')}")
print(f" Guitar: {vocal_info.get('guitar_url')}")
print(f" Keyboard: {vocal_info.get('keyboard_url')}")
print(f" Percussion: {vocal_info.get('percussion_url')}")
print(f" Strings: {vocal_info.get('strings_url')}")
print(f" Synthesizer: {vocal_info.get('synth_url')}")
print(f" Effects: {vocal_info.get('fx_url')}")
print(f" Brass: {vocal_info.get('brass_url')}")
print(f" Woodwinds: {vocal_info.get('woodwinds_url')}")
# Download separated audio files
def download_file(url, filename):
if not url:
return
try:
response = requests.get(url)
if response.status_code == 200:
with open(filename, "wb") as f:
f.write(response.content)
print(f"Saved: {filename}")
except Exception as e:
print(f"Download failed {filename}: {e}")
# Download all available audio files
for key, url in vocal_info.items():
if url and key.endswith('_url'):
filename = f"{task_id}_{key.replace('_url', '')}.mp3"
download_file(url, filename)
else:
# Task failed
print(f"Vocal separation failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or unsupported audio format")
elif code == 451:
print("Source audio file download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
getMessage());
}
}
// Download all available audio files
foreach ($vocalInfo as $key => $url) {
if ($url && strpos($key, '_url') !== false) {
$filename = $taskId . '_' . str_replace('_url', '', $key) . '.mp3';
downloadFile($url, $filename);
}
}
}
} else {
// Task failed
error_log("Vocal separation failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or unsupported audio format");
} elseif ($code === 451) {
error_log("Source audio file download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **File Management**: Separated audio file download and processing should be done in asynchronous tasks
7. **Type Detection**: Determine separation type based on returned fields and apply corresponding processing logic
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio file URLs may have time limits, recommend downloading and saving promptly
* split\_stem mode produces more files, pay attention to storage space management
* Ensure source audio file contains corresponding musical components for optimal separation results
* Different separation types have different callback structures, requiring appropriate processing logic
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Ensure proper handling of different separation type data structures
* Confirm that separated audio file URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note how source audio file quality affects separation results
* Confirm source audio file format is supported
* split\_stem mode requires checking more audio files
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get vocal separation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Suno Voice Check Availability
Source: https://docs.sunoapi.org/suno-api/suno-voice-check-voice
suno-api/suno-voice-api.json POST /api/v1/voice/check-voice
Check whether a generated Suno custom voice is available for use.
### Usage Guide
* Use this endpoint after the custom voice generation task succeeds.
* Submit the related task ID in `task_id`.
* If `isAvailable` is `true`, the generated voice is ready for supported Suno generation workflows.
### When to Use
Call this endpoint before starting a generation request that depends on a custom voice. It helps avoid submitting downstream tasks while the voice is still unavailable.
### Related Endpoint
Query the latest task status and generated voice information before checking availability
# Suno Voice Create Custom Voice
Source: https://docs.sunoapi.org/suno-api/suno-voice-generate
suno-api/suno-voice-api.json POST /api/v1/voice/generate
Generate a reusable Suno custom voice from the user's verification recording.
### Usage Guide
* Call this API after the validation phrase is generated and the user has recorded the verification audio.
* The validation phrase is the `validateInfo` text returned by the server. For best voice generation results, have the user record the server-provided phrase in a singing voice rather than plain speech.
* Submit the original validation `taskId` and the verification audio URL in `verifyUrl`.
* Optional metadata such as `voiceName`, `description`, `style`, and `singerSkillLevel` helps organize and tune the generated voice.
* The API returns a `taskId`; use it to query the final `voiceId`.
* When `callBackUrl` is provided, the system sends a POST callback when the voice is created or the task fails. The callback URL must be publicly accessible and return HTTP 200 within 15 seconds.
### Workflow
1. Generate and retrieve the validation phrase.
2. Record clear verification audio for the phrase; singing is recommended for best voice generation results.
3. Upload or host the verification audio and pass the URL as `verifyUrl`.
4. Submit the voice generation task and store the returned `taskId`.
5. Receive `voiceId` through the record query API or callback when the task succeeds.
### Callback
Learn the callback payload sent when the custom voice is created or the task fails
### Developer Notes
* `taskId` must come from the validation phrase task for the same voice workflow.
* `verifyUrl` should point to the user's recording of the exact validation phrase returned by the server; for best results, recording it in a singing voice is recommended.
* After receiving `voiceId`, use the availability check endpoint before starting generation workflows that depend on the custom voice.
# Suno Voice Generation Callbacks
Source: https://docs.sunoapi.org/suno-api/suno-voice-generate-callbacks
Receive POST callbacks when a Suno Voice custom voice task succeeds or fails.
When you submit a custom voice generation task with `callBackUrl`, the system sends a POST request to your callback URL when the task completes.
## Callback Mechanism Overview
The callback contains the generated `voiceId` when custom voice creation succeeds.
### Callback Timing
* Custom voice created successfully
* Voice verification or creation failed
* Error occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout**: 15 seconds
## Callback Request Format
```json Custom Voice Ready Callback theme={null}
{
"code": 200,
"msg": "success",
"data": {
"taskId": "xxx_task_id_xxx",
"voiceId": "voice_xxx",
"status": "success",
"errorCode": 0,
"errorMessage": ""
}
}
```
```json Custom Voice Failed Callback theme={null}
{
"code": 400,
"msg": "Voice generation failed",
"data": {
"taskId": "xxx_task_id_xxx",
"voiceId": "",
"status": "fail",
"errorCode": 500,
"errorMessage": "Verification audio did not match the validation phrase"
}
}
```
## Field Description
Callback status code. `200` indicates success; non-200 values indicate task failure or processing error.
Status message describing the callback result.
Task ID returned by the custom voice generation API.
Generated custom voice ID. Returned when `status` is `success`.
Task status. Common callback statuses are `success`, `processing_validate_fail`, and `fail`.
Error code returned when the task fails.
Detailed error message returned when the task fails.
## Receiving Callbacks
```javascript Node.js theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/suno/voice-generate-callback', (req, res) => {
const { code, msg, data } = req.body;
if (code === 200 && data.status === 'success') {
console.log('Custom voice ready:', data.voiceId);
} else {
console.error('Custom voice task failed:', msg, data.errorMessage);
}
res.status(200).json({ status: 'received' });
});
app.listen(3000);
```
## Related Endpoint
Query the same voice generation task manually with taskId
# Suno Voice Get Custom Voice Record
Source: https://docs.sunoapi.org/suno-api/suno-voice-record-info
suno-api/suno-voice-api.json GET /api/v1/voice/record-info
Query the custom Suno Voice generation result and obtain the generated voiceId.
### Usage Guide
* Use the `taskId` returned by the custom voice generation API.
* When `status` is `success`, the response contains the generated `voiceId`.
* If the task fails, use `errorCode` and `errorMessage` to decide whether to retry validation or generation.
### Status Handling
| Status | Meaning |
| -------------------------- | ---------------------------------------- |
| `wait_processing` | Task is waiting to be processed |
| `processing_validate` | Verification is being processed |
| `processing_validate_fail` | Verification failed |
| `wait_validating` | Waiting for validation to complete |
| `success` | Voice is ready and `voiceId` can be used |
| `fail` | Task failed |
### Related Endpoint
Confirm whether the generated custom voice is available for supported Suno generation APIs
# Suno Voice Regenerate Verification Phrase
Source: https://docs.sunoapi.org/suno-api/suno-voice-regenerate
suno-api/suno-voice-api.json POST /api/v1/voice/regenerate
Regenerate the validation phrase for an existing Suno Voice task.
### Usage Guide
* Use this API when the previous validation phrase failed, expired, or the user needs a new phrase.
* Submit the existing `taskId` from the voice validation workflow.
* The API schema uses `calBackUrl` for the callback URL field. The system sends a POST callback when the regenerated phrase is ready or the task fails. The callback URL must be publicly accessible and return HTTP 200 within 15 seconds.
* Query the validation phrase result again with the returned `taskId`.
### Workflow
1. Submit the existing validation task ID.
2. Store the returned `taskId`.
3. Wait for the regenerated `validateInfo` through the query API or callback.
4. Ask the user to record the new phrase and submit the verification audio to the voice generation API. For best voice generation results, singing is recommended.
### Callback
Learn the callback payload sent when the regenerated phrase is ready or the task fails
### Developer Notes
* Keep the regenerated phrase and verification recording paired with the same task flow.
* If phrase generation repeatedly fails, choose a cleaner source vocal segment and restart the validation step.
# Suno Voice Regenerate Phrase Callbacks
Source: https://docs.sunoapi.org/suno-api/suno-voice-regenerate-callbacks
Receive POST callbacks when a regenerated Suno Voice validation phrase is ready or fails.
When you submit a phrase regeneration task, provide the callback URL using the `calBackUrl` field from the API schema. The system sends a POST request when the regenerated phrase is ready or the task fails.
## Callback Mechanism Overview
The regenerated phrase callback uses the same response shape as validation phrase generation callbacks.
### Callback Timing
* New validation phrase generated and ready for the user to record
* Phrase regeneration failed
* Error occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout**: 15 seconds
## Callback Request Format
```json Regenerated Phrase Ready Callback theme={null}
{
"code": 200,
"msg": "success",
"data": {
"taskId": "xxx_task_id_xxx",
"validateInfo": "Please record this new validation phrase clearly.",
"status": "wait_validating",
"errorCode": 0,
"errorMessage": ""
}
}
```
```json Regenerated Phrase Failed Callback theme={null}
{
"code": 400,
"msg": "Validation phrase regeneration failed",
"data": {
"taskId": "xxx_task_id_xxx",
"validateInfo": "",
"status": "processing_validate_fail",
"errorCode": 500,
"errorMessage": "Failed to regenerate validation phrase"
}
}
```
## Field Description
Callback status code. `200` indicates success; non-200 values indicate task failure or processing error.
Status message describing the callback result.
Task ID returned by the phrase regeneration API.
Regenerated validation phrase text. Returned when `status` is `wait_validating`.
Task status. Common callback statuses are `wait_validating`, `processing_validate_fail`, and `fail`.
Error code returned when the task fails.
Detailed error message returned when the task fails.
## Related Endpoint
Query the regenerated phrase manually with taskId
# Suno Voice Generate Verification Phrase
Source: https://docs.sunoapi.org/suno-api/suno-voice-validate
suno-api/suno-voice-api.json POST /api/v1/voice/validate
Generate the validation phrase required for the Suno Voice custom voice workflow.
### Usage Guide
* Submit the source recording URL and the vocal segment you want to use for voice creation.
* The API returns a `taskId`; use it to query the generated validation phrase.
* When `callBackUrl` is provided, the system sends a POST callback when the phrase is ready or the task fails. The callback URL must be publicly accessible and return HTTP 200 within 15 seconds.
* After receiving `validateInfo`, ask the user to record the phrase and upload the verification audio to the voice generation API. For best voice generation results, singing is recommended.
### Workflow
1. Upload or host the source audio and make sure `voiceUrl` is publicly accessible.
2. Choose a clean vocal segment with `vocalStartS` and `vocalEndS`.
3. Submit the validation phrase task and store the returned `taskId`.
4. Wait for `validateInfo` through the query API or callback.
5. Record the user performing the validation phrase, then call the custom voice generation API. For best voice generation results, singing is recommended.
### Callback
Learn the callback payload sent when the validation phrase is ready or the task fails
### Developer Notes
* `vocalEndS` must be greater than `vocalStartS`.
* Use a segment with clear speech and minimal background noise for better validation.
* `language` controls the validation phrase language. Supported values include `en`, `zh`, `es`, `fr`, `pt`, `de`, `ja`, `ko`, `hi`, and `ru`.
# Suno Voice Validation Phrase Callbacks
Source: https://docs.sunoapi.org/suno-api/suno-voice-validate-callbacks
Receive POST callbacks when a Suno Voice validation phrase task is ready or fails.
When you submit a validation phrase task with `callBackUrl`, the system sends a POST request to your callback URL after the validation phrase task reaches a terminal state.
## Callback Mechanism Overview
Use callbacks in production to avoid polling the validation phrase query endpoint.
### Callback Timing
* Validation phrase generated and ready for the user to record
* Validation phrase generation failed
* Error occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout**: 15 seconds
## Callback Request Format
```json Validation Phrase Ready Callback theme={null}
{
"code": 200,
"msg": "success",
"data": {
"taskId": "xxx_task_id_xxx",
"validateInfo": "Please record this validation phrase clearly.",
"status": "wait_validating",
"errorCode": 0,
"errorMessage": ""
}
}
```
```json Validation Phrase Failed Callback theme={null}
{
"code": 400,
"msg": "Validation phrase generation failed",
"data": {
"taskId": "xxx_task_id_xxx",
"validateInfo": "",
"status": "processing_validate_fail",
"errorCode": 500,
"errorMessage": "Failed to generate validation phrase"
}
}
```
## Field Description
Callback status code. `200` indicates success; non-200 values indicate task failure or processing error.
Status message describing the callback result.
Task ID returned by the validation phrase generation API.
Validation phrase text. Returned when `status` is `wait_validating`.
Task status. Common callback statuses are `wait_validating`, `processing_validate_fail`, and `fail`.
Error code returned when the task fails.
Detailed error message returned when the task fails.
## Receiving Callbacks
```javascript Node.js theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/suno/voice-validate-callback', (req, res) => {
const { code, msg, data } = req.body;
if (code === 200 && data.status === 'wait_validating') {
console.log('Validation phrase ready:', data.taskId, data.validateInfo);
} else {
console.error('Validation phrase task failed:', msg, data.errorMessage);
}
res.status(200).json({ status: 'received' });
});
app.listen(3000);
```
## Related Endpoint
Query the same task status manually with taskId
# Suno Voice Get Verification Phrase
Source: https://docs.sunoapi.org/suno-api/suno-voice-validate-info
suno-api/suno-voice-api.json GET /api/v1/voice/validate-info
Query the validation phrase generation result for a Suno Voice task.
### Usage Guide
* Use the `taskId` returned by the validation phrase generation or regeneration API.
* When the task reaches `wait_validating`, read `validateInfo` and ask the user to record that phrase.
* If the task fails, inspect `errorCode` and `errorMessage` before retrying.
### Status Handling
| Status | Meaning |
| -------------------------- | ------------------------------------------------- |
| `wait_processing` | Task is waiting to be processed |
| `processing_validate` | Validation phrase is being generated |
| `processing_validate_fail` | Validation phrase generation failed |
| `wait_validating` | Phrase is ready and waiting for user verification |
| `success` | The full voice creation flow has completed |
| `fail` | Task failed |
### Next Step
Submit the verification audio and create the final custom voice
# Upload And Cover Audio
Source: https://docs.sunoapi.org/suno-api/upload-and-cover-audio
suno-api/suno-api.json POST /api/v1/generate/upload-cover
This API covers an audio track by transforming it into a new style while retaining its core melody. It incorporates Suno's upload capability, enabling users to upload an audio file for processing. The expected result is a refreshed audio track with a new style, keeping the original melody intact.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Parameter Usage Guide
* When customMode is true (Custom Mode):
* If instrumental is true: style, title and uploadUrl are required
* If instrumental is false: style, prompt, title and uploadUrl are required
* **Character limits (based on model):**
* **V4 model (Deprecated)**: prompt max 3000 characters, style max 200 characters, title max 80 characters
* **V4\_5, V4\_5PLUS, V5, V5\_5 & V4\_5ALL models (Deprecated)**: prompt max 5000 characters, style max 1000 characters; title max 80 characters for V4\_5ALL, otherwise max 100 characters
* **V6, V6\_WILD & V6\_MINI models**: prompt max 5000 characters, style max 1000 characters, title max 100 characters
* **model** (string, required): `V6`, `V6_WILD`, `V6_MINI`. Deprecated: `V4_5ALL`, `V4`, `V4_5`, `V4_5PLUS`, `V5`, `V5_5`.
* uploadUrl is used to specify the upload location of the audio file; ensure the uploaded audio does not exceed 8 minutes in length.
* When customMode is false (Non-custom Mode):
* Only prompt and uploadUrl are required regardless of instrumental setting
* prompt length limit: 500 characters
* Other parameters should be left empty
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Preferred vocal gender. Allowed values: `m` (male), `f` (female)
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* personaId (string): Persona ID or Suno Voice `voiceId` to apply in Custom Mode. If you use a Voice-generated ID, set `personaModel` to `voice_persona`.
* personaModel (string): Persona type. Use `style_persona` for Generate Persona IDs, or `voice_persona` for Suno Voice IDs.
```json JSON body theme={null}
{
"customMode": true,
"instrumental": false,
"prompt": "Cover with a darker cinematic vibe",
"style": "Cinematic",
"title": "Dark Reprise",
"uploadUrl": "https://storage.example.com/upload",
"model": "V6",
"callBackUrl": "https://example.com/callback",
"vocalGender": "m",
"styleWeight": 0.61,
"weirdnessConstraint": 0.72,
"audioWeight": 0.65
}
```
### Developer Notes
1. Recommended settings for new users: Set customMode to false, instrumental to false, and only provide prompt and uploadUrl. This is the simplest configuration to quickly test the API and experience the results.
2. Generated files will be deleted after 15 days
3. Ensure all required parameters are provided based on customMode and instrumental settings to avoid errors
4. Pay attention to character limits for prompt, style, and title to ensure successful processing
5. Callback process has three stages: text (text generation complete), first (first track complete), complete (all tracks complete)
6. You can use the Get Music Generation Details endpoint to actively check task status instead of waiting for callbacks
7. The uploadUrl parameter is used to specify the upload location of the audio file; please provide a valid URL.
# Upload and Cover Audio Callbacks
Source: https://docs.sunoapi.org/suno-api/upload-and-cover-audio-callbacks
When upload and cover audio tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Upload and Cover Audio API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Audio covering task completed successfully
* Audio covering task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v3-5",
"title": "Iron Man",
"tags": "electrifying, rock",
"createTime": "2025-01-01 00:00:00",
"duration": 228.28
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Audio covering failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------- |
| 200 | Success - Audio covering completed |
| 400 | Bad Request - Parameter error, unsupported audio file format, content violation, etc. |
| 451 | Download Failed - Unable to download source audio file |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First music track completed
* `complete`: All music tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Audio covering result information, returned on success
Music unique identifier
Covered audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming audio URL
Original streaming audio URL
Cover image URL
Original cover image URL
Generation prompt/lyrics
Model name used
Music title
Music tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/upload-cover-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received audio covering callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Audio covering completed');
const musicData = data.data || [];
console.log(`Covered ${musicData.length} music tracks:`);
musicData.forEach((music, index) => {
console.log(`Covered music ${index + 1}:`);
console.log(` Title: ${music.title}`);
console.log(` Duration: ${music.duration} seconds`);
console.log(` Style tags: ${music.tags}`);
console.log(` Covered audio URL: ${music.audio_url}`);
console.log(` Cover URL: ${music.image_url}`);
});
// Process covered music
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Audio covering failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('Source audio file download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/upload-cover-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
music_data = callback_data.get('data', [])
print(f"Received audio covering callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Audio covering completed")
print(f"Covered {len(music_data)} music tracks:")
for i, music in enumerate(music_data):
print(f"Covered music {i + 1}:")
print(f" Title: {music.get('title')}")
print(f" Duration: {music.get('duration')} seconds")
print(f" Style tags: {music.get('tags')}")
print(f" Covered audio URL: {music.get('audio_url')}")
print(f" Cover URL: {music.get('image_url')}")
# Download covered audio file example
try:
audio_url = music.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"covered_music_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Covered audio saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Audio covering failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("Source audio file download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$music) {
error_log("Covered music " . ($index + 1) . ":");
error_log(" Title: " . ($music['title'] ?? ''));
error_log(" Duration: " . ($music['duration'] ?? 0) . " seconds");
error_log(" Style tags: " . ($music['tags'] ?? ''));
error_log(" Covered audio URL: " . ($music['audio_url'] ?? ''));
error_log(" Cover URL: " . ($music['image_url'] ?? ''));
// Download covered audio file example
try {
$audioUrl = $music['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "covered_music_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Covered audio saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Audio covering failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("Source audio file download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
* Ensure uploaded audio file format is supported
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
* Confirm source audio file format is supported
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.
# Upload And Extend Audio
Source: https://docs.sunoapi.org/suno-api/upload-and-extend-audio
suno-api/suno-api.json POST /api/v1/generate/upload-extend
This API extends audio tracks while preserving the original style of the audio track. It includes Suno's upload functionality, allowing users to upload audio files for processing. The expected result is a longer track that seamlessly continues the input style.
### Model Versions
* **Current models**: `V6` (default), `V6_WILD`, `V6_MINI`
* **Deprecated models**: `V5_5`, `V5`, `V4_5PLUS`, `V4_5ALL`, `V4_5`, `V4`
* Deprecated values remain available only for backward compatibility. New integrations should use a V6-series model.
### Parameter Usage Guide
* instrumental (boolean, optional) determines whether to generate instrumental music and defaults to false.
* prompt is optional in all modes and for all instrumental values.
* When defaultParamFlag is true (Custom Parameters):
* If instrumental is true: only style, title, and uploadUrl are required; prompt and vocalGender are optional.
* If instrumental is false: only style, title, and uploadUrl are required. prompt is optional and is used as the prompt when provided; vocalGender is optional.
* **Character limits (based on model):**
* **V4 model (Deprecated)**: prompt max 3000 characters, style max 200 characters, title max 80 characters
* **V4\_5, V4\_5PLUS, V5, V5\_5 & V4\_5ALL models (Deprecated)**: prompt max 5000 characters, style max 1000 characters; title max 80 characters for V4\_5ALL, otherwise max 100 characters
* **V6, V6\_WILD & V6\_MINI models**: prompt max 5000 characters, style max 1000 characters, title max 100 characters
* **model** (string, required): `V6`, `V6_WILD`, `V6_MINI`. Deprecated: `V4_5ALL`, `V4`, `V4_5`, `V4_5PLUS`, `V5`, `V5_5`.
* continueAt: the time point in seconds from which to start extending (must be greater than 0 and less than the uploaded audio duration)
* uploadUrl: specifies the upload location for audio files; ensure uploaded audio does not exceed 8 minutes.
* When defaultParamFlag is false (Default Parameters):
* Only uploadUrl is required
* prompt is optional
* If instrumental is false, lyrics will be generated automatically
* Other parameters will use the original audio's parameters
### Optional parameters
The following fields are optional controls available for this endpoint:
* vocalGender (string): Optional and not required whether instrumental is true or false. Allowed values: `m` (male), `f` (female).
* styleWeight (number): Style adherence weight in range 0–1 (recommended two decimals)
* weirdnessConstraint (number): Creativity/novelty constraint in range 0–1 (recommended two decimals)
* audioWeight (number): Relative weight of audio consistency in range 0–1 (recommended two decimals)
* personaId (string): Persona ID or Suno Voice `voiceId` to apply when using custom parameters. If you use a Voice-generated ID, set `personaModel` to `voice_persona`.
* personaModel (string): Persona type. Use `style_persona` for Generate Persona IDs, or `voice_persona` for Suno Voice IDs.
```json JSON body theme={null}
{
"defaultParamFlag": true,
"instrumental": false,
"prompt": "Extend with brighter chorus and outro",
"style": "Electropop",
"title": "Shimmer (Extended)",
"continueAt": 45,
"uploadUrl": "https://storage.example.com/upload",
"model": "V6",
"callBackUrl": "https://example.com/callback",
"styleWeight": 0.61,
"weirdnessConstraint": 0.72,
"audioWeight": 0.65
}
```
### Developer Notes
1. Generated files will be retained for 14 days
2. Model version must be consistent with the source music
3. This feature is ideal for creating longer works by extending existing music
4. Pay attention to character limits for prompt, style, and title to ensure successful processing
5. uploadUrl parameter specifies the upload location for audio files; provide a valid URL.
# Upload and Extend Audio Callbacks
Source: https://docs.sunoapi.org/suno-api/upload-and-extend-audio-callbacks
When upload and extend audio tasks are completed, the system will send results to your provided callback URL via POST request
When you submit a task to the Upload and Extend Audio API, you can use the `callBackUrl` parameter to set a callback URL. When the task is completed, the system will automatically push the results to your specified address.
## Callback Mechanism Overview
The callback mechanism eliminates the need to poll the API for task status. The system will proactively push task completion results to your server.
### Callback Timing
The system will send callback notifications in the following situations:
* Audio extension task completed successfully
* Audio extension task failed
* Errors occurred during task processing
### Callback Method
* **HTTP Method**: POST
* **Content Type**: application/json
* **Timeout Setting**: 15 seconds
## Callback Request Format
When the task is completed, the system will send a POST request to your `callBackUrl` in the following format:
```json Success Callback theme={null}
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "8551****662c",
"audio_url": "https://example.cn/****.mp3",
"source_audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"source_stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"source_image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v3-5",
"title": "Iron Man",
"tags": "electrifying, rock",
"createTime": "2025-01-01 00:00:00",
"duration": 198.44
}
]
}
}
```
```json Failure Callback theme={null}
{
"code": 400,
"msg": "Audio extension failed",
"data": {
"callbackType": "error",
"task_id": "2fac****9f72",
"data": null
}
}
```
## Status Code Description
Callback status code indicating task processing result:
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------- |
| 200 | Success - Audio extension completed |
| 400 | Bad Request - Parameter error, unsupported audio file format, content violation, etc. |
| 451 | Download Failed - Unable to download source audio file |
| 500 | Server Error - Please try again later |
Status message providing detailed status description
Callback type indicating the current callback stage:
* `text`: Text generation completed
* `first`: First music track completed
* `complete`: All music tracks completed
* `error`: Task failed
Task ID, consistent with the taskId returned when you submitted the task
Audio extension result information, returned on success
Music unique identifier
Extended audio file URL
**Deprecated.** Original audio file link returned by Suno. This link expires after a period of time and is no longer maintained — do not rely on it for long-term storage. Use the [Recovery Audio](/suno-api/recovery-audio) endpoint to obtain a fresh playable link.
Streaming audio URL
Original streaming audio URL
Cover image URL
Original cover image URL
Generation prompt/lyrics
Model name used
Music title
Music tags
Creation time
Audio duration (seconds)
## Callback Reception Examples
Here are example codes for receiving callbacks in popular programming languages:
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/upload-extend-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Received audio extension callback:', {
taskId: data.task_id,
callbackType: data.callbackType,
status: code,
message: msg
});
if (code === 200) {
// Task completed successfully
console.log('Audio extension completed');
const musicData = data.data || [];
console.log(`Extended ${musicData.length} music tracks:`);
musicData.forEach((music, index) => {
console.log(`Extended music ${index + 1}:`);
console.log(` Title: ${music.title}`);
console.log(` Duration: ${music.duration} seconds`);
console.log(` Style tags: ${music.tags}`);
console.log(` Extended audio URL: ${music.audio_url}`);
console.log(` Cover URL: ${music.image_url}`);
});
// Process extended music
// Can download audio files, save locally, etc.
} else {
// Task failed
console.log('Audio extension failed:', msg);
// Handle failure cases...
if (code === 400) {
console.log('Parameter error or content violation');
} else if (code === 451) {
console.log('Source audio file download failed');
} else if (code === 500) {
console.log('Server internal error');
}
}
// Return 200 status code to confirm callback received
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});
```
```python theme={null}
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/upload-extend-callback', methods=['POST'])
def handle_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
task_id = callback_data.get('task_id')
callback_type = callback_data.get('callbackType')
music_data = callback_data.get('data', [])
print(f"Received audio extension callback: {task_id}, type: {callback_type}, status: {code}, message: {msg}")
if code == 200:
# Task completed successfully
print("Audio extension completed")
print(f"Extended {len(music_data)} music tracks:")
for i, music in enumerate(music_data):
print(f"Extended music {i + 1}:")
print(f" Title: {music.get('title')}")
print(f" Duration: {music.get('duration')} seconds")
print(f" Style tags: {music.get('tags')}")
print(f" Extended audio URL: {music.get('audio_url')}")
print(f" Cover URL: {music.get('image_url')}")
# Download extended audio file example
try:
audio_url = music.get('audio_url')
if audio_url:
response = requests.get(audio_url)
if response.status_code == 200:
filename = f"extended_music_{task_id}_{i + 1}.mp3"
with open(filename, "wb") as f:
f.write(response.content)
print(f"Extended audio saved as {filename}")
except Exception as e:
print(f"Audio download failed: {e}")
else:
# Task failed
print(f"Audio extension failed: {msg}")
# Handle failure cases...
if code == 400:
print("Parameter error or content violation")
elif code == 451:
print("Source audio file download failed")
elif code == 500:
print("Server internal error")
# Return 200 status code to confirm callback received
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
```
```php theme={null}
$music) {
error_log("Extended music " . ($index + 1) . ":");
error_log(" Title: " . ($music['title'] ?? ''));
error_log(" Duration: " . ($music['duration'] ?? 0) . " seconds");
error_log(" Style tags: " . ($music['tags'] ?? ''));
error_log(" Extended audio URL: " . ($music['audio_url'] ?? ''));
error_log(" Cover URL: " . ($music['image_url'] ?? ''));
// Download extended audio file example
try {
$audioUrl = $music['audio_url'] ?? '';
if ($audioUrl) {
$audioContent = file_get_contents($audioUrl);
if ($audioContent !== false) {
$filename = "extended_music_{$taskId}_" . ($index + 1) . ".mp3";
file_put_contents($filename, $audioContent);
error_log("Extended audio saved as $filename");
}
}
} catch (Exception $e) {
error_log("Audio download failed: " . $e->getMessage());
}
}
} else {
// Task failed
error_log("Audio extension failed: $msg");
// Handle failure cases...
if ($code === 400) {
error_log("Parameter error or content violation");
} elseif ($code === 451) {
error_log("Source audio file download failed");
} elseif ($code === 500) {
error_log("Server internal error");
}
}
// Return 200 status code to confirm callback received
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
```
## Best Practices
### Callback URL Configuration Recommendations
1. **Use HTTPS**: Ensure your callback URL uses HTTPS protocol for secure data transmission
2. **Verify Source**: Verify the legitimacy of the request source in callback processing
3. **Idempotent Processing**: The same taskId may receive multiple callbacks, ensure processing logic is idempotent
4. **Quick Response**: Callback processing should return a 200 status code as quickly as possible to avoid timeout
5. **Asynchronous Processing**: Complex business logic should be processed asynchronously to avoid blocking callback response
6. **Audio Processing**: Audio download and processing should be done in asynchronous tasks to avoid blocking callback response
### Important Reminders
* Callback URL must be a publicly accessible address
* Server must respond within 15 seconds, otherwise it will be considered a timeout
* If 3 consecutive retries fail, the system will stop sending callbacks
* Please ensure the stability of callback processing logic to avoid callback failures due to exceptions
* Generated audio URLs may have time limits, recommend downloading and saving promptly
* Pay attention to content policy compliance to avoid generation failures due to policy violations
* Ensure uploaded audio file format is supported
## Troubleshooting
If you do not receive callback notifications, please check the following:
* Confirm that the callback URL is accessible from the public network
* Check firewall settings to ensure inbound requests are not blocked
* Verify that domain name resolution is correct
* Ensure the server returns HTTP 200 status code within 15 seconds
* Check server logs for error messages
* Verify that the interface path and HTTP method are correct
* Confirm that the received POST request body is in JSON format
* Check that Content-Type is application/json
* Verify that JSON parsing is correct
* Confirm that audio URLs are accessible
* Check audio download permissions and network connections
* Verify audio save paths and permissions
* Note whether audio content complies with content policies
* Confirm source audio file format is supported
## Alternative Solution
If you cannot use the callback mechanism, you can also use polling:
Use the get music generation details endpoint to regularly query task status. We recommend querying every 30 seconds.