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

# Voice Cloning API

> Create custom AI voices with the Voice.ai Voice Cloning API. Upload audio samples, track processing status, and manage your voice library with our REST API

Clone a voice from an audio sample to create a custom voice for speech generation.

<Info>
  **Prerequisites**: [API key](/docs/guides/authentication), audio sample (MP3, WAV, or PCM format)
</Info>

<Steps>
  <Step title="Clone the Voice">
    Upload your audio file directly using multipart/form-data. See the [Clone Voice](/docs/api-reference/text-to-speech/clone-voice) endpoint for details.

    <CodeGroup>
      ```python Python theme={null}
      import requests

      # Upload audio file directly
      with open('voice_sample.mp3', 'rb') as f:
          files = {'file': ('voice_sample.mp3', f, 'audio/mpeg')}
          data = {
              'name': 'My Cloned Voice',
              'voice_visibility': 'PRIVATE',
              'language': 'en'  # Language code (en, es, fr, de, it, pt, pl, ru, nl, sv, ca)
          }
          response = requests.post(
              'https://dev.voice.ai/api/v1/tts/clone-voice',
              headers={'Authorization': 'Bearer YOUR_API_KEY'},
              files=files,
              data=data
          )

      data = response.json()
      print(f"Voice ID: {data['voice_id']}, Status: {data['status']}")
      ```

      ```bash cURL theme={null}
      curl -X POST "https://dev.voice.ai/api/v1/tts/clone-voice" \
        -H "Authorization: Bearer YOUR_API_KEY" \
        -F "file=@voice_sample.mp3" \
        -F "name=My Cloned Voice" \
        -F "voice_visibility=PRIVATE" \
        -F "language=en"
      ```

      ```typescript TypeScript theme={null}
      // Node.js: Using form-data library
      import FormData from 'form-data';
      import * as fs from 'fs';

      const form = new FormData();
      form.append('file', fs.createReadStream('voice_sample.mp3'));
      form.append('name', 'My Cloned Voice');
      form.append('voice_visibility', 'PRIVATE');
      form.append('language', 'en');  // Language code (en, es, fr, de, it, pt, pl, ru, nl, sv, ca)

      const response = await fetch('https://dev.voice.ai/api/v1/tts/clone-voice', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          ...form.getHeaders()
        },
        body: form
      });

      const data = await response.json();
      console.log(`Voice ID: ${data.voice_id}, Status: ${data.status}`);
      ```
    </CodeGroup>
  </Step>

  <Step title="Check Voice Status">
    Check the voice status using the `voice_id` from the clone response. See the [Get Voice](/docs/api-reference/text-to-speech/get-voice) endpoint for details.

    <CodeGroup>
      ```python Python theme={null}
      import requests
      import time

      voice_id = data['voice_id']  # From clone response

      # Poll until voice is available
      while True:
          response = requests.get(
              f'https://dev.voice.ai/api/v1/tts/voice/{voice_id}',
              headers={'Authorization': 'Bearer YOUR_API_KEY'}
          )
          status_data = response.json()
          status = status_data['status']
          print(f"Status: {status}")
          
          if status == 'AVAILABLE':
              print("Voice is ready!")
              break
          elif status == 'FAILED':
              print("Voice cloning failed")
              break
          
          time.sleep(2)  # Wait 2 seconds before checking again
      ```

      ```bash cURL theme={null}
      # Check status by voice_id
      curl -X GET "https://dev.voice.ai/api/v1/tts/voice/{voice_id}" \
        -H "Authorization: Bearer YOUR_API_KEY"
      ```

      ```typescript TypeScript theme={null}
      // Poll until voice is available
      const checkStatus = async (voiceId: string) => {
        while (true) {
          const response = await fetch(`https://dev.voice.ai/api/v1/tts/voice/${voiceId}`, {
            method: 'GET',
            headers: {
              'Authorization': 'Bearer YOUR_API_KEY'
            }
          });
          
          const data = await response.json();
          console.log(`Status: ${data.status}`);
          
          if (data.status === 'AVAILABLE') {
            console.log('Voice is ready!');
            break;
          } else if (data.status === 'FAILED') {
            console.log('Voice cloning failed');
            break;
          }
          
          await new Promise(resolve => setTimeout(resolve, 2000));  // Wait 2 seconds
        }
      };

      await checkStatus(data.voice_id);
      ```
    </CodeGroup>

    **Status values:**

    * `PENDING` - Voice cloning has started
    * `PROCESSING` - Voice is being processed
    * `AVAILABLE` - Voice is ready to use
    * `FAILED` - Voice cloning failed
  </Step>
</Steps>

## List Voices

List all voices owned by the authenticated user. See the [List Voices](/docs/api-reference/text-to-speech/list-voices) endpoint for details.

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://dev.voice.ai/api/v1/tts/voices',
      headers={'Authorization': 'Bearer YOUR_API_KEY'}
  )

  voices = response.json()
  for voice in voices:
      print(f"Voice ID: {voice['voice_id']}, Name: {voice['name']}, Status: {voice['status']}")
  ```

  ```bash cURL theme={null}
  curl -X GET "https://dev.voice.ai/api/v1/tts/voices" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://dev.voice.ai/api/v1/tts/voices', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });

  const voices = await response.json();
  voices.forEach((voice: any) => {
    console.log(`Voice ID: ${voice.voice_id}, Name: ${voice.name}, Status: ${voice.status}`);
  });
  ```
</CodeGroup>

## Request Parameters

* `file` (required) - Audio file (MP3, WAV, or OGG format, max 7.5MB)
* `name` (optional) - Name for the voice
* `voice_visibility` (optional) - `"PUBLIC"` or `"PRIVATE"` (default: `"PUBLIC"`)
* `language` (optional) - Language code in ISO 639-1 format (default: `"en"`). Supported languages:
  * `en` - English
  * `es` - Spanish
  * `fr` - French
  * `de` - German
  * `it` - Italian
  * `pt` - Portuguese
  * `pl` - Polish
  * `ru` - Russian
  * `nl` - Dutch
  * `sv` - Swedish
  * `ca` - Catalan

<Info>
  The endpoint accepts `multipart/form-data`. Upload the audio file directly - no base64 encoding needed.
</Info>

## Update Voice

Update voice metadata (name and/or visibility). See the [Update Voice](/docs/api-reference/text-to-speech/update-voice) endpoint for details.

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.patch(
      f'https://dev.voice.ai/api/v1/tts/voice/{voice_id}',
      headers={'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json'},
      json={'name': 'Updated Voice Name', 'voice_visibility': 'PRIVATE'}
  )

  data = response.json()
  print(f"Updated: {data['name']}, Visibility: {data['voice_visibility']}")
  ```

  ```bash cURL theme={null}
  curl -X PATCH "https://dev.voice.ai/api/v1/tts/voice/{voice_id}" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Updated Voice Name",
      "voice_visibility": "PRIVATE"
    }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(`https://dev.voice.ai/api/v1/tts/voice/${voiceId}`, {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'Updated Voice Name',
      voice_visibility: 'PRIVATE'
    })
  });

  const data = await response.json();
  console.log(`Updated: ${data.name}, Visibility: ${data.voice_visibility}`);
  ```
</CodeGroup>

## Delete Voice

Delete a voice (owner-only). See the [Delete Voice](/docs/api-reference/text-to-speech/delete-voice) endpoint for details.

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.delete(
      f'https://dev.voice.ai/api/v1/tts/voice/{voice_id}',
      headers={'Authorization': 'Bearer YOUR_API_KEY'}
  )

  data = response.json()
  print(f"Deleted: {data['voice_id']}")
  ```

  ```bash cURL theme={null}
  curl -X DELETE "https://dev.voice.ai/api/v1/tts/voice/{voice_id}" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(`https://dev.voice.ai/api/v1/tts/voice/${voiceId}`, {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });

  const data = await response.json();
  console.log(`Deleted: ${data.voice_id}`);
  ```
</CodeGroup>

## Audio Requirements

* **Formats**: MP3, WAV, or PCM
* **Max size**: 7.5MB
* **Quality**: Clear, single speaker audio works best
* **Duration**: 10-60 seconds recommended

<CardGroup cols={3}>
  <Card title="Generate Speech" icon="volume-high" href="/docs/guides/text-to-speech/quickstart#generate-speech">
    Use your voice\_id to generate speech
  </Card>

  <Card title="Streaming" icon="waveform" href="/docs/guides/text-to-speech/streaming">
    Learn about real-time audio generation
  </Card>

  <Card title="API Reference" icon="book" href="/docs/api-reference">
    Explore complete API documentation
  </Card>
</CardGroup>
