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

# List Voices

> Retrieve a paginated list of voices available for video narration

Retrieves a paginated list of voices. You can request public voices from our voice library, your custom cloned voices, or both.

## Query Parameters

<ParamField query="type" type="string" default="all">
  The type of voices to retrieve.

  **Allowed values:** `public`, `cloned`, `all`

  * `public`: Public library voices available to all users
  * `cloned`: Your custom cloned voices
  * `all`: Both public and cloned voices (default)
</ParamField>

<ParamField query="gender" type="string">
  Filter voices by gender.

  **Allowed values:** `male`, `female`
</ParamField>

<ParamField query="age" type="string">
  Filter voices by age group.

  **Allowed values:** `young`, `middle_aged`, `old`
</ParamField>

<ParamField query="language" type="string">
  Filter voices by language (ISO 639-1 code).

  **Allowed values:** `en`, `es`, `pt`, `de`, `fr`, `it`, `ca`
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Maximum number of voices to return per page.

  **Range:** 1-100
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Number of voices to skip (for pagination).

  **Minimum:** 0
</ParamField>

## Response

<ResponseField name="voices" type="array" required>
  List of voice objects.

  <Expandable title="Voice properties">
    <ResponseField name="voices[].voice_id" type="string">
      Unique identifier for the voice. Use this ID when creating videos with narration.
    </ResponseField>

    <ResponseField name="voices[].name" type="string">
      Display name of the voice.
    </ResponseField>

    <ResponseField name="voices[].type" type="string">
      Voice type: `public` or `cloned`.
    </ResponseField>

    <ResponseField name="voices[].language" type="string">
      Primary language of the voice (ISO 639-1 code).
    </ResponseField>

    <ResponseField name="voices[].accent" type="string | null">
      Accent of the voice (e.g., "american", "british"). May be `null` if not specified.
    </ResponseField>

    <ResponseField name="voices[].age" type="string | null">
      Age group of the voice: `young`, `middle_aged`, or `old`. May be `null` if not specified.
    </ResponseField>

    <ResponseField name="voices[].gender" type="string | null">
      Gender of the voice: `male` or `female`. May be `null` if not specified.
    </ResponseField>

    <ResponseField name="voices[].preview_url" type="string | null">
      URL to a sample audio clip of the voice. May be `null` for cloned voices.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object" required>
  Pagination information.

  <Expandable title="Pagination properties">
    <ResponseField name="pagination.total" type="integer">
      Total number of voices available.
    </ResponseField>

    <ResponseField name="pagination.limit" type="integer">
      Number of voices per page (as requested).
    </ResponseField>

    <ResponseField name="pagination.offset" type="integer">
      Current offset (as requested).
    </ResponseField>

    <ResponseField name="pagination.has_more" type="boolean">
      Whether there are more voices available after this page.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  # List all voices
  curl "https://api.vibepeak.ai/v1/voices" \
    -H "Authorization: Bearer vpk_live_xxxxx"

  # List public female voices in English
  curl "https://api.vibepeak.ai/v1/voices?type=public&gender=female&language=en" \
    -H "Authorization: Bearer vpk_live_xxxxx"

  # List cloned voices with pagination
  curl "https://api.vibepeak.ai/v1/voices?type=cloned&limit=10&offset=0" \
    -H "Authorization: Bearer vpk_live_xxxxx"
  ```

  ```javascript Node.js theme={null}
  // List all voices
  const response = await fetch('https://api.vibepeak.ai/v1/voices', {
    headers: {
      'Authorization': 'Bearer vpk_live_xxxxx'
    }
  });

  const data = await response.json();
  console.log(`Found ${data.pagination.total} voices`);

  for (const voice of data.voices) {
    console.log(`${voice.name} (${voice.voice_id}) - ${voice.language}`);
  }

  // Filter by gender and language
  const filteredResponse = await fetch(
    'https://api.vibepeak.ai/v1/voices?type=public&gender=female&language=en',
    { headers: { 'Authorization': 'Bearer vpk_live_xxxxx' } }
  );

  const filteredData = await filteredResponse.json();
  console.log(`Found ${filteredData.pagination.total} female English voices`);

  // Paginate through all voices
  async function getAllVoices(type = 'all') {
    const voices = [];
    let offset = 0;
    const limit = 50;

    while (true) {
      const res = await fetch(
        `https://api.vibepeak.ai/v1/voices?type=${type}&limit=${limit}&offset=${offset}`,
        { headers: { 'Authorization': 'Bearer vpk_live_xxxxx' } }
      );
      const data = await res.json();
      voices.push(...data.voices);

      if (!data.pagination.has_more) break;
      offset += limit;
    }

    return voices;
  }
  ```

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

  # List all voices
  response = requests.get(
      'https://api.vibepeak.ai/v1/voices',
      headers={'Authorization': 'Bearer vpk_live_xxxxx'}
  )

  data = response.json()
  print(f"Found {data['pagination']['total']} voices")

  for voice in data['voices']:
      print(f"{voice['name']} ({voice['voice_id']}) - {voice['language']}")

  # Filter by gender and language
  response = requests.get(
      'https://api.vibepeak.ai/v1/voices',
      params={'type': 'public', 'gender': 'female', 'language': 'en'},
      headers={'Authorization': 'Bearer vpk_live_xxxxx'}
  )

  filtered_data = response.json()
  print(f"Found {filtered_data['pagination']['total']} female English voices")

  # Paginate through all cloned voices
  def get_all_voices(voice_type='all'):
      voices = []
      offset = 0
      limit = 50

      while True:
          response = requests.get(
              'https://api.vibepeak.ai/v1/voices',
              params={'type': voice_type, 'limit': limit, 'offset': offset},
              headers={'Authorization': 'Bearer vpk_live_xxxxx'}
          )
          data = response.json()
          voices.extend(data['voices'])

          if not data['pagination']['has_more']:
              break
          offset += limit

      return voices
  ```
</RequestExample>

<ResponseExample>
  ```json Public Voices theme={null}
  {
    "voices": [
      {
        "voice_id": "TpuSXADBOG1Nx1grSvue",
        "name": "MimiMoses",
        "type": "public",
        "language": "en",
        "accent": "american",
        "age": "middle_aged",
        "gender": "female",
        "preview_url": "https://storage.googleapis.com/eleven-public-prod/database/user/voices/preview.mp3"
      },
      {
        "voice_id": "EXAVITQu4vr4xnSDxMaL",
        "name": "Sarah",
        "type": "public",
        "language": "en",
        "accent": "american",
        "age": "young",
        "gender": "female",
        "preview_url": "https://storage.googleapis.com/eleven-public-prod/database/user/voices/sarah-preview.mp3"
      }
    ],
    "pagination": {
      "total": 150,
      "limit": 20,
      "offset": 0,
      "has_more": true
    }
  }
  ```

  ```json Cloned Voices theme={null}
  {
    "voices": [
      {
        "voice_id": "abc123-def456-ghi789",
        "name": "My Custom Voice",
        "type": "cloned",
        "language": "en",
        "accent": null,
        "age": null,
        "gender": "female",
        "preview_url": null
      }
    ],
    "pagination": {
      "total": 2,
      "limit": 20,
      "offset": 0,
      "has_more": false
    }
  }
  ```

  ```json Mixed (All) Voices theme={null}
  {
    "voices": [
      {
        "voice_id": "abc123-def456-ghi789",
        "name": "My Custom Voice",
        "type": "cloned",
        "language": "en",
        "accent": null,
        "age": null,
        "gender": "female",
        "preview_url": null
      },
      {
        "voice_id": "TpuSXADBOG1Nx1grSvue",
        "name": "MimiMoses",
        "type": "public",
        "language": "en",
        "accent": "american",
        "age": "middle_aged",
        "gender": "female",
        "preview_url": "https://storage.googleapis.com/eleven-public-prod/database/user/voices/preview.mp3"
      }
    ],
    "pagination": {
      "total": 152,
      "limit": 20,
      "offset": 0,
      "has_more": true
    }
  }
  ```

  ```json Empty Response theme={null}
  {
    "voices": [],
    "pagination": {
      "total": 0,
      "limit": 20,
      "offset": 0,
      "has_more": false
    }
  }
  ```

  ```json 400 Invalid Parameter theme={null}
  {
    "error": {
      "code": "INVALID_PARAMETER",
      "message": "Invalid value for 'type'. Must be 'public', 'cloned', or 'all'.",
      "request_id": "req_xyz123"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "INVALID_API_KEY",
      "message": "Invalid or missing API key.",
      "request_id": "req_xyz123"
    }
  }
  ```
</ResponseExample>

## Usage with Video Creation

Once you've retrieved the voice list, use the voice `voice_id` when creating videos:

```javascript theme={null}
// 1. List available voices
const voicesResponse = await fetch(
  'https://api.vibepeak.ai/v1/voices?type=public&gender=female&language=en',
  { headers: { 'Authorization': 'Bearer vpk_live_xxxxx' } }
);
const { voices } = await voicesResponse.json();

// 2. Select a voice and create a video
const selectedVoice = voices[0];

const videoResponse = await fetch('https://api.vibepeak.ai/v1/real-estate/narrated-slideshow', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vpk_live_xxxxx',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    images: ['https://example.com/image1.jpg', /* ... */],
    script: 'Welcome to this beautiful property...',
    voice: { voice_id: selectedVoice.voice_id },  // Use the voice_id here
    style: 'do-not-modify'
  })
});
```

## Error Codes

| Code                | Status | Description                                                                 |
| ------------------- | ------ | --------------------------------------------------------------------------- |
| `INVALID_PARAMETER` | 400    | Invalid value for `type`, `gender`, `age`, `language`, `limit`, or `offset` |
| `VALIDATION_ERROR`  | 400    | Query parameter validation failed                                           |
| `INVALID_API_KEY`   | 401    | Invalid or missing API key                                                  |

See [Error Handling](/concepts/error-handling) for more details.
