> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://onepin.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://onepin.ai/docs/_mcp/server.

# Browse voices

The voice catalog your workspace can use is the source of truth. List it and filter to what you need.

#### Python

```python
from onepin import OnepinClient

client = OnepinClient()

for v in client.voices.list(language=["en-us"], limit=50).data:
    print(v.id, v.name, v.provider, v.supported_languages)
```

Filters: `language` (BCP-47), `provider`, `gender`, `favorites_only`, `search`. Fields on each voice include `provider_voice_id`, `provider`, and `supported_models` — what a workflow's `voice_map` needs (see [Generator](/docs/workflow/generator)).

#### CLI

```bash
onepin voices list --language en-us
onepin voices list --provider elevenlabs --gender female --json
```

Filters: `--language`, `--provider`, `--gender`, `--favorites-only`, `--search` (all comma-separated where it makes sense).

## Search in plain language

`search` is not a substring match. It combines keyword matching against the voice's name and tags with a semantic match against its description, so a query like `warm narrator for documentary` returns voices that read that way rather than voices with those literal words.

```python
client.voices.list(search="warm narrator for documentary", limit=20)
```

## Hear it before you commit

Every voice carries a `sample_url` — a time-limited presigned URL you can play directly. Two things to know:

* Pass `language=` to `voices.list` and each voice also gets `language_sample_url` plus `language_sample_locale`, the clip in the locale you asked for. `language_sample_locale` is the locale actually served: a bare-family filter like `en` expands to both `en-us` and `en-gb`, and this tells you which one you're hearing.
* `preview_locales` lists the locales a voice has ready-to-play preview audio for. That's what it can be **heard** in — `supported_languages` is what it can **speak**, and they are not the same list.

For one voice in one specific locale there is a dedicated endpoint that returns the clip along with the model it was synthesized with:

```bash
curl "https://api.onepin.ai/api/v1/voices/$VOICE_ID/preview?language=en-us" \
  -H "Authorization: Bearer $ONEPIN_API_KEY"
# → {"data": {"name": "...", "locale": "en-us", "model": "...", "sample_url": "https://…signed…"}}
```

The URL is valid for an hour — fetch the preview again rather than caching it.

> **Note**
>
> `GET /voices/{voice_id}/preview` is new. It reaches the Python SDK and CLI as `voices.preview` in the next release; until then, call it over HTTP as above.

## Imported voices can be unavailable

If your workspace imports voices from its own provider account ([BYOK](/docs/guides/bring-your-own-key), `source: "provider_imported"`), those can go `unavailable` — the provider key stopped working, the voice was deleted upstream, or a sync hasn't reconciled yet. Unavailable voices stay listed and readable, but a workflow that references one is rejected at save, at run start, and at synthesis.

```python
v = client.voices.get(voice_id="...").data
if v.availability == "unavailable":
    print("can't use this one:", v.unavailable_reason)
```

`availability` is null for platform voices — they have no import lifecycle to go wrong.

Browse the full catalog with pricing and languages at [onepin.ai/models](https://onepin.ai/models), or see [Voices & Models](/docs/get-started/voices-models) for the model list.

## Related

* [Voices & Models](/docs/get-started/voices-models) — the model catalog
* [Generator](/docs/workflow/generator) — assigning a voice
* [Bring your own key](/docs/guides/bring-your-own-key) — where imported voices come from, and how to pin one