> ## Documentation Index
> Fetch the complete documentation index at: https://docs.api.box/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Get started with Suno API to generate AI music, lyrics, and audio content in minutes

## Welcome to Suno API

Suno API enables you to create high-quality AI-generated music, lyrics, and audio content using state-of-the-art AI models. Whether you're building music applications, automating creative workflows, or developing audio content, our API provides comprehensive tools for music generation and audio processing.

<CardGroup cols={3}>
  <Card title="Generate Music" icon="wand-magic-sparkles" href="/suno-api/generate-music">
    Create original music tracks with or without lyrics
  </Card>

  <Card title="Extend Music" icon="plus" href="/suno-api/extend-music">
    Seamlessly extend existing music tracks
  </Card>

  <Card title="Generate Lyrics" icon="list-check" href="/suno-api/generate-lyrics">
    Create creative lyrics from text prompts
  </Card>

  <Card title="Music Video" icon="video" href="/suno-api/create-music-video">
    Convert audio tracks to visualized music videos
  </Card>

  <Card title="Upload & Cover" icon="upload" href="/suno-api/upload-and-cover-audio">
    Transform uploaded audio into new styles
  </Card>

  <Card title="Upload & Extend" icon="arrow-up-right-from-square" href="/suno-api/upload-and-extend-audio">
    Upload audio files and seamlessly extend them
  </Card>

  <Card title="Vocal Separation" icon="wave-sine" href="/suno-api/separate-vocals-from-music">
    Separate vocals and instrumentals from music
  </Card>

  <Card title="WAV Conversion" icon="file-audio" href="/suno-api/convert-to-wav-format">
    Convert audio to high-quality WAV format
  </Card>

  <Card title="Get Lyrics" icon="align-left" href="/suno-api/get-timestamped-lyrics">
    Retrieve timestamped synchronized lyrics
  </Card>

  <Card title="Add Instrumental" icon="music" href="/suno-api/add-instrumental">
    Add instrumental elements to existing audio tracks
  </Card>

  <Card title="Add Vocals" icon="microphone" href="/suno-api/add-vocals">
    Generate vocal tracks for instrumental music
  </Card>

  <Card title="Boost Music Style" icon="sparkles" href="/suno-api/boost-music-style">
    Enhance style descriptions with V4\_5 conversational prompts
  </Card>
</CardGroup>

## Authentication

All API requests require authentication using Bearer tokens. Please obtain your API key from the [API Key Management Page](https://api.box/api-key).

<Warning>
  Keep your API key secure and never share it publicly. If you suspect your key has been compromised, reset it immediately.
</Warning>

### API Base URL

```
https://apibox.erweima.ai
```

### Authentication Header

```http theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Quick Start Guide

### Step 1: Generate Your First Music Track

Start with a simple music generation request:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://apibox.erweima.ai/api/v1/generate" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "A peaceful and soothing piano piece with soft melodies",
      "customMode": false,
      "instrumental": true,
      "model": "V4_5ALL",
      "callBackUrl": "https://your-app.com/callback",
      "vocalGender": "m",
      "styleWeight": 0.65,
      "weirdnessConstraint": 0.3,
      "audioWeight": 0.7
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://apibox.erweima.ai/api/v1/generate', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      prompt: 'A peaceful and soothing piano piece with soft melodies',
      customMode: false,
      instrumental: true,
      model: 'V4_5ALL',
      callBackUrl: 'https://your-app.com/callback',
      vocalGender: 'm',
      styleWeight: 0.65,
      weirdnessConstraint: 0.3,
      audioWeight: 0.7
    })
  });

  const data = await response.json();
  console.log('Task ID:', data.data.taskId);
  ```

  ```python Python theme={null}
  import requests

  url = "https://apibox.erweima.ai/api/v1/generate"
  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "prompt": "A peaceful and soothing piano piece with soft melodies",
      "customMode": False,
      "instrumental": True,
      "model": "V4_5ALL",
      "callBackUrl": "https://your-app.com/callback",
      "vocalGender": "m",
      "styleWeight": 0.65,
      "weirdnessConstraint": 0.3,
      "audioWeight": 0.7
  }

  response = requests.post(url, json=payload, headers=headers)
  result = response.json()

  print(f"Task ID: {result['data']['taskId']}")
  ```

  ```php PHP theme={null}
  <?php
  $url = 'https://apibox.erweima.ai/api/v1/generate';
  $headers = [
      'Authorization: Bearer YOUR_API_KEY',
      'Content-Type: application/json'
  ];

  $payload = [
      'prompt' => 'A peaceful and soothing piano piece with soft melodies',
      'customMode' => false,
      'instrumental' => true,
      'model' => 'V4_5ALL',
      'callBackUrl' => 'https://your-app.com/callback',
      'vocalGender' => 'm',
      'styleWeight' => 0.65,
      'weirdnessConstraint' => 0.3,
      'audioWeight' => 0.7
  ];

  $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'];
  ?>
  ```
</CodeGroup>

### Step 2: Check Task Status

Use the returned task ID to check generation status:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://apibox.erweima.ai/api/v1/generate/record-info?taskId=YOUR_TASK_ID" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(`https://apibox.erweima.ai/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 tracks:', result.data.response.data);
  } else if (result.data.status === 'PENDING') {
    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://apibox.erweima.ai/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!")
          tracks = result['data']['response']['data']
          for i, track in enumerate(tracks):
              print(f"Track {i+1}: {track['audio_url']}")
          return tracks
      elif status == 'PENDING':
          print("Still generating...")
          return None
      else:
          print(f"Generation failed: {status}")
          return None

  # Poll until complete
  task_id = "YOUR_TASK_ID"
  while True:
      tracks = check_task_status(task_id, "YOUR_API_KEY")
      if tracks:
          break
      time.sleep(30)  # Wait 30 seconds before checking again
  ```
</CodeGroup>

### Response Format

**Success Response:**

```json theme={null}
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "5c79****be8e"
  }
}
```

**Task Status Response:**

```json theme={null}
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "5c79****be8e",
    "status": "SUCCESS",
    "response": {
      "data": [
        {
          "id": "8551****662c",
          "audio_url": "https://example.cn/****.mp3",
          "stream_audio_url": "https://example.cn/****",
          "image_url": "https://example.cn/****.jpeg",
          "prompt": "A peaceful and soothing piano piece",
          "title": "Peaceful Piano",
          "tags": "peaceful, soothing, piano",
          "duration": 198.44,
          "createTime": "2025-01-01 00:00:00"
        }
      ]
    }
  }
}
```

## Core Features

* **Text-to-Music**: Input text descriptions to generate corresponding musical compositions
* **Music Extension**: Seamlessly create longer versions based on existing audio
* **Lyrics Generation**: Generate structured lyrical content from creative prompts
* **Upload & Cover**: Upload audio files and transform them into different musical styles
* **Upload & Extend**: Upload audio files and seamlessly extend them while preserving style
* **Vocal Separation**: Separate music into independent tracks like vocals and instrumentals with advanced stem separation
* **Format Conversion**: Support for WAV and other high-quality audio format outputs
* **Music Videos**: Convert audio to visualized music videos
* **Add Vocals**: Generate vocal tracks for existing instrumental music
* **Add Instrumental**: Create instrumental accompaniment for vocal tracks
* **Style Enhancement**: Enhance and optimize existing music's stylistic features with V4\_5+ conversational prompts
* **Timestamped Lyrics**: Retrieve synchronized lyrics for karaoke-style applications

## AI Models

Choose the right model for your needs:

<CardGroup cols={3}>
  <Card title="V4_5ALL" icon="list-check">
    **Extended Capabilities**

    Supports longer lyrics (5000 chars) and style descriptions (1000 chars)
  </Card>

  <Card title="V4" icon="wand-magic-sparkles">
    **Improved Vocals**

    Up to 4 minutes, enhanced vocal quality
  </Card>

  <Card title="V4_5" icon="rocket">
    **Better Song Structure**

    Max 1 minute, improved song organization
  </Card>

  <Card title="V4_5PLUS" icon="image">
    **Richer Tones**

    Up to 8 minutes, new creative approaches
  </Card>

  <Card title="V5" icon="star">
    **Latest Model**

    Enhanced quality and capabilities
  </Card>

  <Card title="V5_5" icon="sparkles">
    **Custom voice character**

    Unleash Your Voice: Custom Models Tailored to Your Unique Taste — same API limits as V5 where applicable
  </Card>
</CardGroup>

## Generation Modes

<ParamField path="customMode" type="boolean" required>
  Controls parameter complexity:

  * `false`: Simple mode, only requires prompt
  * `true`: Advanced mode, requires style and title
</ParamField>

<ParamField path="instrumental" type="boolean" required>
  Determines whether music contains vocals:

  * `true`: Instrumental only (no lyrics)
  * `false`: Contains vocals/lyrics
</ParamField>

## Key Parameters

<ParamField path="prompt" type="string" required>
  Text description of the desired music. Be specific about genre, mood, and instruments.

  **Character Limits:**

  * Non-custom mode: 500 characters
  * Custom mode (V4): 3000 characters
  * Custom mode (V4\_5, V4\_5PLUS, V5, V5\_5 & V4\_5ALL): 5000 characters
</ParamField>

<ParamField path="style" type="string">
  Music style specification (custom mode only).

  **Examples:** Jazz, Classical, Electronic, Pop, Rock, Hip-hop

  **Character Limits:**

  * V4: 200 characters
  * V4\_5, V4\_5PLUS, V5, V5\_5 & V4\_5ALL: 1000 characters
</ParamField>

<ParamField path="title" type="string">
  Title for the generated music track (custom mode only).

  **Maximum Length:** 80 characters
</ParamField>

## Complete Workflow Example

Here's a complete example of generating music with lyrics and waiting for completion:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    class SunoAPI {
      constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://apibox.erweima.ai/api/v1';
      }
      
      async generateMusic(prompt, options = {}) {
        const response = await fetch(`${this.baseUrl}/generate`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            prompt,
            customMode: options.customMode || false,
            instrumental: options.instrumental || false,
            model: options.model || 'V4_5ALL',
            style: options.style,
            title: options.title,
            negativeTags: options.negativeTags,
            callBackUrl: options.callBackUrl || 'https://your-app.com/callback',
            vocalGender: options.vocalGender,
            styleWeight: options.styleWeight,
            weirdnessConstraint: options.weirdnessConstraint,
            audioWeight: options.audioWeight
          })
        });
        
        const result = await response.json();
        if (result.code !== 200) {
          throw new Error(`Generation failed: ${result.msg}`);
        }
        
        return result.data.taskId;
      }
      
      async extendMusic(audioId, options = {}) {
        const response = await fetch(`${this.baseUrl}/generate/extend`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            audioId,
            defaultParamFlag: options.defaultParamFlag || false,
            model: options.model || 'V4_5ALL',
            prompt: options.prompt,
            style: options.style,
            title: options.title,
            continueAt: options.continueAt,
            callBackUrl: options.callBackUrl || 'https://your-app.com/callback',
            vocalGender: options.vocalGender,
            styleWeight: options.styleWeight,
            weirdnessConstraint: options.weirdnessConstraint,
            audioWeight: options.audioWeight
          })
        });
        
        const result = await response.json();
        if (result.code !== 200) {
          throw new Error(`Extension failed: ${result.msg}`);
        }
        
        return result.data.taskId;
      }
      
      async generateLyrics(prompt, callBackUrl) {
        const response = await fetch(`${this.baseUrl}/lyrics`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            prompt,
            callBackUrl
          })
        });
        
        const result = await response.json();
        if (result.code !== 200) {
          throw new Error(`Lyrics generation failed: ${result.msg}`);
        }
        
        return result.data.taskId;
      }
      
      async addVocals(uploadUrl, prompt, style, title, negativeTags, options = {}) {
        const response = await fetch(`${this.baseUrl}/generate/add-vocals`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            uploadUrl,
            prompt,
            style,
            title,
            negativeTags,
            model: options.model || 'V4_5PLUS',
            callBackUrl: options.callBackUrl || 'https://your-app.com/callback',
            vocalGender: options.vocalGender,
            styleWeight: options.styleWeight,
            weirdnessConstraint: options.weirdnessConstraint,
            audioWeight: options.audioWeight
          })
        });
        
        const result = await response.json();
        if (result.code !== 200) {
          throw new Error(`Add vocals failed: ${result.msg}`);
        }
        
        return result.data.taskId;
      }
      
      async addInstrumental(uploadUrl, title, tags, negativeTags, options = {}) {
        const response = await fetch(`${this.baseUrl}/generate/add-instrumental`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            uploadUrl,
            title,
            tags,
            negativeTags,
            model: options.model || 'V4_5PLUS',
            callBackUrl: options.callBackUrl || 'https://your-app.com/callback',
            vocalGender: options.vocalGender,
            styleWeight: options.styleWeight,
            weirdnessConstraint: options.weirdnessConstraint,
            audioWeight: options.audioWeight
          })
        });
        
        const result = await response.json();
        if (result.code !== 200) {
          throw new Error(`Add instrumental failed: ${result.msg}`);
        }
        
        return result.data.taskId;
      }
      
      async waitForCompletion(taskId, maxWaitTime = 600000) { // Max wait 10 minutes
        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.includes('FAILED') || status.status === 'SENSITIVE_WORD_ERROR') {
            throw new Error(`Generation failed: ${status.errorMessage || status.status}`);
          }
          
          // Wait 10 seconds before checking again
          await new Promise(resolve => setTimeout(resolve, 10000));
        }
        
        throw new Error('Generation timeout');
      }
      
      async getTaskStatus(taskId) {
        const response = await fetch(`${this.baseUrl}/generate/record-info?taskId=${taskId}`, {
          headers: {
            'Authorization': `Bearer ${this.apiKey}`
          }
        });
        
        const result = await response.json();
        return result.data;
      }
      
      async getRemainingCredits() {
        const response = await fetch(`${this.baseUrl}/generate/credit`, {
          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 music with lyrics
        console.log('Starting music generation...');
        const taskId = await api.generateMusic(
          'A nostalgic folk song about childhood memories',
          { 
            customMode: true,
            instrumental: false,
            model: 'V4_5',
            style: 'folk, acoustic guitar, nostalgic',
            title: 'Childhood Dreams'
          }
        );
        
        // Wait for completion
        console.log(`Task ID: ${taskId}. Waiting for completion...`);
        const result = await api.waitForCompletion(taskId);
        
        console.log('Music generation successful!');
        console.log('Generated tracks:');
        result.data.forEach((track, index) => {
          console.log(`Track ${index + 1}:`);
          console.log(`  Title: ${track.title}`);
          console.log(`  Audio URL: ${track.audio_url}`);
          console.log(`  Duration: ${track.duration} seconds`);
          console.log(`  Tags: ${track.tags}`);
        });
        
        // Extend the first track
        const firstTrack = result.data[0];
        console.log('\nExtending first track...');
        const extendTaskId = await api.extendMusic(firstTrack.id, {
          defaultParamFlag: true,
          prompt: 'Continue with a hopeful chorus',
          style: 'folk, uplifting',
          title: 'Childhood Dreams Extended',
          continueAt: 60,
          model: 'V4_5'
        });
        
        const extendResult = await api.waitForCompletion(extendTaskId);
        console.log('Music extension successful!');
        console.log('Extended track URL:', extendResult.data[0].audio_url);
        
      } catch (error) {
        console.error('Error:', error.message);
      }
    }

    main();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests
    import time

    class SunoAPI:
        def __init__(self, api_key):
            self.api_key = api_key
            self.base_url = 'https://apibox.erweima.ai/api/v1'
            self.headers = {
                'Authorization': f'Bearer {api_key}',
                'Content-Type': 'application/json'
            }
        
        def generate_music(self, prompt, **options):
            data = {
                'prompt': prompt,
                'customMode': options.get('customMode', False),
                'instrumental': options.get('instrumental', False),
                'model': options.get('model', 'V4_5ALL'),
                'callBackUrl': options.get('callBackUrl', 'https://your-app.com/callback')
            }
            
            if options.get('style'):
                data['style'] = options['style']
            if options.get('title'):
                data['title'] = options['title']
            if options.get('negativeTags'):
                data['negativeTags'] = options['negativeTags']
            if options.get('vocalGender'):
                data['vocalGender'] = options['vocalGender']
            if options.get('styleWeight'):
                data['styleWeight'] = options['styleWeight']
            if options.get('weirdnessConstraint'):
                data['weirdnessConstraint'] = options['weirdnessConstraint']
            if options.get('audioWeight'):
                data['audioWeight'] = options['audioWeight']
            
            response = requests.post(f'{self.base_url}/generate', 
                                   headers=self.headers, json=data)
            result = response.json()
            
            if result['code'] != 200:
                raise Exception(f"Generation failed: {result['msg']}")
            
            return result['data']['taskId']
        
        def extend_music(self, audio_id, **options):
            data = {
                'audioId': audio_id,
                'defaultParamFlag': options.get('defaultParamFlag', False),
                'model': options.get('model', 'V4_5ALL'),
                'callBackUrl': options.get('callBackUrl', 'https://your-app.com/callback')
            }
            
            if options.get('prompt'):
                data['prompt'] = options['prompt']
            if options.get('style'):
                data['style'] = options['style']
            if options.get('title'):
                data['title'] = options['title']
            if options.get('continueAt'):
                data['continueAt'] = options['continueAt']
            if options.get('vocalGender'):
                data['vocalGender'] = options['vocalGender']
            if options.get('styleWeight'):
                data['styleWeight'] = options['styleWeight']
            if options.get('weirdnessConstraint'):
                data['weirdnessConstraint'] = options['weirdnessConstraint']
            if options.get('audioWeight'):
                data['audioWeight'] = options['audioWeight']
            
            response = requests.post(f'{self.base_url}/generate/extend', 
                                   headers=self.headers, json=data)
            result = response.json()
            
            if result['code'] != 200:
                raise Exception(f"Extension failed: {result['msg']}")
            
            return result['data']['taskId']
        
        def generate_lyrics(self, prompt, callback_url):
            data = {
                'prompt': prompt,
                'callBackUrl': callback_url
            }
            
            response = requests.post(f'{self.base_url}/lyrics', 
                                   headers=self.headers, json=data)
            result = response.json()
            
            if result['code'] != 200:
                raise Exception(f"Lyrics generation failed: {result['msg']}")
            
            return result['data']['taskId']
        
        def add_vocals(self, upload_url, prompt, style, title, negative_tags, **options):
            data = {
                'uploadUrl': upload_url,
                'prompt': prompt,
                'style': style,
                'title': title,
                'negativeTags': negative_tags,
                'model': options.get('model', 'V4_5PLUS'),
                'callBackUrl': options.get('callBackUrl', 'https://your-app.com/callback')
            }
            
            if options.get('vocalGender'):
                data['vocalGender'] = options['vocalGender']
            if options.get('styleWeight'):
                data['styleWeight'] = options['styleWeight']
            if options.get('weirdnessConstraint'):
                data['weirdnessConstraint'] = options['weirdnessConstraint']
            if options.get('audioWeight'):
                data['audioWeight'] = options['audioWeight']
            
            response = requests.post(f'{self.base_url}/generate/add-vocals', 
                                   headers=self.headers, json=data)
            result = response.json()
            
            if result['code'] != 200:
                raise Exception(f"Add vocals failed: {result['msg']}")
            
            return result['data']['taskId']
        
        def add_instrumental(self, upload_url, title, tags, negative_tags, **options):
            data = {
                'uploadUrl': upload_url,
                'title': title,
                'tags': tags,
                'negativeTags': negative_tags,
                'model': options.get('model', 'V4_5PLUS'),
                'callBackUrl': options.get('callBackUrl', 'https://your-app.com/callback')
            }
            
            if options.get('vocalGender'):
                data['vocalGender'] = options['vocalGender']
            if options.get('styleWeight'):
                data['styleWeight'] = options['styleWeight']
            if options.get('weirdnessConstraint'):
                data['weirdnessConstraint'] = options['weirdnessConstraint']
            if options.get('audioWeight'):
                data['audioWeight'] = options['audioWeight']
            
            response = requests.post(f'{self.base_url}/generate/add-instrumental', 
                                   headers=self.headers, json=data)
            result = response.json()
            
            if result['code'] != 200:
                raise Exception(f"Add instrumental failed: {result['msg']}")
            
            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 'FAILED' in status['status'] or status['status'] == 'SENSITIVE_WORD_ERROR':
                    error_msg = status.get('errorMessage', status['status'])
                    raise Exception(f"Generation failed: {error_msg}")
                
                time.sleep(10)  # Wait 10 seconds
            
            raise Exception('Generation timeout')
        
        def get_task_status(self, task_id):
            response = requests.get(f'{self.base_url}/generate/record-info?taskId={task_id}',
                                  headers={'Authorization': f'Bearer {self.api_key}'})
            return response.json()['data']
        
        def get_remaining_credits(self):
            response = requests.get(f'{self.base_url}/generate/credit',
                                  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 music with lyrics
            print('Starting music generation...')
            task_id = api.generate_music(
                'A nostalgic folk song about childhood memories',
                customMode=True,
                instrumental=False,
                model='V4_5',
                style='folk, acoustic guitar, nostalgic',
                title='Childhood Dreams'
            )
            
            # Wait for completion
            print(f'Task ID: {task_id}. Waiting for completion...')
            result = api.wait_for_completion(task_id)
            
            print('Music generation successful!')
            print('Generated tracks:')
            for i, track in enumerate(result['data']):
                print(f"Track {i + 1}:")
                print(f"  Title: {track['title']}")
                print(f"  Audio URL: {track['audio_url']}")
                print(f"  Duration: {track['duration']} seconds")
                print(f"  Tags: {track['tags']}")
            
            # Extend the first track
            first_track = result['data'][0]
            print('\nExtending first track...')
            extend_task_id = api.extend_music(
                first_track['id'],
                defaultParamFlag=True,
                prompt='Continue with a hopeful chorus',
                style='folk, uplifting',
                title='Childhood Dreams Extended',
                continueAt=60,
                model='V4_5'
            )
            
            extend_result = api.wait_for_completion(extend_task_id)
            print('Music extension successful!')
            print(f"Extended track URL: {extend_result['data'][0]['audio_url']}")
            
        except Exception as error:
            print(f'Error: {error}')

    if __name__ == '__main__':
        main()
    ```
  </Tab>
</Tabs>

## Status Codes and Task Status

<ResponseField name="PENDING" type="Processing">
  Task is waiting for processing or currently generating
</ResponseField>

<ResponseField name="TEXT_SUCCESS" type="Partial Complete">
  Lyrics/text generation successfully completed
</ResponseField>

<ResponseField name="FIRST_SUCCESS" type="Partial Complete">
  First track generation completed
</ResponseField>

<ResponseField name="SUCCESS" type="Complete">
  All tracks generated successfully
</ResponseField>

<ResponseField name="CREATE_TASK_FAILED" type="Error">
  Task creation failed
</ResponseField>

<ResponseField name="GENERATE_AUDIO_FAILED" type="Error">
  Audio generation failed
</ResponseField>

<ResponseField name="SENSITIVE_WORD_ERROR" type="Error">
  Content filtered due to sensitive words
</ResponseField>

## HTTP Status Codes

<ResponseField name="200" type="Success">
  Request successful
</ResponseField>

<ResponseField name="400" type="Bad Request">
  Invalid parameters or missing required fields
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  No access permission, check API key
</ResponseField>

<ResponseField name="404" type="Not Found">
  Invalid request method or path
</ResponseField>

<ResponseField name="405" type="Rate Limited">
  Call limit exceeded
</ResponseField>

<ResponseField name="413" type="Content Too Long">
  Prompt or theme too long
</ResponseField>

<ResponseField name="429" type="Insufficient Credits">
  Account credits insufficient
</ResponseField>

<ResponseField name="455" type="Maintenance">
  System maintenance in progress
</ResponseField>

<ResponseField name="500" type="Server Error">
  Internal server error
</ResponseField>

## Best Practices

<AccordionGroup>
  <Accordion title="Prompt Engineering">
    * Be specific about genre, mood, and instruments
    * Use descriptive adjectives for better style control
    * Include tempo and energy level descriptions
    * Reference musical eras or specific artists for style guidance
  </Accordion>

  <Accordion title="Model Selection">
    * V4\_5ALL: Best for projects requiring longer lyrics and style descriptions
    * V4: Choose when vocal quality is most important
    * V4\_5: Use for better song structure with max 1 min duration
    * V4\_5PLUS: Select for highest quality and longest tracks
  </Accordion>

  <Accordion title="Performance Optimization">
    * Use callbacks instead of frequent polling
    * Start with non-custom mode for simple needs
    * Implement proper error handling for generation failures
    * Cache generated content as files expire after 14-15 days
  </Accordion>

  <Accordion title="Content Guidelines">
    * Avoid using copyrighted material in prompts
    * Use original lyrics and music descriptions
    * Be mindful of content policies for lyrical content
    * Test prompt variations to avoid sensitive word filters
  </Accordion>
</AccordionGroup>

## Error Handling

<AccordionGroup>
  <Accordion title="Content Policy Violation (Code 400)">
    ```javascript theme={null}
    try {
      const taskId = await api.generateMusic('copyrighted lyrics');
    } catch (error) {
      if (error.data.code === 400) {
        console.log('Please use only original content');
      }
    }
    ```
  </Accordion>

  <Accordion title="Insufficient Credits (Code 429)">
    ```javascript theme={null}
    try {
      const taskId = await api.generateMusic('original composition');
    } catch (error) {
      if (error.data.code === 429) {
        console.log('Please add more credits to your account');
      }
    }
    ```
  </Accordion>

  <Accordion title="Rate Limiting (Code 405)">
    ```javascript theme={null}
    const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

    async function generateWithRetry(prompt, options, maxRetries = 3) {
      for (let i = 0; i < maxRetries; i++) {
        try {
          return await api.generateMusic(prompt, options);
        } catch (error) {
          if (error.data.code === 405 && i < maxRetries - 1) {
            await delay(Math.pow(2, i) * 1000); // Exponential backoff
            continue;
          }
          throw error;
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Support

<Info>
  Need help? Our technical support team is here to assist you.

  * **Email**: [support@api.box](mailto:support@api.box)
  * **Documentation**: Check detailed API documentation and examples
  * **API Status**: View our status page for real-time API health information
</Info>

***

Ready to start creating amazing AI music? [Get your API key](https://api.box/api-key) and start creating today!
