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

# Custom Voices

> Clone a voice in Anam, or bring an ElevenLabs, Cartesia or Fish Audio voice into Anam in Lab or with the API, then assign it to a persona.

You can clone a voice in Anam Lab from a recording, or bring in a voice you already have with a provider. Each kind of provider voice reaches Anam a different way, so start by finding your voice in the table below.

Your organization needs custom voice access to clone or import a voice. If Lab or the API reports an access error, contact [Anam Support](mailto:support@anam.ai).

## Choose how to add a voice

| Your voice | How it reaches Anam | Where |
| - | - | - |
| ElevenLabs Voice Library voice or default voice | Its voice ID | [Lab](#public-voice-library-voices) or [API](#import-by-voice-id) |
| ElevenLabs Professional Voice Clone | Its share link | [Lab](#share-a-professional-voice-clone-by-link) or [API](#import-with-an-elevenlabs-share-link) |
| ElevenLabs Professional Voice Clone in your own ElevenLabs account | Your organization's own ElevenLabs API key | [API](#import-with-your-own-elevenlabs-key) |
| ElevenLabs instant clone or Voice Design voice | Your organization's own ElevenLabs API key | [Lab](#use-your-own-elevenlabs-api-key) or [API](#import-with-your-own-elevenlabs-key) |
| Cartesia library voice, or your voice set to **Shared** | Its voice ID | [Lab](#import-cartesia-voices) or [API](#import-by-voice-id) |
| Private Cartesia voice | Make it public, then its voice ID | [Lab](#import-cartesia-voices) |
| Fish Audio public voice | Its voice ID | [API](#import-by-voice-id), or Lab where Fish Audio is enabled |
| A recording of the voice | Clone it in Anam | [Lab](#clone-or-upload-a-voice-in-lab) or [API](#create-a-voice-with-the-api) |

> [!TIP]
>
> To check which kind an ElevenLabs voice is, open **My Voices** in ElevenLabs and use the **Type** filter: Voice Design, Instant Voice Clone, Professional Voice Clone or Default voices.

## Clone or upload a voice in Lab

Sign in to [Anam Lab](https://lab.anam.ai) and open the persona you want to update.

**1. Open the cloning screen**

Select the **Voice** tab, then **Record or upload**. The cloning screen supports both recording and uploading audio.

**2. Record or upload audio**

Choose the language and accent, then select **Start recording** to record a sample with your microphone, or **Upload audio file** to use an existing recording.

For microphone recording, read the displayed script for 10–15 seconds. The recorder stops automatically at 15 seconds. Review your sample, then select **Continue**.

**3. Name and clone the voice**

Enter a **Voice name** and any other details, then select **Clone voice** and listen to the preview.

**4. Use the voice**

Select **Use this voice** to assign the clone to your persona, then **Publish** to apply the change.

### Lab audio requirements

* Upload WAV, MP3/MPEG, MP4/M4A, WebM, or OGG audio.
* The file must be at least 10 KB and no larger than 50 MB (10,240–52,428,800 bytes).
* The 15-second limit applies to the in-browser recorder, not to uploaded file duration. Uploaded files still need to pass file validation and the voice provider's processing checks.

## Import a provider voice in Lab

Select the **Voice** tab, then **Import from provider**. Lab asks two questions and then shows the one way your voice can reach Anam:

1. **Where is the voice from?** ElevenLabs or Cartesia. Fish Audio appears where it's enabled for your organization.
2. **What kind of voice is it?** For ElevenLabs: **Voice Library voice**, **Professional Voice Clone** or **Instant clone or designed voice**. Every Cartesia voice imports the same way, so for Cartesia Lab asks **How do you want to import it?** instead.

Each choice says up front what it leads to, so a voice that needs a share link or your own key never goes through the voice ID form. **Back** returns to the previous step.

Share-link import, connecting a provider account and your own ElevenLabs key are available to every organization.

## Import ElevenLabs voices

The method depends on what kind of voice it is.

### Public Voice Library voices

In Lab, choose **ElevenLabs**, then **Voice Library voice**. Paste the voice ID or a Voice Library link, pick the **Voice model**, and select **Validate**. When the preview is ready, name the voice and select **Save voice**. ElevenLabs' default voices import the same way.

The first import of a Voice Library voice can take about a minute while ElevenLabs adds it to Anam's account.

### Share a Professional Voice Clone by link

A Professional Voice Clone can be shared with Anam by link. Anam's own ElevenLabs account then speaks it, so it works on personas with Zero Data Retention.

**1. Turn on link sharing in ElevenLabs**

In ElevenLabs, open **My Voices**, find the voice and select **More actions** (three dots), then **Share Voice**. Turn on **Anyone with the link** and copy the link.

**2. Import the link in Lab**

In Lab, choose **ElevenLabs**, then **Professional Voice Clone**. Paste the link into **ElevenLabs share link** and select **Add & check**. Lab adds the voice to Anam's ElevenLabs account and shows which models it's fine-tuned for.

**3. Pick a model and import**

Choose the **Voice model**, adjust the name if you want, and select **Import**. If you already have the voice on that model, the button reads **Refresh preview** and regenerates its preview instead of creating another voice.

> [!NOTE]
>
> A shared voice can be used by one Anam organization. Turning off link sharing in ElevenLabs later doesn't remove Anam's copy; contact [Anam Support](mailto:support@anam.ai) to have it removed.

### Use your own ElevenLabs API key

Instant clones and Voice Design voices stay in the ElevenLabs account that made them, and ElevenLabs doesn't let them be shared outside it. To use them, save your organization's ElevenLabs API key in Anam. Anam then speaks those voices with your key, so you never share them.

In Lab, your own key is for instant clones and Voice Design voices; a Professional Voice Clone in your account offers **Use share link** instead. To use one of your own Professional Voice Clones with your key, import it with the API ([`useOrganizationKey`](#import-with-your-own-elevenlabs-key)). You can also save the key with the API ([manage your ElevenLabs key](#manage-your-elevenlabs-key-with-the-api)).

**1. Create the key in ElevenLabs**

Create an API key with **Text to Speech** and **Voices: Read** access in the account that has the voice. See [Create an ElevenLabs API key](#create-an-elevenlabs-api-key).

**2. Choose the voice kind**

In Lab, choose **ElevenLabs**, then **Instant clone or designed voice**.

**3. Save the key**

Paste the key and select **Save key**. Lab checks that ElevenLabs recognizes the key and that it has both permissions, saves it for your organization, and lists the voices in that account. If your organization already saved a key, select **Use saved key** instead.

**4. Use the voice**

Select **Use your key** on the voice. Lab checks the voice with a preview; then name it and select **Save voice**.

If you paste a voice ID that Anam's ElevenLabs account can't reach, Lab tries your organization's saved key straight away. Without a saved key, it asks for one in place and checks the voice again once you save it.

What to know about your own key:

* In Lab, only organization owners and admins can save or remove the key. Other members can use voices that speak with it, and are asked to have an owner or admin add it when none is saved. Over the API, an API key with `voices:write` access can save or remove it.
* A key you paste in Lab needs **Text to Speech** and **Voices: Read** access. Lab checks both before it saves the key and says which one is missing. A key saved with the API needs only **Text to Speech**. Keys from ElevenLabs data-residency workspaces work; Anam uses the host that accepts the key.
* If a preview fails with your key, Lab says why: a missing permission, an ElevenLabs plan without instant voice clones (the free plan), no credits left, or a voice that isn't in the key's account.
* Speech for these voices runs on your ElevenLabs plan, and ElevenLabs bills it there.
* Your saved key shows under the voice list as its last four characters, with **Remove**. Removing it blocks new sessions and previews with the voices that use it until you save a key again, and the voice list marks those voices **Needs your ElevenLabs API key**. Sessions that already started keep running. Removing the key in Anam doesn't revoke it in ElevenLabs; delete it there if you no longer need it.
* Voices on your own key can't be used on personas with Zero Data Retention, because the speech runs through your ElevenLabs account and its retention settings. ElevenLabs offers zero retention on its enterprise plans. If you need ZDR with your own voices, contact [Anam Support](mailto:support@anam.ai).
* Voices on your own key need a Cara 4 avatar. A session with an older avatar fails with `400` and asks you to choose a Cara 4 avatar or another voice.

### Create an ElevenLabs API key

Create the key in the ElevenLabs account or workspace that has your voices. An instant clone belongs to the member who made it, unless they shared it in the workspace.

**1. Open API keys**

In ElevenLabs, go to **Developers**, then [**API Keys**](https://elevenlabs.io/app/developers/api-keys), and select **Create Key**.

**2. Set the permissions**

Name the key, for example "Anam". Keep **Restrict key** on, then set:

* **Text to Speech**: **Access**
* **Voices**: **Read**

Leave the other permissions at **No Access**. You can set a credit limit; your voices stop speaking in Anam when the key reaches it.

**3. Copy the key**

Select **Create Key** and copy the key. ElevenLabs only shows it once, so if you lose it, create a new one.

To fix a key that's missing a permission, open its menu in **API Keys**, select **Edit**, change the permission and paste the same key again.

## Import Cartesia voices

A Cartesia library voice imports by its voice ID. A voice you made in Cartesia must be set to **Shared** first.

**1. Share the voice in Cartesia**

Open the voice's sharing settings and select **Shared**. Cartesia describes this setting as **Anyone with the voice ID can use it**.

![Cartesia voice sharing dialog with Shared selected so anyone with the voice ID can use the voice](https://mintcdn.com/anam/R88VymgYlS3EV8Ad/images/cartesia-voice-sharing.png?fit=max\&auto=format\&n=R88VymgYlS3EV8Ad\&q=85\&s=0a4822009a70cb0f321723921de9bb8d)

**2. Import the voice in Lab**

In Lab, choose **Cartesia**, then **Paste a voice ID**. Paste the voice ID or a `play.cartesia.ai` voice link, select **Validate**, then **Save voice**.

To pick from the voices in your Cartesia account, choose **Use a Cartesia API key** instead, paste a key and select **Connect**. Lab lists your voices, including private ones, and a private voice shows **Make public**, which sets it to public after you confirm.

### Create a Cartesia API key

In Cartesia, open [**API Keys**](https://play.cartesia.ai/keys), create a key and copy it. Cartesia keys start with `sk_car_` and have no permissions to set. Lab forgets the key two hours after you connect it.

## Import voices with the API

[`POST /v1/voice-imports`](https://anam.ai/docs/api-reference/voices/validate-and-import-a-provider-voice) imports an existing provider voice. Anam generates a real preview before it saves the voice, so a successful response means the voice works. Use an API key with `voices:write` access.

Imports are slow, so set your client's timeout above 120 seconds. A voice ID import spends up to 5 seconds reading the voice's details and up to 90 seconds generating the preview. A share-link import can take up to 110 seconds, and the endpoint allows 120 seconds in total. If your client gives up early, the import can still finish and create the voice: list your voices with [`GET /v1/voices`](https://anam.ai/docs/api-reference/voices/list-voices) before you retry a voice ID import, so you don't create a duplicate. Retrying a share-link import doesn't create a duplicate; it refreshes the voice.

Send one of three inputs, depending on the kind of voice:

| Voice | Send |
| - | - |
| ElevenLabs Voice Library or default voice, Cartesia library or shared voice, Fish Audio public voice | `provider` and `providerVoiceId` |
| Any ElevenLabs voice your organization's saved key can reach, including instant clones, Voice Design voices and your own Professional Voice Clones | `provider: "ELEVENLABS"`, `providerVoiceId` and `useOrganizationKey: true` |
| ElevenLabs Professional Voice Clone shared with **Anyone with the link** | `shareUrl` |

### Import by voice ID

```bash cURL theme={"system"}
curl -X POST https://api.anam.ai/v1/voice-imports \
  -H "Authorization: Bearer $ANAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "ELEVENLABS",
    "providerVoiceId": "21m00Tcm4TlvDq8ikWAM",
    "providerModelId": "eleven_v3_conversational"
  }'
```

Omit `providerModelId` to use the provider's default model. Omit `displayName` and `description` to take them from the provider. A successful request returns `201` with the new voice and a `Location` header. Repeating a request creates another voice.

### Manage your ElevenLabs key with the API

Save your organization's ElevenLabs API key once, then import voices that speak with it. A key you save this way only needs **Text to Speech** access; Anam checks it without generating speech.

```bash cURL theme={"system"}
curl -X PUT https://api.anam.ai/v1/voices/elevenlabs-key \
  -H "Authorization: Bearer $ANAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "'"$ELEVENLABS_API_KEY"'" }'
```

Anam checks the key with ElevenLabs on each of its API hosts, including data-residency hosts, and stores it encrypted. Saving replaces any key already saved, including one saved in Lab.

| Request | Access | What it does |
| - | - | - |
| [`GET /v1/voices/elevenlabs-key`](https://anam.ai/docs/api-reference/voices/get-the-organizations-elevenlabs-api-key-status) | `voices:read` | Returns the key's status. |
| [`PUT /v1/voices/elevenlabs-key`](https://anam.ai/docs/api-reference/voices/save-the-organizations-elevenlabs-api-key) | `voices:write` | Saves or replaces the key. |
| [`DELETE /v1/voices/elevenlabs-key`](https://anam.ai/docs/api-reference/voices/remove-the-organizations-elevenlabs-api-key) | `voices:write` | Removes the key. Always works. New sessions and previews with voices that use the key fail until you save a key again; sessions that already started keep running. It doesn't revoke the key in ElevenLabs. |

Each request returns the key's status, never the key itself:

```json Response theme={"system"}
{
  "enabled": true,
  "saved": true,
  "hint": "a1b2",
  "voiceCount": 3,
  "lastValidatedAt": "2026-10-22T14:05:00.000Z",
  "lastUsedAt": "2026-10-22T15:00:00.000Z"
}
```

`enabled` is always `true`. `hint` is the key's last four characters, and `voiceCount` is how many voices speak with it. Saves are limited to 10 per organization per hour, counting saves made in Lab.

### Import with your own ElevenLabs key

After you've saved a key, import any voice it can reach:

```bash cURL theme={"system"}
curl -X POST https://api.anam.ai/v1/voice-imports \
  -H "Authorization: Bearer $ANAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "ELEVENLABS",
    "providerVoiceId": "YOUR_ELEVENLABS_VOICE_ID",
    "useOrganizationKey": true,
    "displayName": "Support desk voice"
  }'
```

`useOrganizationKey` works only with `provider: "ELEVENLABS"` and a `providerVoiceId`. The request returns `201` with the new voice and a `Location` header. The voice has `isZdr: false`, so personas with Zero Data Retention can't use it, and ElevenLabs bills its speech to the account the key belongs to.

### Import with an ElevenLabs share link

```bash cURL theme={"system"}
curl -X POST https://api.anam.ai/v1/voice-imports \
  -H "Authorization: Bearer $ANAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "shareUrl": "https://elevenlabs.io/app/voice-lab/share/OWNER_ID/VOICE_ID",
    "providerModelId": "eleven_v3_conversational",
    "displayName": "Customer voice"
  }'
```

With `shareUrl`, you can also send `provider` (`"ELEVENLABS"`, or omit it), `providerModelId` and `displayName`. Any other field returns `400` `invalid_request`, and `details.issues` lists the fields you can send. The voice speaks with Anam's ElevenLabs account, so it works on personas with Zero Data Retention.

The response is `201` with the new voice and a `Location` header. If your organization already has this voice on the requested model, speaking with Anam's ElevenLabs account, Anam regenerates its preview, applies any `displayName`, and returns that voice with `200`. A copy of the same voice imported with `useOrganizationKey` doesn't count.

### Handle import errors

Every error returns JSON with a stable `code`, a `message`, `retryable` and a `requestId`. Two fields are optional:

* `details.issues` appears when the body fails validation. The top-level `message` is then just `Request validation failed`, and each issue has a `path` and a `message` that says what to change.
* `docsUrl` appears on errors with a page that explains the fix, such as `voice_not_accessible` and the `organization_key_*` errors. Don't rely on it being present.

Authentication, permission and body errors all use `invalid_request`, so tell them apart by status:

| Status | Cause | What to do |
| - | - | - |
| 401 | The API key is missing or invalid. | Send a valid key as `Authorization: Bearer`. |
| 403 | The API key doesn't have voice access (`voices:read` for `GET /v1/voices/elevenlabs-key`, `voices:write` for the rest). | Use a key with that access. |
| 400 | The body failed validation, for example an unsupported `provider`, `useOrganizationKey` with a provider other than ElevenLabs, or a field you can't send with `shareUrl`. | Fix each problem in `details.issues`. |
| 400 | The `providerModelId` isn't supported for the provider. | Use a supported model; `message` names the one you sent. There's no `details.issues`. |
| 400 | The body isn't valid JSON. | Send a JSON body. There's no `details.issues`. |

The other codes:

| `code` | Status | What to do |
| - | - | - |
| `provider_rejected` | 400 | The provider refused this voice with this model. Try another `providerModelId`. |
| `invalid_share_link` | 400 | The `shareUrl` isn't a well-formed ElevenLabs share link: `https://elevenlabs.io/app/voice-lab/share/<owner>/<voice>`. |
| `invalid_elevenlabs_key` | 400 | ElevenLabs doesn't recognize the key on any of its hosts, or you sent a Cartesia key. Copy the whole key again, or [create a new one](#create-an-elevenlabs-api-key). |
| `elevenlabs_key_missing_permissions` | 422 | ElevenLabs recognizes the key, but it doesn't have **Text to Speech** access. Edit the key in ElevenLabs, then retry with the same key. |
| `organization_key_missing` | 409 | No key is saved. Save one with `PUT /v1/voices/elevenlabs-key`, then retry. |
| `voice_bound_elsewhere` | 409 | The voice is linked to another Anam organization through its share link, or another import is reserving it. Imports with your own key aren't affected by share-link bindings. Contact Anam Support if it persists. |
| `import_in_progress` | 409 | Another import of the same voice is running. Retry shortly. |
| `voice_not_accessible` | 422 | The provider can't find the voice for this request: a wrong ID, or a private voice. For a share link, the voice can't be found, isn't shared with **Anyone with the link**, or isn't a Professional Voice Clone; `message` says which. Follow `message`, and `docsUrl` when present. |
| `organization_key_rejected` | 422 | ElevenLabs refused your saved key. Save a new key with Text to Speech access, then retry. |
| `rate_limited` | 429 | Too many key saves this hour. Retry later. |
| `provider_rate_limited` | 429 | The voice provider is limiting requests. Retry later. |
| `provider_unavailable`, `provider_timeout` | 502 or 504 | The provider didn't answer. Retry later. |
| `provider_auth_failed`, `sample_upload_failed`, `internal_error` | 502 or 500 | Retry later, or contact Anam Support with the `requestId`. |

If you're building an integration or an agent that imports voices:

* Branch on `code`, not on `message`. `message` can change wording; codes don't.
* Retry only when `retryable` is `true`, with a backoff.
* On `voice_not_accessible`, don't retry the same request. Ask which kind of voice it is, or use the table above to pick `shareUrl` or `useOrganizationKey`.
* On `organization_key_missing` or `organization_key_rejected`, save a key with `PUT /v1/voices/elevenlabs-key`, then retry the import.
* Show `message` to the person who supplied the voice. When `details.issues` is present, show each issue's `message` instead; the top-level one is generic.
* Set a client timeout above 120 seconds. If a voice ID import times out on your side, list your voices before retrying it.

## Create a voice with the API

Use [create voice](https://anam.ai/docs/api-reference/voices/create-voice.md) for programmatic cloning. The API supports audio sent as multipart form data or an uploaded audio reference.

For larger audio uploads, use [create voice presigned upload](https://anam.ai/docs/api-reference/voices/create-voice-presigned-upload.md), upload the audio to the returned URL, then pass the returned `audioKey` to create voice. Follow the API reference's upload requirements rather than assuming the Lab file formats and limits apply to the API.

## Next Steps

> [card] [Avatar Gallery](https://anam.ai/docs/personas/avatars/gallery.md)
>
> Browse available avatars to pair with your voice

> [card] [Persona Configuration](https://anam.ai/docs/personas/overview.md)
>
> Learn more about configuring personas

> [card] [Prompting Guide](https://anam.ai/docs/personas/llms/prompting-guide.md)
>
> Write effective system prompts for multilingual personas

> [card] [Authentication](https://anam.ai/docs/javascript-sdk/authentication.md)
>
> Understand session token creation


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.