# ElevenLabs

## Docs

- [Add Chapter To A Project](https://elevenlabs.io/docs/api-reference/add-chapter): Creates a new chapter either as blank or from a URL.
- [Add Project](https://elevenlabs.io/docs/api-reference/add-project): Creates a new project, it can be either initialized as blank, from a document or from a URL.
- [Add Sharing Voice](https://elevenlabs.io/docs/api-reference/add-shared-voice): Add a sharing voice to your collection of voices in VoiceLab.
- [Add Voice](https://elevenlabs.io/docs/api-reference/add-voice): Add a new voice to your collection of voices in VoiceLab.
- [Audio Isolation](https://elevenlabs.io/docs/api-reference/audio-isolation): Removes background noise from audio
- [Audio Isolation Stream](https://elevenlabs.io/docs/api-reference/audio-isolation-stream): Removes background noise from audio and streams the result
- [Convert Chapter](https://elevenlabs.io/docs/api-reference/convert-chapter): Starts conversion of a specific chapter.
- [Convert Project](https://elevenlabs.io/docs/api-reference/convert-project): Starts conversion of a project and all of its chapters.
- [Dub A Video Or An Audio File](https://elevenlabs.io/docs/api-reference/create-dub): Dubs provided audio or video file into given language.
- [Creates Audionative Enabled Project.](https://elevenlabs.io/docs/api-reference/creates-audionative-enabled-project): Creates AudioNative enabled project, optionally starts conversion and returns project id and embeddable html snippet.
- [Delete Chapter](https://elevenlabs.io/docs/api-reference/delete-chapter): Delete a chapter by its chapter_id.
- [Delete Dubbing Project](https://elevenlabs.io/docs/api-reference/delete-dub): Deletes a dubbing project.
- [Delete History Item](https://elevenlabs.io/docs/api-reference/delete-history-item): Delete a history item by its ID
- [Delete Project](https://elevenlabs.io/docs/api-reference/delete-project): Delete a project by its project_id.
- [Delete Sample](https://elevenlabs.io/docs/api-reference/delete-sample): Removes a sample by its ID.
- [Delete Voice](https://elevenlabs.io/docs/api-reference/delete-voice): Deletes a voice by its ID.
- [Download History Items](https://elevenlabs.io/docs/api-reference/download-history-items): Download one or more history items. If one history item ID is provided, we will return a single audio file. If more than one history item IDs are provided, we will provide the history items packed into a .zip file.
- [Edit Voice](https://elevenlabs.io/docs/api-reference/edit-voice): Edit a voice created by you.
- [Edit Voice Settings](https://elevenlabs.io/docs/api-reference/edit-voice-settings): Edit your settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.
- [Generate A Random Voice](https://elevenlabs.io/docs/api-reference/generate-voice): Generate a random voice based on parameters. This method returns a generated_voice_id in the response header, and a sample of the voice in the body. If you like the generated voice call /v1/voice-generation/create-voice with the generated_voice_id to create the voice.
- [Voice Generation Parameters](https://elevenlabs.io/docs/api-reference/generate-voice-parameters): Get possible parameters for the /v1/voice-generation/generate-voice endpoint.
- [Get Audio From History Item](https://elevenlabs.io/docs/api-reference/get-audio-from-history-item): Returns the audio of an history item.
- [Get Audio From Sample](https://elevenlabs.io/docs/api-reference/get-audio-from-sample): Returns the audio corresponding to a sample attached to a voice.
- [Get Chapter By Id](https://elevenlabs.io/docs/api-reference/get-chapter-by-id): Returns information about a specific chapter.
- [Get Chapter Snapshots](https://elevenlabs.io/docs/api-reference/get-chapter-snapshots): Gets information about all the snapshots of a chapter, each snapshot corresponds can be downloaded as audio. Whenever a chapter is converted a snapshot will be automatically created.
- [Get Chapters](https://elevenlabs.io/docs/api-reference/get-chapters): Returns a list of your chapters for a project together and its metadata.
- [Get Default Voice Settings.](https://elevenlabs.io/docs/api-reference/get-default-voice-settings): Gets the default settings for voices. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.
- [Get Dubbed File](https://elevenlabs.io/docs/api-reference/get-dubbed-file): Returns dubbed file as a streamed file. Videos will be returned in MP4 format and audio only dubs will be returned in MP3.
- [Get Dubbing Project Metadata](https://elevenlabs.io/docs/api-reference/get-dubbing-metadata): Returns metadata about a dubbing project, including whether it's still in progress or not
- [Get Transcript For Dub](https://elevenlabs.io/docs/api-reference/get-dubbing-transcript): Returns transcript for the dub as an SRT file.
- [Get Generated Items](https://elevenlabs.io/docs/api-reference/get-generated-items): Returns metadata about all your generated audio.
- [Get History Item By Id](https://elevenlabs.io/docs/api-reference/get-history-item-by-id): Returns information about an history item by its ID.
- [Get Models](https://elevenlabs.io/docs/api-reference/get-models): Gets a list of available models.
- [Get Project By Id](https://elevenlabs.io/docs/api-reference/get-project-by-id): Returns information about a specific project. This endpoint returns more detailed information about a project than GET api.elevenlabs.io/v1/projects.
- [Get Project Snapshots](https://elevenlabs.io/docs/api-reference/get-project-snapshots): Gets the snapshots of a project.
- [Get Projects](https://elevenlabs.io/docs/api-reference/get-projects): Returns a list of your projects together and its metadata.
- [Get User Info](https://elevenlabs.io/docs/api-reference/get-user-info): Gets information about the user
- [Get User Subscription Info](https://elevenlabs.io/docs/api-reference/get-user-subscription-info): Gets extended information about the users subscription
- [Get Voice](https://elevenlabs.io/docs/api-reference/get-voice): Returns metadata about a specific voice.
- [Get Voice Settings](https://elevenlabs.io/docs/api-reference/get-voice-settings): Returns the settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.
- [Get Voices](https://elevenlabs.io/docs/api-reference/get-voices): Gets a list of all available voices for a user.
- [API Reference Overview](https://elevenlabs.io/docs/api-reference/overview): Overview of ElevenLabs API endpoints and capabilities
- [Add from file](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-add-from-file): Creates a new pronunciation dictionary from a lexicon .PLS file
- [Get dictionary by id](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-id): Get metadata for a pronunciation dictionary
- [Add rules](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-id-add-rules): Add rules to the pronunciation dictionary
- [Remove rules](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-id-remove-rules): Remove rules from the pronunciation dictionary
- [Download version by id](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-id-version_id-download): Get PLS file with a pronunciation dictionary version rules
- [Get dictionaries](https://elevenlabs.io/docs/api-reference/pronunciation-dictionaries-list): Get a list of the pronunciation dictionaries you have access to and their metadata
- [Get Voices](https://elevenlabs.io/docs/api-reference/query-library): Gets a list of shared voices.
- [Node Library](https://elevenlabs.io/docs/api-reference/sdk-node)
- [Python Library](https://elevenlabs.io/docs/api-reference/sdk-python)
- [Sound Generation](https://elevenlabs.io/docs/api-reference/sound-generation): API that converts text into sounds & uses the most advanced AI audio model ever. Create sound effects for your videos, voice-overs or video games.
- [Speech To Speech](https://elevenlabs.io/docs/api-reference/speech-to-speech): Use Speech to Speech API to transform uploaded speech so it sounds like it was spoken by another voice. STS gives you full control over the emotions, timing and delivery.
- [Streaming](https://elevenlabs.io/docs/api-reference/speech-to-speech-streaming): Create speech by combining the content and emotion of the uploaded audio with a voice of your choice and returns an audio stream.
- [Stream Chapter Audio](https://elevenlabs.io/docs/api-reference/stream-chapter-audio): Stream the audio from a chapter snapshot. Use `GET /v1/projects/{project_id}/chapters/{chapter_id}/snapshots` to return the chapter snapshots of a chapter.
- [Stream Project Audio](https://elevenlabs.io/docs/api-reference/stream-project-audio): Stream the audio from a project snapshot.
- [Text To Speech Streaming](https://elevenlabs.io/docs/api-reference/streaming): Converts text into speech using a voice of your choice and returns audio as an audio stream.
- [Text To Speech Streaming With Timestamps](https://elevenlabs.io/docs/api-reference/streaming-with-timestamps): Converts text into audio together with timestamps on when which word was spoken in a streaming way.
- [Text To Speech](https://elevenlabs.io/docs/api-reference/text-to-speech): API that converts text into lifelike speech with best-in-class latency & uses the most advanced AI audio model ever. Create voiceovers for your videos, audiobooks, or create AI chatbots for free.
- [Text To Speech With Timestamps](https://elevenlabs.io/docs/api-reference/text-to-speech-with-timestamps): Converts text into audio together with timestamps on when which word was spoken.
- [Generate Voice Previews From Description](https://elevenlabs.io/docs/api-reference/ttv-create-previews): Generate custom voice previews based on provided voice description. The response includes a list of voice previews, each containing an id and a sample of the voice audio. If you like the voice preview and want to create a permanent voice, call `/v1/text-to-voice/create-voice-from-preview` with the corresponding voice id.
- [Create Voice From Voice Preview](https://elevenlabs.io/docs/api-reference/ttv-create-voice-from-preview): Create a new voice from previously generated voice preview. This endpoint should be called after you fetched a `generated_voice_id` using `/v1/text-to-voice/create-previews`.
- [Update Pronunciation Dictionaries](https://elevenlabs.io/docs/api-reference/update-pronunciation-dictionaries): Updates the set of pronunciation dictionaries acting on a project. This will automatically mark text within this project as requiring reconverting where the new dictionary would apply or the old one no longer does.
- [Get Characters Usage Metrics](https://elevenlabs.io/docs/api-reference/usage-get-character-stats): Returns the credit usage metrics for the current user or the entire workspace they are part of. The response will return a time axis with unix timestamps for each day and daily usage along that axis. The usage will be broken down by the specified breakdown type. For example, breakdown type "voice" will return the usage of each voice along the time axis.
- [Websockets](https://elevenlabs.io/docs/api-reference/websockets)
- [Delete Existing Invitation](https://elevenlabs.io/docs/api-reference/workspace-delete-invite): Invalidates an existing email invitation. The invitation will still show up in the inbox it has been delivered to, but activating it to join the workspace won't work. This endpoint may only be called by workspace administrators.
- [Invite User](https://elevenlabs.io/docs/api-reference/workspace-invite-user): Sends an email invitation to join your workspace to the provided email. If the user doesn't have an account they will be prompted to create one. If the user accepts this invite they will be added as a user to your workspace and your subscription using one of your seats. This endpoint may only be called by workspace administrators.
- [Update Member](https://elevenlabs.io/docs/api-reference/workspace-update-member): Updates attributes of a workspace member. Apart from the email identifier, all parameters will remain unchanged unless specified. This endpoint may only be called by workspace administrators.
- [Product Updates](https://elevenlabs.io/docs/changelog/product-updates): New updates and improvements
- [Delete Agent](https://elevenlabs.io/docs/conversational-ai/api-reference/delete-conversational-ai-agent): Delete an agent
- [Get Agent](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-agent): Retrieve config for an agent
- [Get Agents](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-agents): Returns a page of your agents and their metadata.
- [Get Conversations](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-conversation): Get all conversations of agents that user owns. With option to restrict to a specific agent.
- [Get Conversation Audio](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-conversation-audio): Get the audio recording of a particular conversation
- [Get Conversation Details](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-conversations): Get the details of a particular conversation
- [Get Knowledge Base Document](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-knowledge-base-document): Get details about a specific documentation making up the agent's knowledge base
- [Get Signed URL](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-signed-url): Get a signed url to start a conversation with an agent with an agent that requires authorization
- [Get Widget](https://elevenlabs.io/docs/conversational-ai/api-reference/get-conversational-ai-widget): Retrieve the widget configuration for an agent
- [Update Agent](https://elevenlabs.io/docs/conversational-ai/api-reference/patch-conversational-ai-agent): Patches an Agent settings
- [Create Agent](https://elevenlabs.io/docs/conversational-ai/api-reference/post-conversational-ai-agent): Create an agent from a config object
- [Create Knowledge Base Document](https://elevenlabs.io/docs/conversational-ai/api-reference/post-conversational-ai-knowledge-base-document): Uploads a file or reference a webpage for the agent to use as part of it's knowledge base
- [Create Agent Avatar](https://elevenlabs.io/docs/conversational-ai/api-reference/post-conversational-ai-widget-avatar): Sets the avatar for an agent displayed in the widget
- [WebSocket](https://elevenlabs.io/docs/conversational-ai/api-reference/websocket): Create real-time, interactive voice conversations with AI agents
- [Custom LLM Integration](https://elevenlabs.io/docs/conversational-ai/customization/byollm): Guide for using your own LLM or server with ElevenLabs SDK.
- [Conversation Customization](https://elevenlabs.io/docs/conversational-ai/customization/conversation-configuration): Learn how to customize your AI agent for each conversation & pass additional metadata to the agent.
- [Knowledge Base](https://elevenlabs.io/docs/conversational-ai/customization/knowledge-base): Learn how to enhance your conversational agent with custom knowledge
- [Tools](https://elevenlabs.io/docs/conversational-ai/customization/tools): Provide your agent with real time information and the ability to take action in third party apps with external function calls.
- [Agent Setup](https://elevenlabs.io/docs/conversational-ai/docs/agent-setup): Deploy customized, conversational voice agents in minutes.
- [Introduction](https://elevenlabs.io/docs/conversational-ai/docs/introduction): Deploy customized, conversational voice agents in minutes.
- [Next.JS](https://elevenlabs.io/docs/conversational-ai/guides/conversational-ai-guide-nextjs): Learn how to create a web application that enables voice conversations with ElevenLabs AI agents
- [Vite (Javascript)](https://elevenlabs.io/docs/conversational-ai/guides/conversational-ai-guide-vite): Learn how to create a web application that enables voice conversations with ElevenLabs AI agents
- [Twilio Integration](https://elevenlabs.io/docs/conversational-ai/guides/conversational-ai-twilio): Learn how to integrate a Conversational AI agent with Twilio to create seamless, human-like voice interactions.
- [JavaScript SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-js): Conversational AI SDK: deploy customized, interactive voice agents in minutes.
- [Python SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-python): Conversational AI SDK: deploy customized, interactive voice agents in minutes.
- [React SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-react): Conversational AI SDK: deploy customized, interactive voice agents in minutes.
- [iOS SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-swift): Conversational AI SDK: deploy customized, interactive voice agents in your Swift applications.
- [Project Examples](https://elevenlabs.io/docs/developer-guides/github-examples)
- [How to dub video and audio with ElevenLabs](https://elevenlabs.io/docs/developer-guides/how-to-dub-a-video): Learn how to automate the dubbing of audio and video files into various languages using the ElevenLabs API
- [How to Use Pronunciation Dictionaries](https://elevenlabs.io/docs/developer-guides/how-to-use-pronunciation-dictionaries): How to add, view, and remove rules to pronunciation dictionaries with the Python SDK
- [Combine Multiple Generations](https://elevenlabs.io/docs/developer-guides/how-to-use-request-stitching): Learn how to keep your voice stable across multiple generations
- [How to Use the Text to Sound Effects API](https://elevenlabs.io/docs/developer-guides/how-to-use-text-to-sound-effects): Learn how to use the text to sound effects API to generate sound effects from text.
- [How to use text to speech with streaming in Python or Node.js](https://elevenlabs.io/docs/developer-guides/how-to-use-tts-with-streaming): How to convert text into speech, upload to S3, and share with a signed URL
- [How to use text-to-speech with websocket streaming in Python or Node.js](https://elevenlabs.io/docs/developer-guides/how-to-use-websocket): How to convert text to speech via websocket and save to mp3
- [How to send an AI message through a phone call using Twilio and ElevenLabs in Node.js](https://elevenlabs.io/docs/developer-guides/integrating-with-twilio)
- [Models](https://elevenlabs.io/docs/developer-guides/models)
- [Quickstart](https://elevenlabs.io/docs/developer-guides/quickstart): Start generating your first text-to-speech using Python and ElevenLabs API
- [Reducing Latency](https://elevenlabs.io/docs/developer-guides/reducing-latency): Seven methods for reducing streaming latency, in order of highest to lowest effectiveness:
- [Specifying Server Location](https://elevenlabs.io/docs/developer-guides/specifying-server-location): How to control the server location for your requests
- [How to set up an ElevenLabs audio player for your articles in React (Next.js, Vite)](https://elevenlabs.io/docs/product/audio-native/audio-native-react)
- [How to set up an ElevenLabs audio player for your articles in Framer](https://elevenlabs.io/docs/product/audio-native/framer)
- [How to set up an ElevenLabs audio player for your articles in Ghost](https://elevenlabs.io/docs/product/audio-native/ghost)
- [Overview](https://elevenlabs.io/docs/product/audio-native/overview)
- [How to set up an ElevenLabs audio player for your articles in Squarespace](https://elevenlabs.io/docs/product/audio-native/squarespace)
- [How to add an ElevenLabs voiceover to your articles in Substack](https://elevenlabs.io/docs/product/audio-native/substack)
- [How to set up an ElevenLabs audio player for your articles in Webflow](https://elevenlabs.io/docs/product/audio-native/webflow)
- [How to set up an ElevenLabs audio player for your articles in Wix](https://elevenlabs.io/docs/product/audio-native/wix)
- [How to set up an ElevenLabs audio player for your articles in Wordpress](https://elevenlabs.io/docs/product/audio-native/wordpress)
- [Overview](https://elevenlabs.io/docs/product/dubbing/overview): Dubbing made easy: reach a broader audience with ElevenLabs.
- [Studio](https://elevenlabs.io/docs/product/dubbing/studio): The ultimate end-to-end workflow for creating amazing dubs.
- [Creating an Account](https://elevenlabs.io/docs/product/guides/creating-the-account)
- [Dubbing: Multilingual Support](https://elevenlabs.io/docs/product/guides/dubbing)
- [Overview](https://elevenlabs.io/docs/product/guides/getting-started): Step by step worflow guides.
- [Understanding the Platform Landing Page](https://elevenlabs.io/docs/product/guides/landing-page)
- [Projects: Managing Long-Form Content](https://elevenlabs.io/docs/product/guides/projects)
- [Sound Effects: From Text to Sounds](https://elevenlabs.io/docs/product/guides/sound-effects)
- [Speech Synthesis: Generating Audio](https://elevenlabs.io/docs/product/guides/speech-synthesis)
- [Voiceover Studio](https://elevenlabs.io/docs/product/guides/voiceover-studio)
- [Voices: Managing your Voices](https://elevenlabs.io/docs/product/guides/voices)
- [Workspaces: Collaborating with your team](https://elevenlabs.io/docs/product/guides/workspace)
- [Introduction](https://elevenlabs.io/docs/product/introduction): Explore our Guides and API Reference to get the most out of ElevenLabs.
- [Overview](https://elevenlabs.io/docs/product/projects/overview): An in-depth overview of using Projects
- [Overview](https://elevenlabs.io/docs/product/sound-effects/overview): Get the most out of our Sound Effects Generator tool and learn how to create everything from blockbuster sound design for films to everyday sounds for your video game.
- [Model Selection](https://elevenlabs.io/docs/product/speech-synthesis/models)
- [Overview](https://elevenlabs.io/docs/product/speech-synthesis/overview): A guide on how to generate voiceovers using your voice on ElevenLabs.
- [Prompting](https://elevenlabs.io/docs/product/speech-synthesis/prompting): Effective techniques to guide ElevenLabs AI in adding pauses, conveying emotions, and pacing the speech.
- [Overview](https://elevenlabs.io/docs/product/speech-synthesis/speech-to-speech): A guide on using our voice changer tool for the most natural-sounding speech-to-speech conversion
- [Voice Selection](https://elevenlabs.io/docs/product/speech-synthesis/voice-selection)
- [Voice Settings](https://elevenlabs.io/docs/product/speech-synthesis/voice-settings)
- [Overview](https://elevenlabs.io/docs/product/troubleshooting/overview): General troubleshooting guide and overview for some issues we've seen.
- [Overview](https://elevenlabs.io/docs/product/voiceover-studio/overview): Elevate your projects with this guide into the Voiceover Studio.
- [Default Voices](https://elevenlabs.io/docs/product/voices/default-voices): A curated set of voices for our core use cases.
- [Overview](https://elevenlabs.io/docs/product/voices/overview): Discover all the voices ElevenLabs has to offer
- [Step-by-step Guide](https://elevenlabs.io/docs/product/voices/pvc-step-by-step-guide): Step-by-step guide to creating the highest quality voice clone available
- [Instant Voice Cloning](https://elevenlabs.io/docs/product/voices/voice-lab/instant-voice-cloning): Guide for getting the most out of you cloned voices.
- [Overview](https://elevenlabs.io/docs/product/voices/voice-lab/overview): Learn more about My Voices
- [Professional Voice Cloning](https://elevenlabs.io/docs/product/voices/voice-lab/professional-voice-cloning): Guide to getting the highest quality voice clone available.
- [Voice Design](https://elevenlabs.io/docs/product/voices/voice-lab/voice-design): Generate a unique voice from a text prompt.
- [Overview](https://elevenlabs.io/docs/product/voices/voice-library/overview): Discover AI voices from the ElevenLabs community
- [Payouts](https://elevenlabs.io/docs/product/voices/voice-library/payouts): Earn rewards for sharing voices in the Voice Library
- [Sharing Voices](https://elevenlabs.io/docs/product/voices/voice-library/sharing): Learn how to share voices in the Voice Library.
- [Overview](https://elevenlabs.io/docs/product/workspace/overview): An overview on how teams can collaborate in a shared workspace.
- [SSO Setup](https://elevenlabs.io/docs/product/workspace/sso_setup): An overview on how to setup SSO (Single Sign-On) for your team.


## Optional

- [Community](https://discord.gg/elevenlabs)


# Add Chapter To A Project

post /v1/projects/{project_id}/chapters/add
Creates a new chapter either as blank or from a URL.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Add Project

post /v1/projects/add
Creates a new project, it can be either initialized as blank, from a document or from a URL.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Add Sharing Voice

post /v1/voices/add/{public_user_id}/{voice_id}
Add a sharing voice to your collection of voices in VoiceLab.



# Add Voice

post /v1/voices/add
Add a new voice to your collection of voices in VoiceLab.

## Voice Cloning API Usage

If you provide a list of file paths to audio recordings intended for voice cloning,
you confirm that you have all necessary rights or consents to upload and clone the
voice samples they contain and that you will not use the platform-generated content
for any illegal, fraudulent, or harmful purpose. You reaffirm your obligation to abide
by ElevenLabs’ [Terms of Service](https://elevenlabs.io/terms-of-use),
[Prohibited Use Policy](https://elevenlabs.io/use-policy) and
[Privacy Policy](https://elevenlabs.io/privacy-policy).


# Audio Isolation

post /v1/audio-isolation
Removes background noise from audio

## Pricing

The API is charged at 1000 characters per minute of audio.

## Removing background noise with our Python SDK

Our Audio Isolation API is what powers our Voice Isolator, which removes background noise from audio and leaves you with crystal clear dialogue. To get started, here's an example you can follow using our [Python SDK.](https://github.com/elevenlabs/elevenlabs-python)

```python
from elevenlabs.client import ElevenLabs

# Initialize the client with your API key
client = ElevenLabs(api_key="your api key")

# Path to the audio file you want to isolate
audio_file_path = "sample_file.mp3"


with open(audio_file_path, "rb") as audio_file:
    # Perform audio isolation
    isolated_audio_iterator = client.audio_isolation.audio_isolation(audio=audio_file)

    # Save the isolated audio to a new file
    output_file_path = "cleaned_file.mp3"
    with open(output_file_path, "wb") as output_file:
        for chunk in isolated_audio_iterator:
            output_file.write(chunk)


print(f"Isolated audio saved to {output_file_path}")
```


# Audio Isolation Stream

post /v1/audio-isolation/stream
Removes background noise from audio and streams the result

## Pricing

The API is charged at 1000 characters per minute of audio.


# Convert Chapter

post /v1/projects/{project_id}/chapters/{chapter_id}/convert
Starts conversion of a specific chapter.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Convert Project

post /v1/projects/{project_id}/convert
Starts conversion of a project and all of its chapters.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Dub A Video Or An Audio File

post /v1/dubbing
Dubs provided audio or video file into given language.



# Creates Audionative Enabled Project.

post /v1/audio-native
Creates AudioNative enabled project, optionally starts conversion and returns project id and embeddable html snippet.



# Delete Chapter

delete /v1/projects/{project_id}/chapters/{chapter_id}
Delete a chapter by its chapter_id.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Delete Dubbing Project

delete /v1/dubbing/{dubbing_id}
Deletes a dubbing project.



# Delete History Item

delete /v1/history/{history_item_id}
Delete a history item by its ID



# Delete Project

delete /v1/projects/{project_id}
Delete a project by its project_id.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Delete Sample

delete /v1/voices/{voice_id}/samples/{sample_id}
Removes a sample by its ID.



# Delete Voice

delete /v1/voices/{voice_id}
Deletes a voice by its ID.



# Download History Items

post /v1/history/download
Download one or more history items. If one history item ID is provided, we will return a single audio file. If more than one history item IDs are provided, we will provide the history items packed into a .zip file.



# Edit Voice

post /v1/voices/{voice_id}/edit
Edit a voice created by you.



# Edit Voice Settings

post /v1/voices/{voice_id}/settings/edit
Edit your settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.



# Generate A Random Voice

post /v1/voice-generation/generate-voice
Generate a random voice based on parameters. This method returns a generated_voice_id in the response header, and a sample of the voice in the body. If you like the generated voice call /v1/voice-generation/create-voice with the generated_voice_id to create the voice.

<Warning>This API is deprecated. Please use the new [Text to Voice API](/api-reference/ttv-create-previews).</Warning>


# Voice Generation Parameters

get /v1/voice-generation/generate-voice/parameters
Get possible parameters for the /v1/voice-generation/generate-voice endpoint.

<Warning>This API is deprecated. Please use the new [Text to Voice API](/api-reference/ttv-create-previews).</Warning>


# Get Audio From History Item

get /v1/history/{history_item_id}/audio
Returns the audio of an history item.



# Get Audio From Sample

get /v1/voices/{voice_id}/samples/{sample_id}/audio
Returns the audio corresponding to a sample attached to a voice.



# Get Chapter By Id

get /v1/projects/{project_id}/chapters/{chapter_id}
Returns information about a specific chapter.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get Chapter Snapshots

get /v1/projects/{project_id}/chapters/{chapter_id}/snapshots
Gets information about all the snapshots of a chapter, each snapshot corresponds can be downloaded as audio. Whenever a chapter is converted a snapshot will be automatically created.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get Chapters

get /v1/projects/{project_id}/chapters
Returns a list of your chapters for a project together and its metadata.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get Default Voice Settings.

get /v1/voices/settings/default
Gets the default settings for voices. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.



# Get Dubbed File

get /v1/dubbing/{dubbing_id}/audio/{language_code}
Returns dubbed file as a streamed file. Videos will be returned in MP4 format and audio only dubs will be returned in MP3.



# Get Dubbing Project Metadata

get /v1/dubbing/{dubbing_id}
Returns metadata about a dubbing project, including whether it's still in progress or not



# Get Transcript For Dub

get /v1/dubbing/{dubbing_id}/transcript/{language_code}
Returns transcript for the dub as an SRT file.



# Get Generated Items

get /v1/history
Returns metadata about all your generated audio.



# Get History Item By Id

get /v1/history/{history_item_id}
Returns information about an history item by its ID.



# Get Models

get /v1/models
Gets a list of available models.



# Get Project By Id

get /v1/projects/{project_id}
Returns information about a specific project. This endpoint returns more detailed information about a project than GET api.elevenlabs.io/v1/projects.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get Project Snapshots

get /v1/projects/{project_id}/snapshots
Gets the snapshots of a project.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get Projects

get /v1/projects
Returns a list of your projects together and its metadata.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Get User Info

get /v1/user
Gets information about the user



# Get User Subscription Info

get /v1/user/subscription
Gets extended information about the users subscription



# Get Voice

get /v1/voices/{voice_id}
Returns metadata about a specific voice.



# Get Voice Settings

get /v1/voices/{voice_id}/settings
Returns the settings for a specific voice. "similarity_boost" corresponds to"Clarity + Similarity Enhancement" in the web app and "stability" corresponds to "Stability" slider in the web app.



# Get Voices

get /v1/voices
Gets a list of all available voices for a user.



# API Reference Overview

Overview of ElevenLabs API endpoints and capabilities

<CardGroup cols={2}>
  <Card title="Text to Speech" icon="microphone-lines" href="/api-reference/text-to-speech">
    Convert text into lifelike speech with industry-leading quality and latency
  </Card>

  <Card title="Speech to Speech" icon="volume-high" href="/api-reference/speech-to-speech">
    Clone voices from audio while preserving emotion and intonation
  </Card>

  <Card title="Sound Effects" icon="waveform" href="/api-reference/sound-generation">
    Generate AI-powered sound effects and audio for any use case
  </Card>

  <Card title="Audio Isolation" icon="layer-group" href="/api-reference/audio-isolation">
    Separate speech from background noise in audio files
  </Card>

  <Card title="Conversational AI" icon="robot" href="/conversational-ai">
    Create interactive AI voice experiences with WebSocket agents
  </Card>

  <Card title="History" icon="clock-rotate-left" href="/api-reference/get-generated-items">
    Access and manage your generated audio history
  </Card>

  <Card title="User" icon="user" href="/api-reference/get-user-subscription-info">
    Access subscription information and user details
  </Card>

  <Card title="Voices" icon="folder" href="/api-reference/get-voices">
    Access and manage your custom AI voice collection
  </Card>

  <Card title="Voice Design" icon="wand-magic-sparkles" href="/api-reference/ttv-create-previews">
    Generate custom voices from text descriptions
  </Card>

  <Card title="Voice Library" icon="book-open" href="/api-reference/query-library">
    Browse and use our collection of shared voices
  </Card>

  <Card title="Projects" icon="folder-tree" href="/api-reference/pronunciation-dictionaries-add-from-file">
    Organize and manage your audio generation projects
  </Card>

  <Card title="Pronunciation" icon="language" href="/api-reference/pronunciation-dictionaries-add-from-file">
    Create and manage custom pronunciation rules
  </Card>

  <Card title="Models" icon="brain" href="/api-reference/get-models">
    Access our selection of AI voice models
  </Card>

  <Card title="Audio Native" icon="music" href="/api-reference/creates-audionative-enabled-project">
    Create and manage audio-enabled web projects
  </Card>

  <Card title="Dubbing" icon="film" href="/api-reference/create-dub">
    Automatically translate and dub audio content
  </Card>

  <Card title="Workspace" icon="users" href="/api-reference/workspace-invite-user">
    Manage team members and workspace settings
  </Card>

  <Card title="Usage" icon="chart-line" href="/api-reference/usage-get-character-stats">
    Monitor character and API usage metrics
  </Card>
</CardGroup>

<Note>
  All API endpoints require authentication using your API key. Click through to
  each section for detailed endpoint documentation.
</Note>


# Add from file

post /v1/pronunciation-dictionaries/add-from-file
Creates a new pronunciation dictionary from a lexicon .PLS file

## Adding a pronunciation dictionary

Here is some example code for uploading a [pronunciation dictionary](https://elevenlabs.io/docs/projects/overview#pronunciation-dictionaries) and printing the response `pronunciation_dictionary_id` and `version_id`. You'll require these identifiers in the request body if you intend to use `pronunciation_dictionary_locators`.

All you will need to do is replace `API_KEY_HERE` with your actual API key and `PATH_HERE` with the actual path to the PLS file you want to upload.

If you need help in understanding how to properly format a PLS / pronunciation dictionary, please refer to the guide [here](https://elevenlabs.io/docs/projects/overview#pronunciation-dictionaries).

<info>There is currently no way to fetch or update old dictionaries uploaded. Therefore, you will need to keep track of the identifiers. If you need to update the dictionary, you will have to upload a new one.</info>

```python
import requests
import os

# Define your API key and the base URL for the Eleven Labs API
XI_API_KEY = "API_KEY_HERE"
BASE_URL = "https://api.elevenlabs.io/v1"

# Setup the headers for HTTP requests to include the API key and accept JSON responses
headers = {
    "Accept": "application/json",
    "xi-api-key": XI_API_KEY
}

def upload_pronunciation_dictionary(file_path, name, description):
    """
    Uploads a pronunciation dictionary file to the Eleven Labs API and returns its ID and version ID.

    Parameters:
    - file_path: The local path to the pronunciation dictionary file.
    - name: A name for the pronunciation dictionary.
    - description: A description of the pronunciation dictionary.

    Returns:
    A tuple containing the pronunciation dictionary ID and version ID if successful, None otherwise.
    """
    # Construct the URL for adding a pronunciation dictionary from a file
    url = f"{BASE_URL}/pronunciation-dictionaries/add-from-file"
    
    # Prepare the file and data to be sent in the request
    files = {'file': open(file_path, 'rb')}
    data = {'name': name, 'description': description}
    
    # Make the POST request to upload the dictionary
    response = requests.post(url, headers=headers, files=files, data=data)
    
    # Handle the response
    if response.status_code == 200:
        # Parse the response JSON to get the pronunciation dictionary and version IDs
        data = response.json()
        pronunciation_dictionary_id = data.get('id')
        version_id = data.get('version_id')
        
        # Return the IDs
        return pronunciation_dictionary_id, version_id
    else:
        # Print an error message if the request failed
        print("Error:", response.status_code)
        return None, None

def main():
    """
    The main function to upload a pronunciation dictionary.
    """
    # Define the path to your pronunciation dictionary file and its metadata
    file_path = r"PATH_HERE"
    name = "Your Pronunciation Dictionary"
    description = "My custom pronunciation dictionary"
    
    # Upload the pronunciation dictionary and receive its ID and version ID
    pronunciation_dictionary_id, version_id = upload_pronunciation_dictionary(file_path, name, description)
    
    # Check if the upload was successful
    if pronunciation_dictionary_id and version_id:
        print("Pronunciation Dictionary Uploaded Successfully!")
        print("Pronunciation Dictionary ID:", pronunciation_dictionary_id)
        print("Version ID:", version_id)
    else:
        print("Failed to upload pronunciation dictionary.")

# Ensure this script block runs only when executed as a script, not when imported
if __name__ == "__main__":
    main()
```

## Using a pronunciation dictionary

Here is some example code on how to use these identifiers or locators in your text-to-speech call.

```python
import requests

# Set your API key and base URL
XI_API_KEY = "API_KEY_HERE"
BASE_URL = "https://api.elevenlabs.io/v1"
VOICE_ID = "TxGEqnHWrfWFTfGW9XjX"

# Headers for the request
headers = {
    "Accept": "application/json",
    "xi-api-key": XI_API_KEY
}

def text_to_speech(text, pronunciation_dictionary_id, version_id):
    """
    Sends a text to speech request using a pronunciation dictionary.
    Returns:
    An audio file.
    """
    # Define the URL for the text-to-speech endpoint
    url = f"{BASE_URL}/text-to-speech/{VOICE_ID}"
    
    # Payload for the request
    payload = {
        "model_id": "eleven_monolingual_v1",
        "pronunciation_dictionary_locators": [
            {
                "pronunciation_dictionary_id": pronunciation_dictionary_id,
                "version_id": version_id
            }
        ],
        "text": text,
        "voice_settings": {
            "stability": 0.5,
            "similarity_boost": 0.8,
            "style": 0.0,
            "use_speaker_boost": True
        }
    }
    
    # Make the POST request
    response = requests.post(url, json=payload, headers=headers)
    
    # Check the response status
    if response.status_code == 200:
        # Here you can save the audio response to a file if needed
        print("Audio file generated successfully.")
        
        # Save the audio to a file
        with open("output_audio.mp3", "wb") as audio_file:
            audio_file.write(response.content)
    else:
        print("Error:", response.status_code)

def main():
    # Example text and dictionary IDs (replace with actual values)
    text = "Hello, world! I can now use pronunciation dictionaries."
    pronunciation_dictionary_id = "PD_ID_HERE"
    version_id = "VERSION_ID_HERE"
    
    # Call the text to speech function
    text_to_speech(text, pronunciation_dictionary_id, version_id)

if __name__ == "__main__":
    main()
```


# Get dictionary by id

get /v1/pronunciation-dictionaries/{pronunciation_dictionary_id}/
Get metadata for a pronunciation dictionary



# Add rules

post /v1/pronunciation-dictionaries/{pronunciation_dictionary_id}/add-rules
Add rules to the pronunciation dictionary



# Remove rules

post /v1/pronunciation-dictionaries/{pronunciation_dictionary_id}/remove-rules
Remove rules from the pronunciation dictionary



# Download version by id

get /v1/pronunciation-dictionaries/{dictionary_id}/{version_id}/download
Get PLS file with a pronunciation dictionary version rules



# Get dictionaries

get /v1/pronunciation-dictionaries/
Get a list of the pronunciation dictionaries you have access to and their metadata



# Get Voices

get /v1/shared-voices
Gets a list of shared voices.



# Node Library





# Python Library





# Sound Generation

post /v1/sound-generation
API that converts text into sounds & uses the most advanced AI audio model ever. Create sound effects for your videos, voice-overs or video games.

## Pricing

The API is charged at 100 characters per generation with automatic duration or 25 characters per second with set duration.


# Speech To Speech

post /v1/speech-to-speech/{voice_id}
Use Speech to Speech API to transform uploaded speech so it sounds like it was spoken by another voice. STS gives you full control over the emotions, timing and delivery.

## Audio generation

Generating speech-to-speech involves a similar process to text-to-speech, but with some adjustments in the API parameters. Instead of providing text when calling the API, you provide the path to an audio file that you would like to convert from one voice to another. Here’s a modified version of your code to illustrate how to generate speech-to-speech using the given API:

```python
# Import necessary libraries
import requests  # Used for making HTTP requests
import json  # Used for working with JSON data

# Define constants for the script
CHUNK_SIZE = 1024  # Size of chunks to read/write at a time
XI_API_KEY = "<xi-api-key>"  # Your API key for authentication
VOICE_ID = "<voice-id>"  # ID of the voice model to use
AUDIO_FILE_PATH = "<path>"  # Path to the input audio file
OUTPUT_PATH = "output.mp3"  # Path to save the output audio file

# Construct the URL for the Speech-to-Speech API request
sts_url = f"https://api.elevenlabs.io/v1/speech-to-speech/{VOICE_ID}/stream"

# Set up headers for the API request, including the API key for authentication
headers = {
    "Accept": "application/json",
    "xi-api-key": XI_API_KEY
}

# Set up the data payload for the API request, including model ID and voice settings
# Note: voice settings are converted to a JSON string
data = {
    "model_id": "eleven_english_sts_v2",
    "voice_settings": json.dumps({
        "stability": 0.5,
        "similarity_boost": 0.8,
        "style": 0.0,
        "use_speaker_boost": True
    })
}

# Set up the files to send with the request, including the input audio file
files = {
    "audio": open(AUDIO_FILE_PATH, "rb")
}

# Make the POST request to the STS API with headers, data, and files, enabling streaming response
response = requests.post(sts_url, headers=headers, data=data, files=files, stream=True)

# Check if the request was successful
if response.ok:
    # Open the output file in write-binary mode
    with open(OUTPUT_PATH, "wb") as f:
        # Read the response in chunks and write to the file
        for chunk in response.iter_content(chunk_size=CHUNK_SIZE):
            f.write(chunk)
    # Inform the user of success
    print("Audio stream saved successfully.")
else:
    # Print the error message if the request was not successful
    print(response.text)
```

## Voices

We offer 1000s of voices in 29 languages. Visit the [Voice Lab](https://elevenlabs.io/voice-lab) to explore our pre-made voices or [clone your own](https://elevenlabs.io/voice-cloning). Visit the [Voices Library](https://elevenlabs.io/voice-library) to see voices generated by ElevenLabs users.

## Supported languages

Our STS API is multilingual and currently supports the following languages:

`Chinese, Korean, Dutch, Turkish, Swedish, Indonesian, Filipino, Japanese, Ukrainian, Greek, Czech, Finnish, Romanian, Russian, Danish, Bulgarian, Malay, Slovak, Croatian, Classic Arabic, Tamil, English, Polish, German, Spanish, French, Italian, Hindi and Portuguese`.

To use them, simply provide the input audio in the language of your choice.

***


# Streaming

post /v1/speech-to-speech/{voice_id}/stream
Create speech by combining the content and emotion of the uploaded audio with a voice of your choice and returns an audio stream.



# Stream Chapter Audio

post /v1/projects/{project_id}/chapters/{chapter_id}/snapshots/{chapter_snapshot_id}/stream
Stream the audio from a chapter snapshot. Use `GET /v1/projects/{project_id}/chapters/{chapter_id}/snapshots` to return the chapter snapshots of a chapter.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Stream Project Audio

post /v1/projects/{project_id}/snapshots/{project_snapshot_id}/stream
Stream the audio from a project snapshot.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>


# Text To Speech Streaming

post /v1/text-to-speech/{voice_id}/stream
Converts text into speech using a voice of your choice and returns audio as an audio stream.



# Text To Speech Streaming With Timestamps

post /v1/text-to-speech/{voice_id}/stream/with-timestamps
Converts text into audio together with timestamps on when which word was spoken in a streaming way.

## Audio generation

You can generate audio together with information on when which character was spoken in a streaming way using the following script:

```python
import requests
import json
import base64

VOICE_ID = "21m00Tcm4TlvDq8ikWAM"  # Rachel
YOUR_XI_API_KEY = "ENTER_YOUR_API_KEY_HERE"

url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream/with-timestamps"

headers = {
  "Content-Type": "application/json",
  "xi-api-key": YOUR_XI_API_KEY
}

data = {
  "text": (
    "Born and raised in the charming south, " 
    "I can add a touch of sweet southern hospitality " 
    "to your audiobooks and podcasts"
  ),
  "model_id": "eleven_multilingual_v2",
  "voice_settings": {
    "stability": 0.5,
    "similarity_boost": 0.75
  }
}


response = requests.post(
    url,
    json=data,
    headers=headers,
    stream=True
)

if response.status_code != 200:
  print(f"Error encountered, status: {response.status_code}, "
          f"content: {response.text}")
  quit()

audio_bytes = b""
characters = []
character_start_times_seconds = []
character_end_times_seconds = []
 
for line in response.iter_lines():
    if line:  # filter out keep-alive new line
        # convert the response which contains bytes into a JSON string from utf-8 encoding
        json_string = line.decode("utf-8")

        # parse the JSON string and load the data as a dictionary
        response_dict = json.loads(json_string)

        # the "audio_base64" entry in the dictionary contains the audio as a base64 encoded string, 
        # we need to decode it into bytes in order to save the audio as a file
        audio_bytes_chunk = base64.b64decode(response_dict["audio_base64"])
        audio_bytes += audio_bytes_chunk
        
        if response_dict["alignment"] is not None:
            characters.extend(response_dict["alignment"]["characters"])
            character_start_times_seconds.extend(response_dict["alignment"]["character_start_times_seconds"])
            character_end_times_seconds.extend(response_dict["alignment"]["character_end_times_seconds"])

with open('output.mp3', 'wb') as f:
  f.write(audio_bytes)

print({
    "characters": characters,
    "character_start_times_seconds": character_start_times_seconds,
    "character_end_times_seconds": character_end_times_seconds
})

```

This prints out a dictionary like:

```python
{   
    'characters': ['B', 'o', 'r', 'n', ' ', 'a', 'n', 'd', ' ', 'r', 'a', 'i', 's', 'e', 'd', ' ', 'i', 'n', ' ', 't', 'h', 'e', ' ', 'c', 'h', 'a', 'r', 'm', 'i', 'n', 'g', ' ', 's', 'o', 'u', 't', 'h', ',', ' ', 'I', ' ', 'c', 'a', 'n', ' ', 'a', 'd', 'd', ' ', 'a', ' ', 't', 'o', 'u', 'c', 'h', ' ', 'o', 'f', ' ', 's', 'w', 'e', 'e', 't', ' ', 's', 'o', 'u', 't', 'h', 'e', 'r', 'n', ' ', 'h', 'o', 's', 'p', 'i', 't', 'a', 'l', 'i', 't', 'y', ' ', 't', 'o', ' ', 'y', 'o', 'u', 'r', ' ', 'a', 'u', 'd', 'i', 'o', 'b', 'o', 'o', 'k', 's', ' ', 'a', 'n', 'd', ' ', 'p', 'o', 'd', 'c', 'a', 's', 't', 's'], 
    'character_start_times_seconds': [0.0, 0.186, 0.279, 0.348, 0.406, 0.441, 0.476, 0.499, 0.522, 0.58, 0.65, 0.72, 0.778, 0.824, 0.882, 0.906, 0.952, 0.975, 1.01, 1.045, 1.068, 1.091, 1.115, 1.149, 1.196, 1.254, 1.3, 1.358, 1.416, 1.474, 1.498, 1.521, 1.602, 1.66, 1.811, 1.869, 1.927, 1.974, 2.009, 2.043, 2.067, 2.136, 2.183, 2.218, 2.252, 2.287, 2.322, 2.357, 2.392, 2.426, 2.45, 2.508, 2.531, 2.589, 2.635, 2.682, 2.717, 2.763, 2.786, 2.81, 2.879, 2.937, 3.007, 3.065, 3.123, 3.17, 3.239, 3.286, 3.367, 3.402, 3.437, 3.46, 3.483, 3.529, 3.564, 3.599, 3.634, 3.68, 3.75, 3.82, 3.889, 3.971, 4.087, 4.168, 4.214, 4.272, 4.331, 4.389, 4.412, 4.447, 4.528, 4.551, 4.574, 4.609, 4.644, 4.702, 4.748, 4.807, 4.865, 4.923, 5.016, 5.074, 5.12, 5.155, 5.201, 5.248, 5.283, 5.306, 5.329, 5.352, 5.41, 5.457, 5.573, 5.654, 5.735, 5.886, 5.944, 6.06], 
    'character_end_times_seconds': [0.186, 0.279, 0.348, 0.406, 0.441, 0.476, 0.499, 0.522, 0.58, 0.65, 0.72, 0.778, 0.824, 0.882, 0.906, 0.952, 0.975, 1.01, 1.045, 1.068, 1.091, 1.115, 1.149, 1.196, 1.254, 1.3, 1.358, 1.416, 1.474, 1.498, 1.521, 1.602, 1.66, 1.811, 1.869, 1.927, 1.974, 2.009, 2.043, 2.067, 2.136, 2.183, 2.218, 2.252, 2.287, 2.322, 2.357, 2.392, 2.426, 2.45, 2.508, 2.531, 2.589, 2.635, 2.682, 2.717, 2.763, 2.786, 2.81, 2.879, 2.937, 3.007, 3.065, 3.123, 3.17, 3.239, 3.286, 3.367, 3.402, 3.437, 3.46, 3.483, 3.529, 3.564, 3.599, 3.634, 3.68, 3.75, 3.82, 3.889, 3.971, 4.087, 4.168, 4.214, 4.272, 4.331, 4.389, 4.412, 4.447, 4.528, 4.551, 4.574, 4.609, 4.644, 4.702, 4.748, 4.807, 4.865, 4.923, 5.016, 5.074, 5.12, 5.155, 5.201, 5.248, 5.283, 5.306, 5.329, 5.352, 5.41, 5.457, 5.573, 5.654, 5.735, 5.886, 5.944, 6.06, 6.548]
}
```

As you can see this dictionary contains three lists of the same size. For example response\_dict\['alignment']\['characters']\[3] contains the fourth character in the text you provided 'n',
response\_dict\['alignment']\['character\_start\_times\_seconds']\[3] and response\_dict\['alignment']\['character\_end\_times\_seconds']\[3] contain its start (0.348 seconds) and end (0.406 seconds) timestamps.


# Text To Speech

post /v1/text-to-speech/{voice_id}
API that converts text into lifelike speech with best-in-class latency & uses the most advanced AI audio model ever. Create voiceovers for your videos, audiobooks, or create AI chatbots for free.

***

# Introduction

Our AI model produces the highest-quality AI voices in the industry.

Our [text to speech](https://elevenlabs.io/text-to-speech) [API](https://elevenlabs.io/api) allows you to convert text into audio in 32 languages and 1000s of voices. Integrate our realistic text to speech voices into your react app, use our Python library or our websockets guide to get started.

### API Features

<Card title="High-quality voices" icon="check" iconType="duotone" color="green">
  1000s of voices, in 32 languages, for every use-case, at 128kbps
</Card>

<Card title="Ultra-low latency" icon="check" iconType="duotone" color="green">
  As low as \~300ms (+ network latency) audio generation times with our Turbo model.
</Card>

<Card title="Contextual awareness" icon="check" iconType="duotone" color="green">
  Understands text nuances for appropriate intonation and resonance.
</Card>

***

# Quick Start

## Audio generation

Generate spoken audio from text with a simple request like the following Python example:

```python
import requests

CHUNK_SIZE = 1024
url = "https://api.elevenlabs.io/v1/text-to-speech/<voice-id>"

headers = {
  "Accept": "audio/mpeg",
  "Content-Type": "application/json",
  "xi-api-key": "<xi-api-key>"
}

data = {
  "text": "Born and raised in the charming south, 
  I can add a touch of sweet southern hospitality 
  to your audiobooks and podcasts",
  "model_id": "eleven_monolingual_v1",
  "voice_settings": {
    "stability": 0.5,
    "similarity_boost": 0.5
  }
}

response = requests.post(url, json=data, headers=headers)
with open('output.mp3', 'wb') as f:
    for chunk in response.iter_content(chunk_size=CHUNK_SIZE):
        if chunk:
            f.write(chunk)
```

## Voices

We offer 1000s of voices in 29 languages. Visit the [Voice Lab](https://elevenlabs.io/voice-lab) to explore our pre-made voices or [clone your own](https://elevenlabs.io/voice-cloning). Visit the [Voices Library](https://elevenlabs.io/voice-library) to see voices generated by ElevenLabs users.

## Generation & Concurrency Limits

All our models support up to 10k characters (\~10 minutes of audio) in a single request. To achieve consistency over long form audio, try [request stitching](https://elevenlabs.io/docs/api-reference/how-to-use-request-stitching).

The concurrency limit (the maximum number of concurrent requests you can run in parallel) depends on the tier you are on.

*   Free: 2
*   Starter: 3
*   Creator: 5
*   Pro: 10
*   Scale: 15
*   Business: 15

If you need a higher limit, reach out to our [Enterprise team](https://elevenlabs.io/enterprise) to discuss a custom plan.

## Supported languages

Our TTS API is multilingual and currently supports the following languages:

`Chinese, Korean, Dutch, Turkish, Swedish, Indonesian, Filipino, Japanese, Ukrainian, Greek, Czech, Finnish, Romanian, Russian, Danish, Bulgarian, Malay, Slovak, Croatian, Classic Arabic, Tamil, English, Polish, German, Spanish, French, Italian, Hindi, Portuguese, Hungarian, Vietnamese and Norwegian`.

To use them, simply provide the input text in the language of your choice.

<CardGroup cols={2}>
  <Card title="Streaming API" icon="book-open-cover" href="/api-reference/streaming">
    Dig into the details of using the ElevenLabs TTS API.
  </Card>

  <Card title="Websockets" icon="comments" href="/api-reference/websockets">
    Learn how to use our API with websockets.
  </Card>

  <Card title="Join Our Discord" icon="discord" href="https://discord.gg/elevenlabs">
    A great place to ask questions and get help from the community.
  </Card>

  <Card title="Integration Guides" icon="rectangle-pro" href="/developer-guides/how-to-use-tts-with-streaming">
    Learn how to integrate ElevenLabs into your workflow.
  </Card>
</CardGroup>

***


# Text To Speech With Timestamps

post /v1/text-to-speech/{voice_id}/with-timestamps
Converts text into audio together with timestamps on when which word was spoken.

***

## Audio generation

You can generate audio together with information on when which character was spoken using the following script:

```python
import requests
import json
import base64

VOICE_ID = "21m00Tcm4TlvDq8ikWAM"  # Rachel
YOUR_XI_API_KEY = "ENTER_YOUR_API_KEY_HERE"

url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/with-timestamps"

headers = {
  "Content-Type": "application/json",
  "xi-api-key": YOUR_XI_API_KEY
}

data = {
  "text": (
    "Born and raised in the charming south, " 
    "I can add a touch of sweet southern hospitality " 
    "to your audiobooks and podcasts"
  ),
  "model_id": "eleven_multilingual_v2",
  "voice_settings": {
    "stability": 0.5,
    "similarity_boost": 0.75
  }
}


response = requests.post(
    url,
    json=data,
    headers=headers,
)

if response.status_code != 200:
  print(f"Error encountered, status: {response.status_code}, "
          f"content: {response.text}")
  quit()

# convert the response which contains bytes into a JSON string from utf-8 encoding
json_string = response.content.decode("utf-8")

# parse the JSON string and load the data as a dictionary
response_dict = json.loads(json_string)

# the "audio_base64" entry in the dictionary contains the audio as a base64 encoded string, 
# we need to decode it into bytes in order to save the audio as a file
audio_bytes = base64.b64decode(response_dict["audio_base64"])

with open('output.mp3', 'wb') as f:
  f.write(audio_bytes)

# the 'alignment' entry contains the mapping between input characters and their timestamps
print(response_dict['alignment'])
```

This prints out a dictionary like:

```python
{   
    'characters': ['B', 'o', 'r', 'n', ' ', 'a', 'n', 'd', ' ', 'r', 'a', 'i', 's', 'e', 'd', ' ', 'i', 'n', ' ', 't', 'h', 'e', ' ', 'c', 'h', 'a', 'r', 'm', 'i', 'n', 'g', ' ', 's', 'o', 'u', 't', 'h', ',', ' ', 'I', ' ', 'c', 'a', 'n', ' ', 'a', 'd', 'd', ' ', 'a', ' ', 't', 'o', 'u', 'c', 'h', ' ', 'o', 'f', ' ', 's', 'w', 'e', 'e', 't', ' ', 's', 'o', 'u', 't', 'h', 'e', 'r', 'n', ' ', 'h', 'o', 's', 'p', 'i', 't', 'a', 'l', 'i', 't', 'y', ' ', 't', 'o', ' ', 'y', 'o', 'u', 'r', ' ', 'a', 'u', 'd', 'i', 'o', 'b', 'o', 'o', 'k', 's', ' ', 'a', 'n', 'd', ' ', 'p', 'o', 'd', 'c', 'a', 's', 't', 's'], 
    'character_start_times_seconds': [0.0, 0.186, 0.279, 0.348, 0.406, 0.441, 0.476, 0.499, 0.522, 0.58, 0.65, 0.72, 0.778, 0.824, 0.882, 0.906, 0.952, 0.975, 1.01, 1.045, 1.068, 1.091, 1.115, 1.149, 1.196, 1.254, 1.3, 1.358, 1.416, 1.474, 1.498, 1.521, 1.602, 1.66, 1.811, 1.869, 1.927, 1.974, 2.009, 2.043, 2.067, 2.136, 2.183, 2.218, 2.252, 2.287, 2.322, 2.357, 2.392, 2.426, 2.45, 2.508, 2.531, 2.589, 2.635, 2.682, 2.717, 2.763, 2.786, 2.81, 2.879, 2.937, 3.007, 3.065, 3.123, 3.17, 3.239, 3.286, 3.367, 3.402, 3.437, 3.46, 3.483, 3.529, 3.564, 3.599, 3.634, 3.68, 3.75, 3.82, 3.889, 3.971, 4.087, 4.168, 4.214, 4.272, 4.331, 4.389, 4.412, 4.447, 4.528, 4.551, 4.574, 4.609, 4.644, 4.702, 4.748, 4.807, 4.865, 4.923, 5.016, 5.074, 5.12, 5.155, 5.201, 5.248, 5.283, 5.306, 5.329, 5.352, 5.41, 5.457, 5.573, 5.654, 5.735, 5.886, 5.944, 6.06], 
    'character_end_times_seconds': [0.186, 0.279, 0.348, 0.406, 0.441, 0.476, 0.499, 0.522, 0.58, 0.65, 0.72, 0.778, 0.824, 0.882, 0.906, 0.952, 0.975, 1.01, 1.045, 1.068, 1.091, 1.115, 1.149, 1.196, 1.254, 1.3, 1.358, 1.416, 1.474, 1.498, 1.521, 1.602, 1.66, 1.811, 1.869, 1.927, 1.974, 2.009, 2.043, 2.067, 2.136, 2.183, 2.218, 2.252, 2.287, 2.322, 2.357, 2.392, 2.426, 2.45, 2.508, 2.531, 2.589, 2.635, 2.682, 2.717, 2.763, 2.786, 2.81, 2.879, 2.937, 3.007, 3.065, 3.123, 3.17, 3.239, 3.286, 3.367, 3.402, 3.437, 3.46, 3.483, 3.529, 3.564, 3.599, 3.634, 3.68, 3.75, 3.82, 3.889, 3.971, 4.087, 4.168, 4.214, 4.272, 4.331, 4.389, 4.412, 4.447, 4.528, 4.551, 4.574, 4.609, 4.644, 4.702, 4.748, 4.807, 4.865, 4.923, 5.016, 5.074, 5.12, 5.155, 5.201, 5.248, 5.283, 5.306, 5.329, 5.352, 5.41, 5.457, 5.573, 5.654, 5.735, 5.886, 5.944, 6.06, 6.548]
}
```

As you can see this dictionary contains three lists of the same size. For example response\_dict\['alignment']\['characters']\[3] contains the fourth character in the text you provided 'n',
response\_dict\['alignment']\['character\_start\_times\_seconds']\[3] and response\_dict\['alignment']\['character\_end\_times\_seconds']\[3] contain its start (0.348 seconds) and end (0.406 seconds) timestamps.


# Generate Voice Previews From Description

post /v1/text-to-voice/create-previews
Generate custom voice previews based on provided voice description. The response includes a list of voice previews, each containing an id and a sample of the voice audio. If you like the voice preview and want to create a permanent voice, call `/v1/text-to-voice/create-voice-from-preview` with the corresponding voice id.

<Tip>
  Follow our [Voice Design Prompt
  Guide](/product/voices/voice-lab/voice-design#voice-design-prompt-guide) for
  best results.
</Tip>

When you hit generate, we'll create three voice previews. You will be charged credits equal to the length of the text you submit (you are charged this amount once per call, even though you receive three voice previews). "Text" should be no less than 100 characters and no more than 1k characters.


# Create Voice From Voice Preview

post /v1/text-to-voice/create-voice-from-preview
Create a new voice from previously generated voice preview. This endpoint should be called after you fetched a `generated_voice_id` using `/v1/text-to-voice/create-previews`.



# Update Pronunciation Dictionaries

post /v1/projects/{project_id}/update-pronunciation-dictionaries
Updates the set of pronunciation dictionaries acting on a project. This will automatically mark text within this project as requiring reconverting where the new dictionary would apply or the old one no longer does.

<Note>Projects API avaliable upon request. To get access, [contact sales](https://elevenlabs.io/contact-sales).</Note>

<Note>You can use the Pronunciation Dictionaries API to add a pronunciation dictionary from a file in order to get a valid id</Note>


# Get Characters Usage Metrics

get /v1/usage/character-stats
Returns the credit usage metrics for the current user or the entire workspace they are part of. The response will return a time axis with unix timestamps for each day and daily usage along that axis. The usage will be broken down by the specified breakdown type. For example, breakdown type "voice" will return the usage of each voice along the time axis.



# Websockets



This API provides real-time [text-to-speech](https://elevenlabs.io/text-to-speech) conversion using WebSockets. This allows you to send a text message and receive audio data back in real-time.

<Note>
  Endpoint:<br />`wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id={model}`
</Note>

# When to use

The Text-to-Speech Websockets API is designed to generate audio from partial text input while ensuring consistency throughout the generated audio. Although highly flexible, the Websockets API isn't a one-size-fits-all solution. It's well-suited for scenarios where:

*   The input text is being streamed or generated in chunks.
*   Word-to-audio alignment information is required.

For a practical demonstration in a real world application, refer to the [Example of voice streaming using ElevenLabs and OpenAI](#example-voice-streaming-using-elevenlabs-and-openai) section.

# When not to use

However, it may not be the best choice when:

*   The entire input text is available upfront. Given that the generations are partial, some buffering is involved, which could potentially result in slightly higher latency compared to a standard HTTP request.
*   You want to quickly experiment or prototype. Working with Websockets can be harder and more complex than using a standard HTTP API, which might slow down rapid development and testing.

In these cases, use the [Text to Speech API](/api-reference/text-to-speech) instead.

# Protocol

The WebSocket API uses a bidirectional protocol that encodes all messages as JSON objects.

# Streaming input text

The client can send messages with text input to the server. The messages can contain the following fields:

```json
{
  "text": "This is a sample text ",
  "voice_settings": {
    "stability": 0.8,
    "similarity_boost": 0.8
  },
  "generation_config": {
    "chunk_length_schedule": [120, 160, 250, 290]
  },
  "xi_api_key": "<XI API Key>",
  "authorization": "Bearer <Authorization Token>"
}

```

<ParamField body="text" type="string" required>
  Should always end with a single space string `" "`. In the first message, the text should be a space `" "`.
</ParamField>

<ParamField body="try_trigger_generation" type="boolean" default={false} deprecated>
  This is an advanced setting that most users shouldn't need to use. It relates to our generation schedule explained [here](#understanding-how-our-websockets-buffer-text).

  Use this to attempt to immediately trigger the generation of audio, overriding the `chunk_length_schedule`. Unlike flush, `try_trigger_generation` will only generate audio if our [buffer](#understanding-how-our-websockets-buffer-text) contains more than a minimum threshold of characters, this is to ensure a higher quality response from our model.

  Note that overriding the chunk schedule to generate small amounts of text may result in lower quality audio, therefore, only use this parameter if you really need text to be processed immediately. We generally recommend keeping the default value of `false` and adjusting the `chunk_length_schedule` in the `generation_config` instead.
</ParamField>

<ParamField body="voice_settings" type="object">
  This property should only be provided in the first message you send.

  <Expandable title="properties">
    <ParamField body="stability" type="number">
      Defines the stability for voice settings.
    </ParamField>

    <ParamField body="similarity_boost" type="number">
      Defines the similarity boost for voice settings.
    </ParamField>

    <ParamField body="style" type="number">
      Defines the style for voice settings. This parameter is available on V2+ models.
    </ParamField>

    <ParamField body="use_speaker_boost" type="boolean">
      Defines the use speaker boost for voice settings. This parameter is available on V2+ models.
    </ParamField>
  </Expandable>
</ParamField>

<a id="chunk_length_schedule" />

<ParamField body="generation_config" type="object">
  This property should only be provided in the first message you send.

  <Expandable title="properties" defaultOpen>
    <ParamField body="chunk_length_schedule" type="array">
      This is an advanced setting that most users shouldn't need to use. It relates to our generation schedule explained [here](#understanding-how-our-websockets-buffer-text).

      Determines the minimum amount of text that needs to be sent and present in our buffer before audio starts being generated. This is to maximise the amount of context available to the model to improve audio quality, whilst balancing latency of the returned audio chunks.

      The default value is: \[120, 160, 250, 290].

      This means that the first chunk of audio will not be generated until you send text that totals at least 120 characters long. The next chunk of audio will only be generated once a further 160 characters have been sent. The third audio chunk will be generated after the next 250 characters. Then the fourth, and beyond, will be generated in sets of at least 290 characters.

      Customize this array to suit your needs. If you want to generate audio more frequently to optimise latency, you can reduce the values in the array. Note that setting the values too low may result in lower quality audio. Please test and adjust as needed.

      Each item should be in the range 50-500.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="flush" type="boolean">
  Flush forces the generation of audio. Set this value to `true` when you have finished sending text, but want to keep the websocket connection open.

  This is useful when you want to ensure that the last chunk of audio is generated even when the length of text sent is smaller than the value set in `chunk_length_schedule` (e.g. 120 or 50).

  To understand more about how our websockets buffer text before audio is generated, please refer to [this](#understanding-how-our-websockets-buffer-text) section.
</ParamField>

<ParamField body="xi_api_key" type="string">
  Provide the XI API Key in the first message if it's not in the header.
</ParamField>

<ParamField body="authorization" type="string">
  Authorization bearer token. Should be provided only in the first message if not present in the header and the XI API Key is not provided.
</ParamField>

<Note>
  For best latency we recommend streaming word-by-word, this way we will start generating as soon as we reach the predefined number of un-generated characters.
</Note>

## Close connection

In order to close the connection, the client should send an End of Sequence (EOS) message. The EOS message should always be an empty string:

```json End of Sequence (EOS) message
{
    "text": ""
}
```

<ParamField body="text" type="string" required>
  Should always be an empty string `""`.
</ParamField>

## Streaming output audio

The server will always respond with a message containing the following fields:

```json Response message
{
    "audio": "Y3VyaW91cyBtaW5kcyB0aGluayBhbGlrZSA6KQ==",
    "isFinal": false,
    "normalizedAlignment": {
        "charStartTimesMs": [0, 3, 7, 9, 11, 12, 13, 15, 17, 19, 21],
        "charDurationsMs": [3, 4, 2, 2, 1, 1, 2, 2, 2, 2, 3],
        "chars": ["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
    },
    "alignment": {
        "charStartTimesMs": [0, 3, 7, 9, 11, 12, 13, 15, 17, 19, 21],
        "charDurationsMs": [3, 4, 2, 2, 1, 1, 2, 2, 2, 2, 3],
        "chars": ["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
    }
}
```

<ResponseField name="audio" type="string" optional="true">
  A generated partial audio chunk, encoded using the selected output\_format, by default this is MP3 encoded as a base64 string.
</ResponseField>

<ResponseField name="isFinal" type="boolean" optional="true">
  Indicates if the generation is complete. If set to `True`, `audio` will be null.
</ResponseField>

<ResponseField name="normalizedAlignment" type="string" optional="true">
  Alignment information for the generated audio given the input normalized text sequence.

  <Expandable title="properties">
    <ParamField body="char_start_times_ms" type="array">
      A list of starting times (in milliseconds) for each character in the normalized text as it corresponds to the audio. For instance, the character 'H' starts at time 0 ms in the audio.  Note these times are relative to the returned chunk from the model, and not the full audio response. See an example [here](#example-getting-word-start-times-using-alignment-values) for how to use this.
    </ParamField>

    <ParamField body="chars_durations_ms" type="array">
      A list providing the duration (in milliseconds) for each character's pronunciation in the audio. For instance, the character 'H' has a pronunciation duration of 3 ms.
    </ParamField>

    <ParamField body="chars" type="array">
      The list of characters in the normalized text sequence that corresponds with the timings and durations. This list is used to map the characters to their respective starting times and durations.
    </ParamField>
  </Expandable>
</ResponseField>

<ResponseField name="alignment" type="string" optional="true">
  Alignment information for the generated audio given the original text sequence.

  <Expandable title="properties">
    <ParamField body="char_start_times_ms" type="array">
      A list of starting times (in milliseconds) for each character in the original text as it corresponds to the audio. For instance, the character 'H' starts at time 0 ms in the audio. Note these times are relative to the returned chunk from the model, and not the full audio response. See an example [here](#example-getting-word-start-times-using-alignment-values) for how to use this.
    </ParamField>

    <ParamField body="chars_durations_ms" type="array">
      A list providing the duration (in milliseconds) for each character's pronunciation in the audio. For instance, the character 'H' has a pronunciation duration of 3 ms.
    </ParamField>

    <ParamField body="chars" type="array">
      The list of characters in the original text sequence that corresponds with the timings and durations. This list is used to map the characters to their respective starting times and durations.
    </ParamField>
  </Expandable>
</ResponseField>

## Path parameters

<ParamField path="voice_id" type="string">
  Voice ID to be used, you can use [Get Voices](/api-reference/get-voices) to list all the available voices.
</ParamField>

## Query parameters

<ParamField query="model_id" type="string">
  Identifier of the model that will be used, you can query them using [Get Models](/api-reference/get-models).
</ParamField>

<ParamField query="language_code" type="string">
  Language code (ISO 639-1) used to enforce a language for the model. Currently only Turbo v2.5 supports language enforcement. For other models, an error will be returned if language code is provided.
</ParamField>

<ParamField query="enable_logging" type="string">
  Whether to enable request logging, if disabled the request will not be present in history nor bigtable.
  Enabled by default. Note: simple logging (aka printing) to stdout/stderr is always enabled.
</ParamField>

<ParamField query="enable_ssml_parsing" type="boolean">
  Whether to enable/disable parsing of SSML tags within the provided text. For best results, we recommend
  sending SSML tags as fully contained messages to the websockets endpoint, otherwise this may result in additional latency.
  Please note that rendered text, in normalizedAlignment, will be altered in support of SSML tags. The
  rendered text will use a . as a placeholder for breaks, and syllables will be reported using the CMU arpabet alphabet where SSML phoneme tags are used to specify pronunciation.
  Disabled by default.
</ParamField>

<ParamField query="optimize_streaming_latency" type="string" deprecated>
  You can turn on latency optimizations at some cost of quality. The best possible final latency varies by model. Possible values:

  | Value | Description                                                                                                                                                  |
  | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | 0     | default mode (no latency optimizations)                                                                                                                      |
  | 1     | normal latency optimizations (about 50% of possible latency improvement of option 3)                                                                         |
  | 2     | strong latency optimizations (about 75% of possible latency improvement of option 3)                                                                         |
  | 3     | max latency optimizations                                                                                                                                    |
  | 4     | max latency optimizations, but also with text normalizer turned off for even more latency savings (best latency, but can mispronounce eg numbers and dates). |

  Defaults to `0`
</ParamField>

<ParamField query="output_format" type="string">
  Output format of the generated audio. Must be one of:

  | Value      | Description                                                                                                   |
  | ---------- | ------------------------------------------------------------------------------------------------------------- |
  | mp3\_44100 | default output format, mp3 with 44.1kHz sample rate                                                           |
  | pcm\_16000 | PCM format (S16LE) with 16kHz sample rate                                                                     |
  | pcm\_22050 | PCM format (S16LE) with 22.05kHz sample rate                                                                  |
  | pcm\_24000 | PCM format (S16LE) with 24kHz sample rate                                                                     |
  | pcm\_44100 | PCM format (S16LE) with 44.1kHz sample rate                                                                   |
  | ulaw\_8000 | μ-law format (mulaw) with 8kHz sample rate. (Note that this format is commonly used for Twilio audio inputs.) |

  Defaults to `mp3_44100`
</ParamField>

<ParamField query="inactivity_timeout" type="number">
  The number of seconds that the connection can be inactive before it is automatically closed.

  Defaults to `20` seconds, with a maximum allowed value of `180` seconds.
</ParamField>

<ParamField query="sync_alignment" type="boolean">
  The audio for each text sequence is delivered in multiple chunks. By default when it's set to false, you'll receive all timing data (alignment information) with the first chunk only.
  However, if you enable this option, you'll get the timing data with every audio chunk instead. This can help you precisely match each audio segment with its corresponding text.
</ParamField>

# Example - Voice streaming using ElevenLabs and OpenAI

The following example demonstrates how to leverage the ElevenLabs Websockets API to stream input from OpenAI's GPT model, while the answer is being generated, thereby minimizing the overall latency of the operation.

```python
import asyncio
import websockets
import json
import base64
import shutil
import os
import subprocess
from openai import AsyncOpenAI

# Define API keys and voice ID
OPENAI_API_KEY = '<OPENAI_API_KEY>'
ELEVENLABS_API_KEY = '<ELEVENLABS_API_KEY>'
VOICE_ID = '21m00Tcm4TlvDq8ikWAM'

# Set OpenAI API key
aclient = AsyncOpenAI(api_key=OPENAI_API_KEY)

def is_installed(lib_name):
    return shutil.which(lib_name) is not None


async def text_chunker(chunks):
    """Split text into chunks, ensuring to not break sentences."""
    splitters = (".", ",", "?", "!", ";", ":", "—", "-", "(", ")", "[", "]", "}", " ")
    buffer = ""

    async for text in chunks:
        if buffer.endswith(splitters):
            yield buffer + " "
            buffer = text
        elif text.startswith(splitters):
            yield buffer + text[0] + " "
            buffer = text[1:]
        else:
            buffer += text

    if buffer:
        yield buffer + " "


async def stream(audio_stream):
    """Stream audio data using mpv player."""
    if not is_installed("mpv"):
        raise ValueError(
            "mpv not found, necessary to stream audio. "
            "Install instructions: https://mpv.io/installation/"
        )

    mpv_process = subprocess.Popen(
        ["mpv", "--no-cache", "--no-terminal", "--", "fd://0"],
        stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
    )

    print("Started streaming audio")
    async for chunk in audio_stream:
        if chunk:
            mpv_process.stdin.write(chunk)
            mpv_process.stdin.flush()

    if mpv_process.stdin:
        mpv_process.stdin.close()
    mpv_process.wait()


async def text_to_speech_input_streaming(voice_id, text_iterator):
    """Send text to ElevenLabs API and stream the returned audio."""
    uri = f"wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id=eleven_turbo_v2_5"

    async with websockets.connect(uri) as websocket:
        await websocket.send(json.dumps({
            "text": " ",
            "voice_settings": {"stability": 0.5, "similarity_boost": 0.8},
            "xi_api_key": ELEVENLABS_API_KEY,
        }))

        async def listen():
            """Listen to the websocket for audio data and stream it."""
            while True:
                try:
                    message = await websocket.recv()
                    data = json.loads(message)
                    if data.get("audio"):
                        yield base64.b64decode(data["audio"])
                    elif data.get('isFinal'):
                        break
                except websockets.exceptions.ConnectionClosed:
                    print("Connection closed")
                    break

        listen_task = asyncio.create_task(stream(listen()))

        async for text in text_chunker(text_iterator):
            await websocket.send(json.dumps({"text": text}))

        await websocket.send(json.dumps({"text": ""}))

        await listen_task


async def chat_completion(query):
    """Retrieve text from OpenAI and pass it to the text-to-speech function."""
    response = await aclient.chat.completions.create(model='gpt-4', messages=[{'role': 'user', 'content': query}],
    temperature=1, stream=True)

    async def text_iterator():
        async for chunk in response:
            delta = chunk.choices[0].delta
            yield delta.content

    await text_to_speech_input_streaming(VOICE_ID, text_iterator())


# Main execution
if __name__ == "__main__":
    user_query = "Hello, tell me a very long story."
    asyncio.run(chat_completion(user_query))


```

# Example - Other examples for interacting with our Websocket API

Some examples for interacting with the Websocket API in different ways are provided below

<CodeGroup>
  ```python Python websockets and asyncio
  import asyncio
  import websockets
  import json
  import base64

  async def text_to_speech(voice_id):
      model = 'eleven_turbo_v2_5'
      uri = f"wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id={model}"

      async with websockets.connect(uri) as websocket:

          # Initialize the connection
          bos_message = {
              "text": " ",
              "voice_settings": {
                  "stability": 0.5,
                  "similarity_boost": 0.8
              },
              "xi_api_key": "api_key_here",  # Replace with your API key
          }
          await websocket.send(json.dumps(bos_message))

          # Send "Hello World" input
          input_message = {
              "text": "Hello World "
          }
          await websocket.send(json.dumps(input_message))

          # Send EOS message with an empty string instead of a single space
          # as mentioned in the documentation
          eos_message = {
              "text": ""
          }
          await websocket.send(json.dumps(eos_message))

          # Added a loop to handle server responses and print the data received
          while True:
              try:
                  response = await websocket.recv()
                  data = json.loads(response)
                  print("Server response:", data)

                  if data["audio"]:
                      chunk = base64.b64decode(data["audio"])
                      print("Received audio chunk")
                  else:
                      print("No audio data in the response")
                      break
              except websockets.exceptions.ConnectionClosed:
                  print("Connection closed")
                  break

  asyncio.get_event_loop().run_until_complete(text_to_speech("voice_id_here"))
  ```

  ```javascript Javascript websockets
  const voiceId = "voice_id_here"; // replace with your voice_id
  const model = 'eleven_turbo_v2_5';
  const wsUrl = `wss://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream-input?model_id=${model}`;
  const socket = new WebSocket(wsUrl);

  // 2. Initialize the connection by sending the BOS message
  socket.onopen = function (event) {
      const bosMessage = {
          "text": " ",
          "voice_settings": {
              "stability": 0.5,
              "similarity_boost": 0.8
          },
          "xi_api_key": "api_key_here", // replace with your API key
      };

      socket.send(JSON.stringify(bosMessage));

      // 3. Send the input text message ("Hello World")
      const textMessage = {
          "text": "Hello World "
      };

      socket.send(JSON.stringify(textMessage));

      // 4. Send the EOS message with an empty string
      const eosMessage = {
          "text": ""
      };

      socket.send(JSON.stringify(eosMessage));
  };

  // 5. Handle server responses
  socket.onmessage = function (event) {
      const response = JSON.parse(event.data);

      console.log("Server response:", response);

      if (response.audio) {
          // decode and handle the audio data (e.g., play it)
          const audioChunk = atob(response.audio);  // decode base64
          console.log("Received audio chunk");
      } else {
          console.log("No audio data in the response");
      }

      if (response.isFinal) {
          // the generation is complete
      }

      if (response.normalizedAlignment) {
          // use the alignment info if needed
      }
  };

  // Handle errors
  socket.onerror = function (error) {
      console.error(`WebSocket Error: ${error}`);
  };

  // Handle socket closing
  socket.onclose = function (event) {
      if (event.wasClean) {
          console.info(`Connection closed cleanly, code=${event.code}, reason=${event.reason}`);
      } else {
          console.warn('Connection died');
      }
  };
  ```

  ```python elevenlabs-python
  from elevenlabs import generate, stream

  def text_stream():
      yield "Hi there, I'm Eleven "
      yield "I'm a text to speech API "

  audio_stream = generate(
      text=text_stream(),
      voice="Nicole",
      model="eleven_turbo_v2_5",
      stream=True
  )

  stream(audio_stream)
  ```
</CodeGroup>

# Example - Getting word start times using alignment values

This code example shows how the start times of words can be retrieved using the alignment values returned from our API.

```python
import asyncio
import websockets
import json
import base64

# Define API keys and voice ID
ELEVENLABS_API_KEY = "INSERT HERE" <- INSERT YOUR API KEY HERE
VOICE_ID = 'nPczCjzI2devNBz1zQrb' #Brian

def calculate_word_start_times(alignment_info):
    # Alignment start times are indexed from the start of the audio chunk that generated them
    # In order to analyse runtime over the entire response we keep a cumulative count of played audio
    full_alignment = {'chars': [], 'charStartTimesMs': [], 'charDurationsMs': []}
    cumulative_run_time = 0
    for old_dict in alignment_info:
        full_alignment['chars'].extend([" "] + old_dict['chars'])
        full_alignment['charDurationsMs'].extend([old_dict['charStartTimesMs'][0]] + old_dict['charDurationsMs'])
        full_alignment['charStartTimesMs'].extend([0] + [time+cumulative_run_time for time in old_dict['charStartTimesMs']])
        cumulative_run_time += sum(old_dict['charDurationsMs'])
    
    # We now have the start times of every character relative to the entire audio output
    zipped_start_times = list(zip(full_alignment['chars'], full_alignment['charStartTimesMs']))
    # Get the start time of every character that appears after a space and match this to the word
    words = ''.join(full_alignment['chars']).split(" ")
    word_start_times = list(zip(words, [0] + [zipped_start_times[i+1][1] for (i, (a,b)) in enumerate(zipped_start_times) if a == ' ']))
    print(f"total duration:{cumulative_run_time}")
    print(word_start_times)


async def text_to_speech_alignment_example(voice_id, text_to_send):
    """Send text to ElevenLabs API and stream the returned audio and alignment information."""
    uri = f"wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id=eleven_turbo_v2_5"
    async with websockets.connect(uri) as websocket:
        await websocket.send(json.dumps({
            "text": " ",
            "voice_settings": {"stability": 0.5, "similarity_boost": 0.8, "use_speaker_boost": False},
            "generation_config": {
                "chunk_length_schedule": [120, 160, 250, 290]
            },
            "xi_api_key": ELEVENLABS_API_KEY,
        }))

        async def text_iterator(text):
            """Split text into chunks to mimic streaming from an LLM or similar"""
            split_text = text.split(" ")
            words = 0
            to_send = ""
            for chunk in split_text:
                to_send += chunk  + ' '
                words += 1
                if words >= 10:
                    print(to_send)
                    yield to_send
                    words = 0
                    to_send = ""
            yield to_send

        async def listen():
            """Listen to the websocket for audio data and write it to a file."""
            audio_chunks = []
            alignment_info = []
            received_final_chunk = False
            print("Listening for chunks from ElevenLabs...")
            while not received_final_chunk:
                try:
                    message = await websocket.recv()
                    data = json.loads(message)
                    if data.get("audio"):
                        audio_chunks.append(base64.b64decode(data["audio"]))
                    if data.get("alignment"):
                        alignment_info.append(data.get("alignment"))
                    if data.get('isFinal'):
                        received_final_chunk = True
                        break
                except websockets.exceptions.ConnectionClosed:
                    print("Connection closed")
                    break
            print("Writing audio to file")
            with open("output_file.mp3", "wb") as f:        
                f.write(b''.join(audio_chunks))

            calculate_word_start_times(alignment_info)


        listen_task = asyncio.create_task(listen())

        async for text in text_iterator(text_to_send):
            await websocket.send(json.dumps({"text": text}))
        await websocket.send(json.dumps({"text": " ", "flush": True}))
        await listen_task


# Main execution
if __name__ == "__main__":
    text_to_send = "The twilight sun cast its warm golden hues upon the vast rolling fields, saturating the landscape with an ethereal glow."
    asyncio.run(text_to_speech_alignment_example(VOICE_ID, text_to_send))
```

# Understanding how our websockets buffer text

Our websocket service incorporates a buffer system designed to optimize the Time To First Byte (TTFB) while maintaining high-quality streaming.

All text sent to the websocket endpoint is added to this buffer and only when that buffer reaches a certain size is an audio generation attempted. This is because our model provides higher quality audio when the model has longer inputs, and can deduce more context about how the text should be delivered.

The buffer ensures smooth audio data delivery and is automatically emptied with a final audio generation either when the stream is closed, or upon sending a `flush` command. We have advanced settings for changing the chunk schedule, which can improve latency at the cost of quality by generating audio more frequently with smaller text inputs.


# Delete Existing Invitation

delete /v1/workspace/invites
Invalidates an existing email invitation. The invitation will still show up in the inbox it has been delivered to, but activating it to join the workspace won't work. This endpoint may only be called by workspace administrators.

<Note> Workspaces are currently only available for Enterprise customers. To upgrade, [get in touch with our sales team](https://elevenlabs.io/enterprise).</Note>


# Invite User

post /v1/workspace/invites/add
Sends an email invitation to join your workspace to the provided email. If the user doesn't have an account they will be prompted to create one. If the user accepts this invite they will be added as a user to your workspace and your subscription using one of your seats. This endpoint may only be called by workspace administrators.

<Note> Workspaces are currently only available for Enterprise customers. To upgrade, [get in touch with our sales team](https://elevenlabs.io/enterprise).</Note>


# Update Member

post /v1/workspace/members
Updates attributes of a workspace member. Apart from the email identifier, all parameters will remain unchanged unless specified. This endpoint may only be called by workspace administrators.

<Note> Workspaces are currently only available for Enterprise customers. To upgrade, [get in touch with our sales team](https://elevenlabs.io/enterprise).</Note>


# Product Updates

New updates and improvements

<Update label="October 27, 2024">
  ## API Updates

  *   **u-law Audio Formats**: Added u-law audio formats to the Convai API for integrations with Twilio.
  *   **TTS Websocket Improvements**: TTS websocket improvements, flushes and generation work more intuitively now.
  *   **TTS Websocket Auto Mode**: A more streamlined mode for using websockets. This setting focuses on reducing the latency by disabling the chunk schedule and all buffers. It is only recommended when sending full sentences, sending partial sentences will result in highly reduced quality.
  *   **Improvements to latency consistency**: Improvements to latency consistency for all models.

  ## Website Updates

  *   **TTS Redesign**: The website TTS redesign is now in alpha!
</Update>

<Update label="October 20, 2024">
  ## API Updates

  *   **Normalize Text with the API**: Added the option normalize the input text in the TTS API. The new parameter is called `apply_text_normalization` and works on all non-turbo models.

  ## Feature Additions

  *   **Voice Design**: The Voice Design feature is now in beta!
</Update>

<Update label="October 13, 2024">
  ## Model Updates

  *   **Stability Improvements**: Significant improvements in the audio stability of all models, but especially noticeable on `turbo_v2` and `turbo_v2.5`, when using:
      *   Websockets
      *   Projects
      *   Reader app
      *   TTS with request stitching
      *   ConvAI
  *   **Latency Improvements**: Time to first byte latency improvements by around 20-30ms for all models.

  ## API Updates

  *   **Remove Background Noise Voice Samples**: Added the ability to remove background noise from voice samples using our audio isolation model to improve quality for IVCs and PVCs at no additional cost.
  *   **Remove Background Noise STS Input**: Added the ability to remove background noise from STS audio input using our audio isolation model to improve quality at no additional cost.

  ### Feature Additions

  *   **Conversational AI Beta**: The conversational AI feature is now in beta!
</Update>


# Delete Agent

delete /v1/convai/agents/{agent_id}
Delete an agent



# Get Agent

get /v1/convai/agents/{agent_id}
Retrieve config for an agent



# Get Agents

get /v1/convai/agents
Returns a page of your agents and their metadata.



# Get Conversations

get /v1/convai/conversations
Get all conversations of agents that user owns. With option to restrict to a specific agent.



# Get Conversation Audio

get /v1/convai/conversations/{conversation_id}/audio
Get the audio recording of a particular conversation



# Get Conversation Details

get /v1/convai/conversations/{conversation_id}
Get the details of a particular conversation



# Get Knowledge Base Document

get /v1/convai/agents/{agent_id}/knowledge-base/{documentation_id}
Get details about a specific documentation making up the agent's knowledge base



# Get Signed URL

get /v1/convai/conversation/get_signed_url
Get a signed url to start a conversation with an agent with an agent that requires authorization



# Get Widget

get /v1/convai/agents/{agent_id}/widget
Retrieve the widget configuration for an agent



# Update Agent

patch /v1/convai/agents/{agent_id}
Patches an Agent settings



# Create Agent

post /v1/convai/agents/create
Create an agent from a config object



# Create Knowledge Base Document

post /v1/convai/agents/{agent_id}/add-to-knowledge-base
Uploads a file or reference a webpage for the agent to use as part of it's knowledge base



# Create Agent Avatar

post /v1/convai/agents/{agent_id}/avatar
Sets the avatar for an agent displayed in the widget



# WebSocket

Create real-time, interactive voice conversations with AI agents

<Note>
  This documentation is for developers integrating directly with the ElevenLabs
  WebSocket API. For convenience, consider using [the official SDKs provided by
  ElevenLabs](/conversational-ai/docs/introduction).
</Note>

The ElevenLabs [Conversational AI](https://elevenlabs.io/conversational-ai) WebSocket API enables real-time, interactive voice conversations with AI agents. By establishing a WebSocket connection, you can send audio input and receive audio responses in real-time, creating life-like conversational experiences.

<Note>
  Endpoint: `wss://api.elevenlabs.io/v1/convai/conversation?agent_id={agent_id}`
</Note>

## Authentication

### Using Agent ID

For public agents, you can directly use the `agent_id` in the WebSocket URL without additional authentication:

```bash
wss://api.elevenlabs.io/v1/convai/conversation?agent_id=<your-agent-id>
```

### Using a Signed URL

For private agents or conversations requiring authorization, obtain a signed URL from your server, which securely communicates with the ElevenLabs API using your API key.

### Example using cURL

**Request:**

```bash
curl -X GET "https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=<your-agent-id>" \
     -H "xi-api-key: <your-api-key>"
```

**Response:**

```json
{
  "signed_url": "wss://api.elevenlabs.io/v1/convai/conversation?agent_id=<your-agent-id>&token=<token>"
}
```

<Warning>Never expose your ElevenLabs API key on the client side.</Warning>

## Communication

### Client-to-Server Messages

#### User Audio Chunk

Send audio data from the user to the server.

**Format:**

```json
{
  "user_audio_chunk": "<base64-encoded-audio-data>"
}
```

**Notes:**

*   **Audio Format Requirements:**

    *   PCM 16-bit mono format
    *   Base64 encoded
    *   Sample rate of 16,000 Hz

*   **Recommended Chunk Duration:**

    *   Send audio chunks approximately every **250 milliseconds (0.25 seconds)**
    *   This equates to chunks of about **4,000 samples** at a 16,000 Hz sample rate

*   **Optimizing Latency and Efficiency:**
    *   **Balance Latency and Efficiency:** Sending audio chunks every 250 milliseconds offers a good trade-off between responsiveness and network overhead.
    *   **Adjust Based on Needs:**
        *   *Lower Latency Requirements:* Decrease the chunk duration to send smaller chunks more frequently.
        *   *Higher Efficiency Requirements:* Increase the chunk duration to send larger chunks less frequently.
    *   **Network Conditions:** Adapt the chunk size if you experience network constraints or variability.

#### Pong Message

Respond to server `ping` messages by sending a `pong` message, ensuring the `event_id` matches the one received in the `ping` message.

**Format:**

```json
{
  "type": "pong",
  "event_id": 12345
}
```

### Server-to-Client Messages

#### conversation\_initiation\_metadata

Provides initial metadata about the conversation.

**Format:**

```json
{
  "type": "conversation_initiation_metadata",
  "conversation_initiation_metadata_event": {
    "conversation_id": "conv_123456789",
    "agent_output_audio_format": "pcm_16000"
  }
}
```

### Other Server-to-Client Messages

| Type             | Purpose                                             |
| ---------------- | --------------------------------------------------- |
| user\_transcript | Transcriptions of the user's speech                 |
| agent\_response  | Agent's textual response                            |
| audio            | Chunks of the agent's audio response                |
| interruption     | Indicates that the agent's response was interrupted |
| ping             | Server pings to measure latency                     |

##### Message Formats

**user\_transcript:**

```json
{
  "type": "user_transcript",
  "user_transcription_event": {
    "user_transcript": "Hello, how are you today?"
  }
}
```

**agent\_response:**

```json
{
  "type": "agent_response",
  "agent_response_event": {
    "agent_response": "Hello! I'm doing well, thank you for asking. How can I assist you today?"
  }
}
```

**audio:**

```json
{
  "type": "audio",
  "audio_event": {
    "audio_base_64": "SGVsbG8sIHRoaXMgaXMgYSBzYW1wbGUgYXVkaW8gY2h1bms=",
    "event_id": 67890
  }
}
```

**interruption:**

```json
{
  "type": "interruption",
  "interruption_event": {
    "event_id": 54321
  }
}
```

**internal\_tentative\_agent\_response:**

```json
{
  "type": "internal_tentative_agent_response",
  "tentative_agent_response_internal_event": {
    "tentative_agent_response": "I'm thinking about how to respond..."
  }
}
```

**ping:**

```json
{
  "type": "ping",
  "ping_event": {
    "event_id": 13579,
    "ping_ms": 50
  }
}
```

## Latency Management

To ensure smooth conversations, implement these strategies:

*   **Adaptive Buffering:** Adjust audio buffering based on network conditions.
*   **Jitter Buffer:** Implement a jitter buffer to smooth out variations in packet arrival times.
*   **Ping-Pong Monitoring:** Use ping and pong events to measure round-trip time and adjust accordingly.

## Security Best Practices

*   Rotate API keys regularly and use environment variables to store them.
*   Implement rate limiting to prevent abuse.
*   Clearly explain the intention when prompting users for microphone access.
*   Optimized Chunking: Tweak the audio chunk duration to balance latency and efficiency.

## Additional Resources

*   [ElevenLabs Conversational AI Documentation](https://elevenlabs.io/docs/conversational-ai/overview)
*   [ElevenLabs Conversational AI SDKs](https://elevenlabs.io/docs/conversational-ai/client-sdk)


# Custom LLM Integration

Guide for using your own LLM or server with ElevenLabs SDK.

## Using Your Own OpenAI Key for LLM

To integrate a custom OpenAI key, create a secret containing your OPENAI\_API\_KEY:

<Steps>
  <Step>
    Navigate to the "Secrets" page and select "Add Secret"

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_1.png" />
  </Step>

  <Step>
    Choose "Custom LLM" from the dropdown menu.

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_2.png" />
  </Step>

  <Step>
    Enter the URL, your model, and the secret you created.

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_3.png" />
  </Step>
</Steps>

## Custom LLM Server

To bring a custom LLM server, set up a compatible server endpoint using OpenAI's style, specifically targeting create\_chat\_completion.

Here's an example server implementation using FastAPI and OpenAI's Python SDK:

```python
import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional

# Load environment variables from .env file
load_dotenv()

# Retrieve API key from environment
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY not found in environment variables")

app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    messages: List[Message]
    model: str
    temperature: Optional[float] = 0.7
    max_tokens: Optional[int] = None
    stream: Optional[bool] = False
    user_id: Optional[str] = None

@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
    oai_request = request.dict(exclude_none=True)
    if "user_id" in oai_request:
        oai_request["user"] = oai_request.pop("user_id")

    chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)

    async def event_stream():
        try:
            async for chunk in chat_completion_coroutine:
                # Convert the ChatCompletionChunk to a dictionary before JSON serialization
                chunk_dict = chunk.model_dump()
                yield f"data: {json.dumps(chunk_dict)}\n\n"
            yield "data: [DONE]\n\n"
        except Exception as e:
            logging.error("An error occurred: %s", str(e))
            yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8013)
```

Run this code or your own server code.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_4.png" />

### Setting Up a Public URL for Your Server

To make your server accessible, create a public URL using a tunneling tool like ngrok:

```shell
ngrok http --url=<Your url>.ngrok.app 8013
```

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_5.png" />

### Configuring Elevenlabs CustomLLM

Now let's make the changes in Elevenlabs

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/byollm_6.png" />

Direct your server URL to ngrok endpoint, also setup "Limit token usage" to 5000.

You can start interacting with Conversational AI with your own LLM server


# Conversation Customization

Learn how to customize your AI agent for each conversation & pass additional metadata to the agent.

Learn how to customize your AI agent for each conversation by adding personalized details and passing custom parameters. For example, greet users by their name, adjust responses based on account-specific data, or include metadata to enhance interactions.

## What You'll Need

*   An [ElevenLabs account](https://elevenlabs.io)
*   A configured ElevenLabs Conversational Agent ([create one here](/conversational-ai/docs/agent-setup))
*   Python 3.7+ or Node.js 16+

## Agent Conversation Overrides

In ElevenLabs Conversational AI, you typically define a top-level agent with default settings. This feature allows you to create tailored voice experiences, without creating new agents.

<Frame>
  <img width="500" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/configuration-1.png" />
</Frame>

The following steps will show you how to configure the `prompt` & `first_message` on setup to greet the user by their name.

<Tabs>
  <Tab title="Javascript">
    <Tip>
      Ensure you have the latest [Javascript](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-js)/[React SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-react) installed.
    </Tip>

    <Steps>
      <Step>
        ```javascript
        const conversation = await Conversation.startSession({
          ...
          overrides: {
              agent: {
                  prompt: {
                      prompt: `The customer's bank account balance is ${customer_balance}. They are based in ${customer_location}.`
                  },
                  first_message: `Hi ${customer_name}, how can I help you today?`,
              },
              tts: {
                  voiceId: "" // override the voice id.
              }
          },
          ...
        })
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Python">
    <Tip>
      Ensure you have the latest [Python SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-python) installed.
    </Tip>

    <Steps>
      <Step title="Define the Conversation Override">
        ```python
        from elevenlabs.conversational_ai.conversation import Conversation, ConversationConfig

        # dynamically change the first message based on the user's name
        conversation_override = {
            "agent": {
                "prompt": {
                    "prompt": f"The customer's bank account balance is {customer_balance}. They are based in {customer_location}."
                },
                "first_message": f"Hi {customer_name}, how can I help you today?",
                "language": <insert-override-language-here>,
            },
            "tts": {
                "voice_id": "iP95p4xoKVk53GoZ742B" # Override the voice
            }
        }

        config = ConversationConfig(
            conversation_config_override=conversation_override
        )
        conversation = Conversation(
            ...
            config=config,
            ...
        )
        ```
      </Step>

      <Step title="Start the Session">
        ```python
        conversation.start_session()
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Swift">
    <Tip>
      Ensure you have the latest [Swift SDK](https://elevenlabs.io/docs/conversational-ai/libraries/conversational-ai-sdk-swift) installed.
    </Tip>

    <Steps>
      <Step title="Define the Conversation Override">
        ```swift
        import ElevenLabsSDK

        let promptOverride = ElevenLabsSDK.AgentPrompt(
            prompt: "The customer's bank account balance is \(customer_balance). They are based in \(customer_location)."
        )

        let agentConfig = ElevenLabsSDK.AgentConfig(
            prompt: promptOverride,
            firstMessage: "Hi \(customer_name), how can I help you today?",
            language: .en
        )

        let overrides = ElevenLabsSDK.ConversationConfigOverride(
            agent: agentConfig,
            tts: TTSConfig(voiceId: "custom_voice_id") // Override the voice
        )

        let config = ElevenLabsSDK.SessionConfig(
            agentId: agent.id,
            overrides: overrides
        )
        ```
      </Step>

      <Step title="Start the Conversation">
        ```swift
        ...
        let conversation = try await ElevenLabsSDK.Conversation.startSession(
            config: config,
            callbacks: callbacks
        )
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

With this agent override feature, you can now create a single agent and customize it with every customer conversation.

## Custom LLM Parameters

Similarly, you may pass additional parameters to your custom LLM implementation.

<Tabs>
  <Tab title="Python">
    <Steps>
      <Step title="Define the Extra Parameters">
        Create an object containing your custom parameters:

        ```python
        from elevenlabs.conversational_ai.conversation import Conversation, ConversationConfig

        extra_body_for_convai = {
            "UUID": "123e4567-e89b-12d3-a456-426614174000",
            "parameter-1": "value-1",
            "parameter-2": "value-2",
        }

        config = ConversationConfig(
            extra_body=extra_body_for_convai,
        )
        ```
      </Step>

      <Step title="Update the LLM Implementation">
        Modify your custom LLM code to handle the additional parameters:

        ```python
        import json
        import os
        import fastapi
        from fastapi.responses import StreamingResponse
        from fastapi import Request
        from openai import AsyncOpenAI
        import uvicorn
        import logging
        from dotenv import load_dotenv
        from pydantic import BaseModel
        from typing import List, Optional

        # Load environment variables from .env file
        load_dotenv()

        # Retrieve API key from environment
        OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
        if not OPENAI_API_KEY:
            raise ValueError("OPENAI_API_KEY not found in environment variables")

        app = fastapi.FastAPI()
        oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)

        class Message(BaseModel):
            role: str
            content: str

        class ChatCompletionRequest(BaseModel):
            messages: List[Message]
            model: str
            temperature: Optional[float] = 0.7
            max_tokens: Optional[int] = None
            stream: Optional[bool] = False
            user_id: Optional[str] = None
            elevenlabs_extra_body: Optional[dict] = None

        @app.post("/v1/chat/completions")
        async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
            oai_request = request.dict(exclude_none=True)
            print(oai_request)
            if "user_id" in oai_request:
                oai_request["user"] = oai_request.pop("user_id")

            if "elevenlabs_extra_body" in oai_request:
                oai_request.pop("elevenlabs_extra_body")

            chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)

            async def event_stream():
                try:
                    async for chunk in chat_completion_coroutine:
                        chunk_dict = chunk.model_dump()
                        yield f"data: {json.dumps(chunk_dict)}\n\n"
                    yield "data: [DONE]\n\n"
                except Exception as e:
                    logging.error("An error occurred: %s", str(e))
                    yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"

            return StreamingResponse(event_stream(), media_type="text/event-stream")

        if __name__ == "__main__":
            uvicorn.run(app, host="0.0.0.0", port=8013)
        ```
      </Step>
    </Steps>

    ### Example Request

    With this custom message setup, your LLM will receive requests in this format:

    ```json
    {
      "messages": [
        {
          "role": "system",
          "content": "\n  <Redacted>"
        },
        {
          "role": "assistant",
          "content": "Hey I'm currently unavailable."
        },
        {
          "role": "user",
          "content": "Hey, who are you?"
        }
      ],
      "model": "gpt-4o",
      "temperature": 0.5,
      "max_tokens": 5000,
      "stream": true,
      "elevenlabs_extra_body": {
        "UUID": "123e4567-e89b-12d3-a456-426614174000",
        "parameter-1": "value-1",
        "parameter-2": "value-2"
      }
    }
    ```
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Configuration Issues">
    If the configuration override isn't working:

    *   Verify the configuration structure matches the expected format
    *   Check that all required fields are present
    *   Ensure the config object is properly passed to the Conversation constructor
  </Accordion>

  <Accordion title="LLM Parameter Problems">
    If custom parameters aren't being received:

    *   Confirm the extra\_body is properly structured
    *   Verify the LLM implementation is handling the elevenlabs\_extra\_body field
    *   Check the request payload in your LLM logs
  </Accordion>
</AccordionGroup>


# Knowledge Base

Learn how to enhance your conversational agent with custom knowledge

Knowledge bases allow you to provide additional context to your conversational
agent beyond its base LLM knowledge.

<Note>
  Non-enterprise users can add up to 5 files/links (max 20MB, 300,000 characters
  total).
</Note>

## Adding Knowledge Items

There are 3 options to enhance your conversational agent's knowledge:

### 1. File Upload

<Frame>
  <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/knowledge-base-1.png" alt="File upload interface showing supported formats (PDF, TXT, DOCX, HTML, EPUB) with a 21MB size limit" />
</Frame>

### 2. URL Import

<Frame>
  <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/knowledge-base-2.png" alt="URL import interface where users can paste documentation links" />
</Frame>

<Warning>
  Ensure you have permission to use the content from the URLs you provide
</Warning>

### 3. Direct Text Input

<Frame>
  <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/knowledge-base-3.png" alt="Text input interface where users can name and add custom content" />
</Frame>

## Best Practices

<CardGroup cols={2}>
  <Card title="Content Quality" icon="star">
    Provide clear, well-structured information that's relevant to your agent's
    purpose
  </Card>

  <Card title="Size Management" icon="hard-drive">
    Break large documents into smaller, focused pieces for better processing
  </Card>
</CardGroup>

## Enterprise Features

<Info>
  Need higher limits? Contact our sales team to discuss enterprise plans with
  expanded knowledge base capabilities.
</Info>


# Tools

Provide your agent with real time information and the ability to take action in third party apps with external function calls.

Tools allow you to make external function calls to third party apps so you can get real-time information. You might use tools to:

<CardGroup>
  <Card title="Calendar Management" icon="calendar">
    Schedule appointments and manage availability on someone's calendar
  </Card>

  <Card title="Restaurant Bookings" icon="utensils">
    Book restaurant reservations and manage dining arrangements
  </Card>

  <Card title="CRM Integration" icon="users">
    Create or update customer records in a CRM system
  </Card>

  <Card title="Inventory Lookup" icon="box">
    Get inventory data to make product recommendations
  </Card>
</CardGroup>

To help you get started with Tools, we'll walk through an "AI receptionist" we created by integrating with the Cal.com API.

<iframe width="100%" height="400" src="https://www.youtube.com/embed/C2SpW339vqY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

## Tools Overview

### Secrets

Before we proceed with creating our Tools, we will first create a Secret to securely store our API keys. The Cal.com API we will use for our example takes a Bearer token so we will first add a Secret named "Bearer" and provide the Bearer token as the value.

You can find Secrets within the Conversational AI Dashboard in the Agent subnav.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/bearer-secret.png" />

### Webhooks

Next, look for "Tools" in the "Agent" subnav. Add a new Tool to configure your webhook. For our AI receptionist, we created two Tools to interact with the Cal.com API:

<AccordionGroup>
  <Accordion title="Get Available Slots" icon="calendar-check">
    This tool allows the AI receptionist to check calendar availability. It can answer questions like "When is Sam available to meet tomorrow?" or "Is Sam free at 10:30am on Tuesday?"

    ```bash
    Name: Get_Available_Slots
    Method: GET
    URL: https://api.cal.com/v2/slots/available
    ```

    Uses Cal.com's [Get Available Slots](https://cal.com/docs/api-reference/v2/slots/get-available-slots#get-available-slots) endpoint to fetch open calendar slots within a specified date/time range.
  </Accordion>

  <Accordion title="Book Meeting" icon="calendar-plus">
    This tool handles the actual meeting booking once a suitable time has been selected.

    ```bash
    Name: Book_Meeting
    Method: POST
    URL: https://api.cal.com/v2/bookings
    ```

    Uses Cal.com's [Create a booking](https://cal.com/docs/api-reference/v2/bookings/create-a-booking#create-a-booking) endpoint. This should only be called after collecting:

    *   Caller's full name
    *   Meeting time
    *   Email address
  </Accordion>
</AccordionGroup>

### Headers

Within the Cal.com documentation, we see that both our availability and booking endpoints require the same three headers:

```bash
Content-Type: application/json
cal-api-version: 2024-08-13
Authorization: Bearer <your-bearer-token>
```

We configured that as follows:

| Type   | Name            | Value                                      |
| ------ | --------------- | ------------------------------------------ |
| Value  | Content-Type    | application/json                           |
| Value  | cal-api-version | 2024-08-13                                 |
| Secret | Bearer          | Bearer (the secret key we defined earlier) |

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/headers.png" />
</Frame>

### Path Parameters

You can add path parameters by including variables surrounded by curly brackets in your URL like this {variable}. Once added to the URL path, it will appear under Path Parameters with the ability to update the Data Type and Description.
Our AI receptionist does not call for Path Parameters so we will not be defining any.

### Query Parameters

Get and Delete requests typically have query parameters while Post and Patch do not. Our Get\_Available\_Slots tool relies on a Get request that requires the following query parameters: startTime, endTime, eventTypeId, eventTypeSlug, and duration.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/cal-get-slots.png" />

In our Description for each, we define a prompt that our Conversational Agent will use to extract the relevant information from the call transcript using an LLM.

Here's how we defined our query parameters for our AI receptionist:

| Identifier    | Data Type | Required | Description                                                                                                                                                                                      |
| ------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| startTime     | String    | Yes      | The start time of the slot the person is checking availability for in UTC timezone, formatted as ISO 8601 (e.g., '2024-08-13T09:00:00Z'). Extract time from natural language and convert to UTC. |
| endTime       | String    | Yes      | The end time of the slot the person is checking availability for in UTC timezone, formatted as ISO 8601 (e.g., '2024-08-13T09:00:00Z'). Extract time from natural language and convert to UTC.   |
| eventTypeSlug | String    | Yes      | The desired meeting length. Should be 15minutes, 30minutes, or 60minutes.                                                                                                                        |
| eventTypeId   | Number    | Yes      | The desired meeting length, as an event id. If 15 minutes, return 1351800. If 30 minutes, return 1351801. If 60 minutes, return 1351802.                                                         |

### Body Parameters

Post and Patch requests typically have body parameters while Get and Delete do not. Our Book\_Meeting tool is a Post request and requires the following Body Parameters: startTime, eventTypeId, attendee.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/cal-book-meeting.png" />

In our Description for each, we define a prompt that our Conversational Agent will use to extract the relevant information from the call transcript using an LLM.

Here's how we defined our body parameters for our AI receptionist:

| Identifier  | Data Type | Required | Description                                                                                                                                                                                                      |
| ----------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| startTime   | String    | Yes      | The start time of the slot the person is checking availability for in UTC timezone, formatted as ISO 8601 (e.g., '2024-08-13T09:00:00Z'). Extract time from natural language and convert to UTC.                 |
| eventTypeId | String    | Yes      | The unique Cal event ID for the meeting duration. Use 1351800 for a 15-minute meeting, 1351801 for 30 minutes, and 1351802 for 60 minutes. If no specific duration is provided, default to 1351801 (30 minutes). |
| attendee    | Object    | Yes      | The info on the attendee including their full name, email address and time zone.                                                                                                                                 |

Since attendee is an object, it's subfields are defined as their own parameters:

| Identifier | Data Type | Required | Description                                                                                                     |
| ---------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| name       | String    | Yes      | The full name of the person booking the meeting.                                                                |
| email      | String    | Yes      | The email address of the person booking the meeting. Should be a properly formatted email.                      |
| timeZone   | String    | Yes      | The caller's timezone. Should be in the format of 'Continent/City' like 'Europe/London' or 'America/New\_York'. |

### Adjusting System Prompt to reference your Tools

Now that you've defined your Tools, instruct your agent on when and how to invoke them in your system prompt. If your Tools require the user to provide information, it's best to ask your agent to collect that information before calling it (though in many cases your agent will be able to realize it is missing information and will request for it anyway).

Here's the System Prompt we use for our AI Receptionist:

> You are my receptionist and people are calling to book a time with me.
>
> You can check my availability by using Get\_Available\_Slots. That endpoint takes start and end date/time and returns open slots in between. If someone asks for my availability but doesn't specify a date / time, just check for open slots tomorrow. If someone is checking availability and there are no open slots, keep checking the next day until you find one with availability.
>
> Once you've agreed upon a time to meet, you can use Book\_Meeting to book a call.
> You will need to collect their full name, the time they want to meet, whether they want to meet for 15, 30 or 60 minutes, and their email address to book a meeting.
>
> If you call Book\_Meeting and it fails, it's likely either that the email address is formatted in an invalid way or the selected time is not one where I am available.


# Agent Setup

Deploy customized, conversational voice agents in minutes.

<iframe width="100%" height="400" src="https://www.youtube.com/embed/TFIudjLTrQM" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

## The Web Dashboard

The easiest way to get started with ElevenLabs Conversational AI is through our web dashboard.

You can access your dashboard [here](https://elevenlabs.io/sign-up). The web dashboard enables you to:

*   Create and manage AI assistants
*   Configure voice settings and conversation parameters
*   Review conversation analytics and transcripts
*   Manage API keys and integration settings

<Note>
  The web dashboard uses our Web SDK (link to it) under the hood to handle
  real-time conversations.
</Note>

## Pierogi Palace Assistant

In this guide, we'll create an AI assistant for "Pierogi Palace" - a modern Polish restaurant that takes orders through voice conversations. Our assistant will help customers order traditional Polish dishes with a contemporary twist.

<Frame caption="The Pierogi Palace menu showcases traditional Polish dishes that customers can order through the AI assistant">
  ![Pierogi Palace](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/pierogi-palace.png)
</Frame>

The assistant will guide customers through:

*   **Menu Selection**

    *   Various pierogi options with traditional and modern fillings
    *   Portion sizes (available in dozens)

*   **Order Details**

    *   Quantity confirmation
    *   Price calculation in Polish złoty
    *   Order review and modifications if needed

*   **Delivery Information**
    *   Delivery address collection
    *   Estimated preparation time (10 minutes)
    *   Delivery time calculation based on location
    *   Payment method confirmation (cash on delivery)

## Assistant Setup

In this guide, we'll walk through configuring your **Pierogi Palace** assistant using ElevenLabs Conversational AI. We'll set up the assistant's voice, language model, and transcription settings to help customers place orders seamlessly.

### Prerequisites

*   An [ElevenLabs account](https://www.elevenlabs.io)

### 1. Access the Dashboard

<Steps>
  <Step title="Sign In to ElevenLabs">
    Go to [elevenlabs.io](https://elevenlabs.io/sign-up) and sign in to your account.
  </Step>

  <Step title="Navigate to Conversational AI">
    In the ElevenLabs dashboard, click on **Conversational AI** in the left sidebar.{" "}

    <Frame caption="Navigating to the Conversational AI section">
      ![Dashboard](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-1.png)
    </Frame>
  </Step>
</Steps>

### 2. Create Your Assistant

<Steps>
  <Step title="Start Creating a New Assistant">
    *   Click the **+** button to create a new AI Agent.
    *   Choose the **Blank Template** option & call the agent `Pierogi Palace`.

    <Frame caption="Creating a new assistant">
      ![Create New Assistant](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-2.png)
    </Frame>
  </Step>

  <Step title="Configure Assistant Details">
    Set the `First message` & `System prompt` fields to the following, leaving the **Knowledge Base** and **Tools** empty for now:

    <CodeGroup>
      ```plaintext Greeting Message
      Welcome to Pierogi Palace! I'm here to help you place your order. What can I get started for you today?
      ```

      ```plaintext System Prompt
      You are a friendly and efficient virtual assistant for Pierogi Palace, a modern Polish restaurant specializing in pierogis. It is located in the Zakopane mountains in Poland.
      Your role is to help customers place orders over voice conversations. You have comprehensive knowledge of the menu items and their prices.

      Menu Items:

      - Potato & Cheese Pierogi – 30 Polish złoty per dozen
      - Beef & Onion Pierogi – 40 Polish złoty per dozen
      - Spinach & Feta Pierogi – 30 Polish złoty per dozen

      Your Tasks:

      1. Greet the Customer: Start with a warm welcome and ask how you can assist.
      2. Take the Order: Listen carefully to the customer's selection, confirm the type and quantity of pierogis.
      3. Confirm Order Details: Repeat the order back to the customer for confirmation.
      4. Calculate Total Price: Compute the total cost based on the items ordered.
      5. Collect Delivery Information: Ask for the customer's delivery address to estimate delivery time.
      6. Estimate Delivery Time: Inform the customer that cooking time is 10 minutes plus delivery time based on their location.
      7. Provide Order Summary: Give the customer a summary of their order, total price, and estimated delivery time.
      8. Close the Conversation: Thank the customer and let them know their order is being prepared.

      Guidelines:

      - Use a friendly and professional tone throughout the conversation.
      - Be patient and attentive to the customer's needs.
      - If unsure about any information, politely ask the customer to repeat or clarify.
      - Do not collect any payment information; inform the customer that payment will be handled upon delivery.
      - Avoid discussing topics unrelated to taking and managing the order.
      ```
    </CodeGroup>
  </Step>
</Steps>

### 3. Configure Voice Settings

<Steps>
  <Step title="Select a Voice for Your Assistant">
    In this step, you can choose from over 3,000 life-like voices available in ElevenLabs, for this demo we will be using Jessica's voice.

    <Frame caption="Assistant voice configuration">
      ![Assistant Settings](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-3.png)
    </Frame>

    <Note> Higher quality settings may increase response time slightly. For an optimal customer experience, we recommend balancing quality and latency based on your assistant's expected use case. </Note>
  </Step>
</Steps>

### 4. Test Your Assistant

<Steps>
  <Step title="Converse with Your Assistant">
    *   Press the **Order** button and try ordering some Pierogi to see how the assistant handles the conversation.

    <Frame caption="Testing your assistant">
      ![Assistant Testing Interface](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-4.png)
    </Frame>
  </Step>
</Steps>

### 5. Configure Data Collection

Configure evaluation criteria and data collection to analyze conversations and improve your assistant's performance.

<Frame>
  ![Assistant Analysis Interface](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-6.png)
</Frame>

<Steps>
  <Step title="Configure Evaluation Criteria">
    Navigate to the **ANALYSIS** section in your assistant's settings to define custom criteria for evaluating conversations.

    1.  **Goal Prompt Criteria**
        This passes the conversation transcript to the LLM to verify if specific goals were met. Results will be:

    *   success
    *   failure
    *   unknown

    Plus a rationale explaining the chosen result.

    Configure the following fields:

    *   **Name**: Enter a descriptive name
    *   **Prompt**: Enter detailed instructions for evaluating the conversation

    <CodeGroup>
      ```plaintext order_completion
      Name: order_completion
      Prompt: Evaluate if the conversation resulted in a successful order completion.
      Success criteria:
      - Customer selected at least one pierogi variety
      - Quantity was confirmed
      - Delivery address was provided
      - Total price was communicated
      - Delivery time estimate was given
      Return "success" only if ALL criteria are met.
      ```

      ```plaintext customer_satisfaction
      Name: customer_satisfaction
      Prompt: Analyze the conversation for signs of customer satisfaction.
      Success criteria:
      - Customer's questions were answered clearly
      - No repeated requests for clarification
      - No signs of frustration or confusion
      - Positive or neutral customer responses
      Return "failure" if there are clear signs of dissatisfaction.
      ```

      ```plaintext menu_explanation
      Name: menu_explanation
      Prompt: Evaluate if the assistant properly explained menu options when asked.
      Success criteria:
      - Mentioned available pierogi varieties
      - Provided prices when relevant
      - Explained portion sizes (dozens)
      Return "unknown" if menu items were not discussed.
      ```
    </CodeGroup>
  </Step>

  <Step title="Set Up Data Collection">
    In the **Data collection** section, define specifications for extracting data from conversation transcripts.

    Click **Add data collection item** and configure:

    *   **Data type**: Select "string"
    *   **Identifier**: Enter a unique identifier for this data point
    *   **Description**: Provide detailed instructions for the LLM about how to extract the specific data from the transcript

    Example data collection items:

    <CodeGroup>
      ```plaintext Order Type
      Identifier: order_type
      Description: Extract the type of order from the conversation.
      Should be one of:
      - delivery
      - pickup
      - inquiry_only
      ```

      ```plaintext Ordered Items
      Identifier: ordered_items
      Description: List all pierogi varieties and quantities ordered in the format: "item: quantity".
      Should be one of:
      - completed_order
      - abandoned_order
      - menu_inquiry
      - general_inquiry
      If no order was placed, return "none"
      ```

      ```plaintext Delivery Zone
      Identifier: delivery_zone
      Description: Based on the delivery address, categorize the location.
      Should be one of:
      - central_zakopane
      - outer_zakopane
      - outside_delivery_zone
      ```

      ```plaintext Interaction Type
      Identifier: interaction_type
      Description: Categorize the conversation.
      Should be one of:
      - completed_order
      - abandoned_order
      - menu_inquiry
      - general_inquiry
      ```
    </CodeGroup>
  </Step>

  <Step title="View Conversation History">
    <Frame caption="You can view evaluation results and collected data for each conversation in the history tab.">
      ![Conversation History](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-perogi-7.png)
    </Frame>
  </Step>
</Steps>

Your Pierogi Palace assistant is now ready to take orders 🥟! The assistant can handle menu inquiries, process orders, and provide delivery estimates.


# Introduction

Deploy customized, conversational voice agents in minutes.

<Frame>
  ![Conversational AI Platform](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai.png)
</Frame>

## What is Conversational AI?

ElevenLabs Conversational AI is a platform for deploying customized, conversational voice agents. Built in response to our customers' needs, our platform eliminates months of development time typically spent building conversation stacks from scratch. Our Conversational AI orchestration platform combines three key components:

<CardGroup cols={3}>
  <Card title="Speech to Text" icon="ear-listen">
    **The ears** - Converts spoken language into text with high accuracy
  </Card>

  <Card title="Language Models" icon="brain-circuit">
    **The brain** - Processes and understands context to generate intelligent
    responses
  </Card>

  <Card title="Text to Speech" icon="microphone">
    **The voice** - Transforms text responses into natural-sounding speech using
    our industry-leading voice technology
  </Card>
</CardGroup>

## Why Choose ElevenLabs?

<CardGroup cols={2}>
  <Card title="Rapid Development" icon="rocket">
    Get to production in hours, not months. Our platform handles the complex infrastructure including speech processing, turn-taking, and conversation management.

    <Frame>
      ![Playground](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/playground.png)
    </Frame>
  </Card>

  <Card title="Premium Voice Quality" icon="waveform">
    Get access to over **3,000** premium voices or clone your own. Our industry-leading voice technology delivers the most natural-sounding AI conversations.

    <Frame>
      ![Voices](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/voices.png)
    </Frame>
  </Card>

  <Card title="Full Customization" icon="sliders">
    Bring your own brain - integrate custom RAG, LLMs, and functions, or
    leverage our built-in solutions. You maintain complete control over your
    business logic.
  </Card>

  <Card title="Real-Time Analytics" icon="chart-mixed">
    Monitor and optimize your AI conversations with comprehensive analytics.
    Track engagement metrics, conversation quality, and user satisfaction in
    real-time through our intuitive dashboard.
  </Card>
</CardGroup>

## Pricing

<Note>
  Conversational AI is currently in beta. During this period, we're covering the
  LLM costs, though these will be passed through to customers in the future.
</Note>

<Card title="Usage Pricing" icon="code">
  *   Setup & Prompt Testing: **500 credits per minute**
  *   Production: **1,000 credits per minute**
</Card>

## Key Features

<AccordionGroup>
  <Accordion title="Conversational Voice Agents">
    Deploy sophisticated AI agents that can:

    *   Engage in natural, context-aware conversations
    *   Handle interruptions gracefully with built-in turn-taking logic
    *   Process complex queries using advanced language models
    *   Maintain conversation history and context
    *   Scale to handle multiple concurrent conversations
  </Accordion>

  <Accordion title="Easy Integration">
    Multiple flexible deployment options:

    *   Quick embed via customizable widget
    *   Direct API access for custom implementations
    *   Comprehensive SDKs for Python and JavaScript
    *   WebSocket support for real-time interactions
    *   Simple authentication and usage monitoring
  </Accordion>

  {" "}

  <Accordion title="Development & Customization">
    Powerful tools to save development time:

    *   Pre-built templates for common use cases
    *   Customizable system prompts and
        knowledge bases
    *   Built-in analytics and success metrics
    *   Voice customization options
  </Accordion>

  <Accordion title="Enterprise Features">
    Advanced capabilities for business needs:

    *   Custom LLM support
    *   Enhanced security and compliance options
    *   Advanced analytics and reporting
    *   Priority support channels
    *   Custom integration assistance
  </Accordion>
</AccordionGroup>

## Popular Applications

Companies and creators use our Conversational AI orchestration platform to create:

<CardGroup cols={2}>
  <Card title="Customer Service Representatives" icon="headset">
    AI agents trained on company help documentation that can handle complex
    customer queries, troubleshoot issues, and provide 24/7 support in multiple
    languages.
  </Card>

  <Card title="Virtual Assistants" icon="calendar-check">
    Personal AI helpers that manage scheduling, set reminders, look up
    information, and help users stay organized throughout their day.
  </Card>

  <Card title="Retail Support" icon="shop">
    Shopping assistants that help customers find products, provide personalized
    recommendations, track orders, and answer product-specific questions.
  </Card>

  <Card title="Conversational Characters" icon="book-open">
    Engaging NPCs and storytelling agents that create immersive experiences,
    guide players through custom worlds, and adapt narratives based on user
    interactions.
  </Card>
</CardGroup>

<Note>
  Ready to get started? Check out our [quickstart
  guide](/conversational-ai/docs/agent-setup) to create your first AI agent in
  minutes.
</Note>


# Next.JS

Learn how to create a web application that enables voice conversations with ElevenLabs AI agents

This tutorial will guide you through creating a web client that can interact with a Conversational AI agent. You'll learn how to implement real-time voice conversations, allowing users to speak with an AI agent that can listen, understand, and respond naturally using voice synthesis.

## What You'll Need

1.  An ElevenLabs agent created following [this guide](/conversational-ai/docs/agent-setup)
2.  `npm` installed on your local system.
3.  We'll use Typescript for this tutorial, but you can use Javascript if you prefer.

<Note>
  Looking for a complete example? Check out our [Next.js demo on
  GitHub](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai/nextjs).
</Note>

<Frame>
  ![Convai Example Project](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-nextjs-example.png)
</Frame>

## Setup

<Steps>
  <Step title="Create a new Next.js project">
    Open a terminal window and run the following command:

    ```bash
    npm create next-app my-conversational-agent
    ```

    It will ask you some questions about how to build your project. We'll follow the default suggestions for this tutorial.
  </Step>

  <Step title="Navigate to project directory">
    ```shell
    cd my-conversational-agent
    ```
  </Step>

  <Step title="Install the ElevenLabs dependency">
    ```shell
    npm install @11labs/react
    ```
  </Step>

  <Step title="Test the setup">
    Run the following command to start the development server and open the provided URL in your browser:

    ```shell
    npm run dev
    ```

    <Frame>
      ![Verce Default Screen](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-nextjs-1.png)
    </Frame>
  </Step>
</Steps>

## Implement Conversational AI

<Steps>
  <Step title="Create the conversation component">
    Create a new file `app/components/conversation.tsx`:

    ```tsx app/components/conversation.tsx
    'use client';

    import { useConversation } from '@11labs/react';
    import { useCallback } from 'react';

    export function Conversation() {
      const conversation = useConversation({
        onConnect: () => console.log('Connected'),
        onDisconnect: () => console.log('Disconnected'),
        onMessage: (message) => console.log('Message:', message),
        onError: (error) => console.error('Error:', error),
      });


      const startConversation = useCallback(async () => {
        try {
          // Request microphone permission
          await navigator.mediaDevices.getUserMedia({ audio: true });

          // Start the conversation with your agent
          await conversation.startSession({
            agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
          });

        } catch (error) {
          console.error('Failed to start conversation:', error);
        }
      }, [conversation]);

      const stopConversation = useCallback(async () => {
        await conversation.endSession();
      }, [conversation]);

      return (
        <div className="flex flex-col items-center gap-4">
          <div className="flex gap-2">
            <button
              onClick={startConversation}
              disabled={conversation.status === 'connected'}
              className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
            >
              Start Conversation
            </button>
            <button
              onClick={stopConversation}
              disabled={conversation.status !== 'connected'}
              className="px-4 py-2 bg-red-500 text-white rounded disabled:bg-gray-300"
            >
              Stop Conversation
            </button>
          </div>

          <div className="flex flex-col items-center">
            <p>Status: {conversation.status}</p>
            <p>Agent is {conversation.isSpeaking ? 'speaking' : 'listening'}</p>
          </div>
        </div>
      );
    }
    ```
  </Step>

  <Step title="Update the main page">
    Replace the contents of `app/page.tsx` with:

    ```tsx app/page.tsx
    import { Conversation } from './components/conversation';

    export default function Home() {
      return (
        <main className="flex min-h-screen flex-col items-center justify-between p-24">
          <div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm">
            <h1 className="text-4xl font-bold mb-8 text-center">
              ElevenLabs Conversational AI
            </h1>
            <Conversation />
          </div>
        </main>
      );
    }
    ```
  </Step>
</Steps>

<Accordion title="(Optional) Authenticate the agents with a signed URL">
  <Note>
    This authentication step is only required for private agents. If you're using
    a public agent, you can skip this section and directly use the `agentId` in
    the `startSession` call.
  </Note>

  If you're using a private agent that requires authentication, you'll need to generate
  a signed URL from your server. This section explains how to set this up.

  ### What You'll Need

  1.  An ElevenLabs account and API key. Sign up [here](https://www.elevenlabs.io/sign-up).

  <Steps>
    <Step title="Create environment variables">
      Create a `.env.local` file in your project root:

      ```yaml .env.local
      ELEVENLABS_API_KEY=your-api-key-here
      NEXT_PUBLIC_AGENT_ID=your-agent-id-here
      ```

      <Warning>
        1.  Make sure to add `.env.local` to your `.gitignore` file to prevent accidentally committing sensitive credentials to version control.
        2.  Never expose your API key in the client-side code. Always keep it secure on the server.
      </Warning>
    </Step>

    <Step title="Create an API route">
      Create a new file `app/api/get-signed-url/route.ts`:

      ```tsx app/api/get-signed-url/route.ts
      import { NextResponse } from 'next/server';

      export async function GET() {
        try {
          const response = await fetch(
            `https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=${process.env.NEXT_PUBLIC_AGENT_ID}`,
            {
              headers: {
                'xi-api-key': process.env.ELEVENLABS_API_KEY!,
              },
            }
          );

          if (!response.ok) {
            throw new Error('Failed to get signed URL');
          }

          const data = await response.json();
          return NextResponse.json({ signedUrl: data.signed_url });
        } catch (error) {
          return NextResponse.json(
            { error: 'Failed to generate signed URL' },
            { status: 500 }
          );
        }
      }
      ```
    </Step>

    <Step title="Update the Conversation component">
      Modify your `conversation.tsx` to fetch and use the signed URL:

      ```tsx app/components/conversation.tsx {5-12,19,23}
      // ... existing imports ...

      export function Conversation() {
        // ... existing conversation setup ...
        const getSignedUrl = async (): Promise<string> => {
          const response = await fetch("/api/get-signed-url");
          if (!response.ok) {
            throw new Error(`Failed to get signed url: ${response.statusText}`);
          }
          const { signedUrl } = await response.json();
          return signedUrl;
        };

        const startConversation = useCallback(async () => {
          try {
            // Request microphone permission
            await navigator.mediaDevices.getUserMedia({ audio: true });

            const signedUrl = await getSignedUrl();

            // Start the conversation with your signed url
            await conversation.startSession({
              signedUrl,
            });

          } catch (error) {
            console.error('Failed to start conversation:', error);
          }
        }, [conversation]);

        // ... rest of the component ...
      }
      ```

      <Warning>
        Signed URLs expire after a short period. However, any conversations initiated before expiration will continue uninterrupted. In a production environment, implement proper error handling and URL refresh logic for starting new conversations.
      </Warning>
    </Step>
  </Steps>
</Accordion>

## Next Steps

Now that you have a basic implementation, you can:

1.  Add visual feedback for voice activity
2.  Implement error handling and retry logic
3.  Add a chat history display
4.  Customize the UI to match your brand

<Info>
  For more advanced features and customization options, check out the
  [@11labs/react](https://www.npmjs.com/package/@11labs/react) package.
</Info>


# Vite (Javascript)

Learn how to create a web application that enables voice conversations with ElevenLabs AI agents

This tutorial will guide you through creating a web client that can interact with a Conversational AI agent. You'll learn how to implement real-time voice conversations, allowing users to speak with an AI agent that can listen, understand, and respond naturally using voice synthesis.

<Note>
  Looking to build with React/Next.js? Check out our [Next.js
  guide](/conversational-ai/guides/conversational-ai-guide-nextjs).
</Note>

## What You'll Need

1.  An ElevenLabs agent created following [this guide](/conversational-ai/docs/agent-setup)
2.  `npm` installed on your local system
3.  Basic knowledge of JavaScript

<Note>
  Looking for a complete example? Check out our [Vanilla JS demo on
  GitHub](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai/javascript).
</Note>

## Project Setup

<Steps>
  <Step title="Create a Project Directory">
    Open a terminal and create a new directory for your project:

    ```bash
    mkdir elevenlabs-conversational-ai
    cd elevenlabs-conversational-ai
    ```
  </Step>

  <Step title="Initialize npm and Install Dependencies">
    Initialize a new npm project and install the required packages:

    ```bash
    npm init -y
    npm install vite @11labs/client
    ```
  </Step>

  <Step title="Set up Basic Project Structure">
    Add this to your `package.json`:

    ```json package.json {4}
    {
        "scripts": {
            ...
            "dev:frontend": "vite"
        }
    }
    ```

    Create the following file structure:

    ```shell {2,3}
    elevenlabs-conversational-ai/
    ├── index.html
    ├── script.js
    ├── package-lock.json
    ├── package.json
    └── node_modules
    ```
  </Step>
</Steps>

## Implementing the Voice Chat Interface

<Steps>
  <Step title="Create the HTML Interface">
    In `index.html`, set up a simple user interface:

    <Frame>
      ![Conversational AI HTML interface step](https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/conversational-ai/images/convai-vite-1.png)
    </Frame>

    ```html index.html
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>ElevenLabs Conversational AI</title>
        </head>
        <body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
            <h1>ElevenLabs Conversational AI</h1>
            <div style="margin-bottom: 20px;">
                <button id="startButton" style="padding: 10px 20px; margin: 5px;">Start Conversation</button>
                <button id="stopButton" style="padding: 10px 20px; margin: 5px;" disabled>Stop Conversation</button>
            </div>
            <div style="font-size: 18px;">
                <p>Status: <span id="connectionStatus">Disconnected</span></p>
                <p>Agent is <span id="agentStatus">listening</span></p>
            </div>
            <script type="module" src="script.js"></script>
        </body>
    </html>
    ```
  </Step>

  <Step title="Implement the Conversation Logic">
    In `script.js`, implement the functionality:

    ```javascript script.js
    import { Conversation } from '@11labs/client';

    const startButton = document.getElementById('startButton');
    const stopButton = document.getElementById('stopButton');
    const connectionStatus = document.getElementById('connectionStatus');
    const agentStatus = document.getElementById('agentStatus');

    let conversation;

    async function startConversation() {
        try {
            // Request microphone permission
            await navigator.mediaDevices.getUserMedia({ audio: true });

            // Start the conversation
            conversation = await Conversation.startSession({
                agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
                onConnect: () => {
                    connectionStatus.textContent = 'Connected';
                    startButton.disabled = true;
                    stopButton.disabled = false;
                },
                onDisconnect: () => {
                    connectionStatus.textContent = 'Disconnected';
                    startButton.disabled = false;
                    stopButton.disabled = true;
                },
                onError: (error) => {
                    console.error('Error:', error);
                },
                onModeChange: (mode) => {
                    agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
                },
            });
        } catch (error) {
            console.error('Failed to start conversation:', error);
        }
    }

    async function stopConversation() {
        if (conversation) {
            await conversation.endSession();
            conversation = null;
        }
    }

    startButton.addEventListener('click', startConversation);
    stopButton.addEventListener('click', stopConversation);
    ```
  </Step>

  <Step title="Start the frontend server">
    ```shell
    npm run dev:frontend
    ```
  </Step>
</Steps>

<Note>
  Make sure to replace `'YOUR_AGENT_ID'` with your actual agent ID from
  ElevenLabs.
</Note>

<Accordion title="(Optional) Authenticate with a Signed URL">
  <Note>
    This authentication step is only required for private agents. If you're using a public agent, you can skip this section and directly use the `agentId` in the `startSession` call.
  </Note>

  <Steps>
    <Step title="Create Environment Variables">
      Create a `.env` file in your project root:

      ```env .env
      ELEVENLABS_API_KEY=your-api-key-here
      AGENT_ID=your-agent-id-here
      ```

      <Warning>
        Make sure to add `.env` to your `.gitignore` file to prevent accidentally committing sensitive credentials.
      </Warning>
    </Step>

    <Step title="Setup the Backend">
      1.  Install additional dependencies:

      ```bash
      npm install express cors dotenv
      ```

      2.  Create a new folder called `backend`:

      ```shell {2}
      elevenlabs-conversational-ai/
      ├── backend
      ...
      ```
    </Step>

    <Step title="Create the Server">
      ```javascript backend/server.js
      require("dotenv").config();

      const express = require("express");
      const cors = require("cors");

      const app = express();
      app.use(cors());
      app.use(express.json());

      const PORT = process.env.PORT || 3001;

      app.get("/api/get-signed-url", async (req, res) => {
          try {
              const response = await fetch(
                  `https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=${process.env.AGENT_ID}`,
                  {
                      headers: {
                          "xi-api-key": process.env.ELEVENLABS_API_KEY,
                      },
                  }
              );

              if (!response.ok) {
                  throw new Error("Failed to get signed URL");
              }

              const data = await response.json();
              res.json({ signedUrl: data.signed_url });
          } catch (error) {
              console.error("Error:", error);
              res.status(500).json({ error: "Failed to generate signed URL" });
          }
      });

      app.listen(PORT, () => {
          console.log(`Server running on http://localhost:${PORT}`);
      });
      ```
    </Step>

    <Step title="Update the Client Code">
      Modify your `script.js` to fetch and use the signed URL:

      ```javascript script.js {2-10,16,19,20}
      // ... existing imports and variables ...

      async function getSignedUrl() {
          const response = await fetch('http://localhost:3001/api/get-signed-url');
          if (!response.ok) {
              throw new Error(`Failed to get signed url: ${response.statusText}`);
          }
          const { signedUrl } = await response.json();
          return signedUrl;
      }

      async function startConversation() {
          try {
              await navigator.mediaDevices.getUserMedia({ audio: true });

              const signedUrl = await getSignedUrl();

              conversation = await Conversation.startSession({
                  signedUrl,
                  // agentId has been removed...
                  onConnect: () => {
                      connectionStatus.textContent = 'Connected';
                      startButton.disabled = true;
                      stopButton.disabled = false;
                  },
                  onDisconnect: () => {
                      connectionStatus.textContent = 'Disconnected';
                      startButton.disabled = false;
                      stopButton.disabled = true;
                  },
                  onError: (error) => {
                      console.error('Error:', error);
                  },
                  onModeChange: (mode) => {
                      agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
                  },
              });
          } catch (error) {
              console.error('Failed to start conversation:', error);
          }
      }

      // ... rest of the code ...
      ```

      <Warning>
        Signed URLs expire after a short period. However, any conversations initiated before expiration will continue uninterrupted. In a production environment, implement proper error handling and URL refresh logic for starting new conversations.
      </Warning>
    </Step>

    <Step title="Update the package.json">
      ```json package.json {4,5}
      {
          "scripts": {
              ...
              "dev:backend": "node backend/server.js",
              "dev": "npm run dev:frontend & npm run dev:backend"
          }
      }
      ```
    </Step>

    <Step title="Run the Application">
      Start the application with:

      ```bash
      npm run dev
      ```
    </Step>
  </Steps>
</Accordion>

## Next Steps

Now that you have a basic implementation, you can:

1.  Add visual feedback for voice activity
2.  Implement error handling and retry logic
3.  Add a chat history display
4.  Customize the UI to match your brand

<Info>
  For more advanced features and customization options, check out the
  [@11labs/client](https://www.npmjs.com/package/@11labs/client) package.
</Info>


# Twilio Integration

Learn how to integrate a Conversational AI agent with Twilio to create seamless, human-like voice interactions.

Connect your ElevenLabs Conversational AI agent to phone calls and create human-like voice experiences using Twilio's Voice API.

## What You'll Need

*   An [ElevenLabs account](https://elevenlabs.io)
*   A configured ElevenLabs Conversational Agent ([create one here](/conversational-ai/docs/agent-setup))
*   A [Twilio account](https://www.twilio.com/try-twilio) with an active phone number
*   Python 3.7+ or Node.js 16+
*   [ngrok](https://ngrok.com/) for local development

## Agent Configuration

Before integrating with Twilio, you'll need to configure your agent to use the correct audio format supported by Twilio.

<Steps>
  <Step title="Configure TTS Output">
    1.  Navigate to your agent settings
    2.  Go to the Voice Section
    3.  Select "μ-law 8000 Hz" from the dropdown

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/twilio_3.png" />
  </Step>

  <Step title="Set Input Format">
    1.  Navigate to your agent settings
    2.  Go to the Advanced Section
    3.  Select "μ-law 8000 Hz" for the input format

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/twilio_4.png" />
  </Step>
</Steps>

## Implementation

<Tabs>
  <Tab title="Javascript">
    <Note>
      Looking for a complete example? Check out this [Javascript implementation](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai/twilio/javascript) on GitHub.
    </Note>

    <Steps>
      <Step title="Initialize the Project">
        First, set up a new Node.js project:

        ```bash
        mkdir conversational-ai-twilio
        cd conversational-ai-twilio
        npm init -y; npm pkg set type="module";
        ```
      </Step>

      <Step title="Install dependencies">
        Next, install the required dependencies for the project.

        ```bash
        npm install @fastify/formbody @fastify/websocket dotenv fastify ws
        ```
      </Step>

      <Step title="Create the project files">
        Create a `.env` & `index.js` file  with the following code:

        <CodeGroup>
          ```text .env
          ELEVENLABS_AGENT_ID=<your-agent-id>
          ```

          ```javascript index.js
          import Fastify from "fastify";
          import WebSocket from "ws";
          import dotenv from "dotenv";
          import fastifyFormBody from "@fastify/formbody";
          import fastifyWs from "@fastify/websocket";

          // Load environment variables from .env file
          dotenv.config();

          const { ELEVENLABS_AGENT_ID } = process.env;

          // Check for the required ElevenLabs Agent ID
          if (!ELEVENLABS_AGENT_ID) {
          console.error("Missing ELEVENLABS_AGENT_ID in environment variables");
          process.exit(1);
          }

          // Initialize Fastify server
          const fastify = Fastify();
          fastify.register(fastifyFormBody);
          fastify.register(fastifyWs);

          const PORT = process.env.PORT || 8000;

          // Root route for health check
          fastify.get("/", async (_, reply) => {
          reply.send({ message: "Server is running" });
          });

          // Route to handle incoming calls from Twilio
          fastify.all("/incoming-call-eleven", async (request, reply) => {
          // Generate TwiML response to connect the call to a WebSocket stream
          const twimlResponse = `<?xml version="1.0" encoding="UTF-8"?>
              <Response>
              <Connect>
                  <Stream url="wss://${request.headers.host}/media-stream" />
              </Connect>
              </Response>`;

          reply.type("text/xml").send(twimlResponse);
          });

          // WebSocket route for handling media streams from Twilio
          fastify.register(async (fastifyInstance) => {
          fastifyInstance.get("/media-stream", { websocket: true }, (connection, req) => {
              console.info("[Server] Twilio connected to media stream.");

              let streamSid = null;

              // Connect to ElevenLabs Conversational AI WebSocket
              const elevenLabsWs = new WebSocket(
              `wss://api.elevenlabs.io/v1/convai/conversation?agent_id=${ELEVENLABS_AGENT_ID}`
              );

              // Handle open event for ElevenLabs WebSocket
              elevenLabsWs.on("open", () => {
              console.log("[II] Connected to Conversational AI.");
              });

              // Handle messages from ElevenLabs
              elevenLabsWs.on("message", (data) => {
              try {
                  const message = JSON.parse(data);
                  handleElevenLabsMessage(message, connection);
              } catch (error) {
                  console.error("[II] Error parsing message:", error);
              }
              });

              // Handle errors from ElevenLabs WebSocket
              elevenLabsWs.on("error", (error) => {
              console.error("[II] WebSocket error:", error);
              });

              // Handle close event for ElevenLabs WebSocket
              elevenLabsWs.on("close", () => {
              console.log("[II] Disconnected.");
              });

              // Function to handle messages from ElevenLabs
              const handleElevenLabsMessage = (message, connection) => {
              switch (message.type) {
                  case "conversation_initiation_metadata":
                  console.info("[II] Received conversation initiation metadata.");
                  break;
                  case "audio":
                  if (message.audio_event?.audio_base_64) {
                      // Send audio data to Twilio
                      const audioData = {
                      event: "media",
                      streamSid,
                      media: {
                          payload: message.audio_event.audio_base_64,
                      },
                      };
                      connection.send(JSON.stringify(audioData));
                  }
                  break;
                  case "interruption":
                  // Clear Twilio's audio queue
                  connection.send(JSON.stringify({ event: "clear", streamSid }));
                  break;
                  case "ping":
                  // Respond to ping events from ElevenLabs
                  if (message.ping_event?.event_id) {
                      const pongResponse = {
                      type: "pong",
                      event_id: message.ping_event.event_id,
                      };
                      elevenLabsWs.send(JSON.stringify(pongResponse));
                  }
                  break;
              }
              };

              // Handle messages from Twilio
              connection.on("message", async (message) => {
              try {
                  const data = JSON.parse(message);
                  switch (data.event) {
                  case "start":
                      // Store Stream SID when stream starts
                      streamSid = data.start.streamSid;
                      console.log(`[Twilio] Stream started with ID: ${streamSid}`);
                      break;
                  case "media":
                      // Route audio from Twilio to ElevenLabs
                      if (elevenLabsWs.readyState === WebSocket.OPEN) {
                      // data.media.payload is base64 encoded
                      const audioMessage = {
                          user_audio_chunk: Buffer.from(
                              data.media.payload,
                              "base64"
                          ).toString("base64"),
                      };
                      elevenLabsWs.send(JSON.stringify(audioMessage));
                      }
                      break;
                  case "stop":
                      // Close ElevenLabs WebSocket when Twilio stream stops
                      elevenLabsWs.close();
                      break;
                  default:
                      console.log(`[Twilio] Received unhandled event: ${data.event}`);
                  }
              } catch (error) {
                  console.error("[Twilio] Error processing message:", error);
              }
              });

              // Handle close event from Twilio
              connection.on("close", () => {
              elevenLabsWs.close();
              console.log("[Twilio] Client disconnected");
              });

              // Handle errors from Twilio WebSocket
              connection.on("error", (error) => {
              console.error("[Twilio] WebSocket error:", error);
              elevenLabsWs.close();
              });
          });
          });

          // Start the Fastify server
          fastify.listen({ port: PORT }, (err) => {
          if (err) {
              console.error("Error starting server:", err);
              process.exit(1);
          }
          console.log(`[Server] Listening on port ${PORT}`);
          });
          ```
        </CodeGroup>
      </Step>

      <Step title="Run the server">
        You can now run the server with the following command:

        ```bash
        node index.js
        ```

        If the server starts successfully, you should see the message `[Server] Listening on port 8000` (or the port you specified) in your terminal.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Python">
    <Note>
      Looking for a complete example? Check out this [implementation](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai/twilio) on GitHub.
    </Note>

    <Steps>
      <Step title="Initialize the Project">
        ```bash
         mkdir conversational-ai-twilio
         cd conversational-ai-twilio
        ```
      </Step>

      <Step title="Install dependencies">
        Next, install the required dependencies for the project.

        ```bash
        pip install fastapi uvicorn python-dotenv twilio elevenlabs websockets
        ```
      </Step>

      <Step title="Create the project files">
        Create a `.env`, `main.py` & `twilio_audio_interface.py` file  with the following code:

        ```
        conversational-ai-twilio/
        ├── .env
        ├── main.py
        └── twilio_audio_interface.py
        ```

        <CodeGroup>
          ```text .env
          ELEVENLABS_API_KEY=<api-key-here>
          AGENT_ID=<agent-id-here>
          ```

          ```python main.py
          import json
          import traceback
          import os
          from dotenv import load_dotenv
          from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
          from fastapi.responses import HTMLResponse
          from twilio.twiml.voice_response import VoiceResponse, Connect
          from elevenlabs import ElevenLabs
          from elevenlabs.conversational_ai.conversation import Conversation
          from twilio_audio_interface import TwilioAudioInterface

          # Load environment variables
          load_dotenv()

          # Initialize FastAPI app
          app = FastAPI()

          # Initialize ElevenLabs client
          eleven_labs_client = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))
          ELEVEN_LABS_AGENT_ID = os.getenv("AGENT_ID")

          @app.get("/")
          async def root():
              return {"message": "Twilio-ElevenLabs Integration Server"}

          @app.api_route("/incoming-call-eleven", methods=["GET", "POST"])
          async def handle_incoming_call(request: Request):
              """Handle incoming call and return TwiML response."""
              response = VoiceResponse()
              host = request.url.hostname
              connect = Connect()
              connect.stream(url=f"wss://{host}/media-stream-eleven")
              response.append(connect)
              return HTMLResponse(content=str(response), media_type="application/xml")

          @app.websocket("/media-stream-eleven")
          async def handle_media_stream(websocket: WebSocket):
              await websocket.accept()
              print("WebSocket connection established")

              audio_interface = TwilioAudioInterface(websocket)
              conversation = None

              try:
                  conversation = Conversation(
                      client=eleven_labs_client,
                      agent_id=ELEVEN_LABS_AGENT_ID,
                      requires_auth=False,
                      audio_interface=audio_interface,
                      callback_agent_response=lambda text: print(f"Agent said: {text}"),
                      callback_user_transcript=lambda text: print(f"User said: {text}"),
                  )

                  conversation.start_session()
                  print("Conversation session started")

                  async for message in websocket.iter_text():
                      if not message:
                          continue

                      try:
                          data = json.loads(message)
                          await audio_interface.handle_twilio_message(data)
                      except Exception as e:
                          print(f"Error processing message: {str(e)}")
                          traceback.print_exc()

              except WebSocketDisconnect:
                  print("WebSocket disconnected")
              finally:
                  if conversation:
                      print("Ending conversation session...")
                      conversation.end_session()
                      conversation.wait_for_session_end()

          if __name__ == "__main__":
              import uvicorn
              uvicorn.run(app, host="0.0.0.0", port=8000)
          ```

          ```python twilio_audio_interface.py
          import asyncio
          from typing import Callable
          import queue
          import threading
          import base64
          from elevenlabs.conversational_ai.conversation import AudioInterface
          import websockets

          class TwilioAudioInterface(AudioInterface):
              def __init__(self, websocket):
                  self.websocket = websocket
                  self.output_queue = queue.Queue()
                  self.should_stop = threading.Event()
                  self.stream_sid = None
                  self.input_callback = None
                  self.output_thread = None

              def start(self, input_callback: Callable[[bytes], None]):
                  self.input_callback = input_callback
                  self.output_thread = threading.Thread(target=self._output_thread)
                  self.output_thread.start()

              def stop(self):
                  self.should_stop.set()
                  if self.output_thread:
                      self.output_thread.join(timeout=5.0)
                  self.stream_sid = None

              def output(self, audio: bytes):
                  self.output_queue.put(audio)

              def interrupt(self):
                  try:
                      while True:
                          _ = self.output_queue.get(block=False)
                  except queue.Empty:
                      pass
                  asyncio.run(self._send_clear_message_to_twilio())

              async def handle_twilio_message(self, data):
                  try:
                      if data["event"] == "start":
                          self.stream_sid = data["start"]["streamSid"]
                          print(f"Started stream with stream_sid: {self.stream_sid}")
                      if data["event"] == "media":
                          audio_data = base64.b64decode(data["media"]["payload"])
                          if self.input_callback:
                              self.input_callback(audio_data)
                  except Exception as e:
                      print(f"Error in input_callback: {e}")

              def _output_thread(self):
                  while not self.should_stop.is_set():
                      asyncio.run(self._send_audio_to_twilio())

              async def _send_audio_to_twilio(self):
                  try:
                      audio = self.output_queue.get(timeout=0.2)
                      audio_payload = base64.b64encode(audio).decode("utf-8")
                      audio_delta = {
                          "event": "media",
                          "streamSid": self.stream_sid,
                          "media": {"payload": audio_payload},
                      }
                      await self.websocket.send_json(audio_delta)
                  except queue.Empty:
                      pass
                  except Exception as e:
                      print(f"Error sending audio: {e}")

              async def _send_clear_message_to_twilio(self):
                  try:
                      clear_message = {"event": "clear", "streamSid": self.stream_sid}
                      await self.websocket.send_json(clear_message)
                  except Exception as e:
                      print(f"Error sending clear message to Twilio: {e}")
          ```
        </CodeGroup>
      </Step>

      <Step title="Run the server">
        You can now run the server with the following command:

        ```bash
        python main.py
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Twilio Setup

<Steps>
  <Step title="Create a Public URL">
    Use ngrok to make your local server accessible:

    ```bash
    ngrok http --url=<your-url-here> 8000
    ```

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/twilio_1.png" />
  </Step>

  <Step title="Configure Twilio">
    1.  Go to the [Twilio Console](https://console.twilio.com)
    2.  Navigate to `Phone Numbers` → `Manage` → `Active numbers`
    3.  Select your phone number
    4.  Under "Voice Configuration", set the webhook for incoming calls to:
        `https://your-ngrok-url.ngrok.app/incoming-call-eleven`
    5.  Set the HTTP method to POST

    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/developer-guides/images/twilio_2.png" />
  </Step>
</Steps>

## Testing

1.  Call your Twilio phone number.
2.  Start speaking - you'll see the transcripts in the ElevenLabs console.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Connection Issues">
    If the WebSocket connection fails:

    *   Verify your ngrok URL is correct in Twilio settings
    *   Check that your server is running and accessible
    *   Ensure your firewall isn't blocking WebSocket connections
  </Accordion>

  <Accordion title="Audio Problems">
    If there's no audio output:

    *   Confirm your ElevenLabs API key is valid
    *   Verify the AGENT\_ID is correct
    *   Check audio format settings match Twilio's requirements (μ-law 8kHz)
  </Accordion>
</AccordionGroup>

## Security Best Practices

<Warning>
  Follow these security guidelines for production deployments:

  <>
    *   Use environment variables for sensitive information
    *   Implement proper authentication for your endpoints
    *   Use HTTPS for all communications
    *   Regularly rotate API keys
    *   Monitor usage to prevent abuse
  </>
</Warning>


# JavaScript SDK

Conversational AI SDK: deploy customized, interactive voice agents in minutes.

<Info>
  Also see the [Conversational AI
  overview](/conversational-ai/docs/introduction)
</Info>

## Installation

Install the package in your project through package manager.

```shell
npm install @11labs/client
# or
yarn add @11labs/client
# or
pnpm install @11labs/client
```

## Usage

This library is primarily meant for development in vanilla JavaScript projects, or as a base for libraries tailored to specific frameworks.
It is recommended to check whether your specific framework has it's own library.
However, you can use this library in any JavaScript-based project.

### Initialize conversation

First, initialize the Conversation instance:

```js
const conversation = await Conversation.startSession(options);
```

This will kick off the websocket connection and start using microphone to communicate with the ElevenLabs Conversational AI agent. Consider explaining and allowing microphone access in your apps UI before the Conversation kicks off:

```js
// call after explaning to the user why the microphone access is needed
await navigator.mediaDevices.getUserMedia();
```

#### Session configuration

The options passed to `startSession` specifiy how the session is established. There are two ways to start a session:

##### Using Agent ID

Agent ID can be acquired through [ElevenLabs UI](https://elevenlabs.io/app/conversational-ai).
For public agents, you can use the ID directly:

```js
const conversation = await Conversation.startSession({
  agentId: "<your-agent-id>",
});
```

##### Using a signed URL

If the conversation requires authorization, you will need to add a dedicated endpoint to your server that
will request a signed url using the [ElevenLabs API](https://elevenlabs.io/docs/introduction) and pass it back to the client.

Here's an example of how it could be set up:

```js
// Node.js server

app.get("/signed-url", yourAuthMiddleware, async (req, res) => {
  const response = await fetch(
    `https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=${process.env.AGENT_ID}`,
    {
      method: "GET",
      headers: {
        // Requesting a signed url requires your ElevenLabs API key
        // Do NOT expose your API key to the client!
        "xi-api-key": process.env.XI_API_KEY,
      },
    }
  );

  if (!response.ok) {
    return res.status(500).send("Failed to get signed URL");
  }

  const body = await response.json();
  res.send(body.signed_url);
});
```

```js
// Client

const response = await fetch("/signed-url", yourAuthHeaders);
const signedUrl = await response.text();

const conversation = await Conversation.startSession({ signedUrl });
```

#### Optional callbacks

The options passed to `startSession` can also be used to register optional callbacks:

*   **onConnect** - handler called when the conversation websocket connection is established.
*   **onDisconnect** - handler called when the conversation websocket connection is ended.
*   **onMessage** - handler called when a new text message is received. These can be tentative or final transcriptions of user voice, replies produced by LLM. Primarily used for handling conversation transcription.
*   **onError** - handler called when an error is encountered.
*   **onStatusChange** - handler called whenever connection status changes. Can be `connected`, `connecting` and `disconnected` (initial).
*   **onModeChange** - handler called when a status changes, eg. agent switches from `speaking` to `listening`, or the other way around.

#### Return value

`startSession` returns a `Conversation` instance that can be used to control the session. The method will throw an error if the session cannot be established. This can happen if the user denies microphone access, or if the websocket connection
fails.

##### endSession

A method to manually end the conversation. The method will end the conversation and disconnect from websocket.
Afterwards the conversation instance will be unusable and can be safely discarded.

```js
await conversation.endSession();
```

##### getId

A method returning the conversation ID.

```js
const id = conversation.geId();
```

##### setVolume

A method to set the output volume of the conversation. Accepts object with volume field between 0 and 1.

```js
await conversation.setVolume({ volume: 0.5 });
```

##### getInputVolume / getOutputVolume

Methods that return the current input/output volume on a scale from `0` to `1` where `0` is -100 dB and `1` is -30 dB.

```js
const inputVolume = await conversation.getInputVolume();
const outputVolume = await conversation.getOutputVolume();
```

##### getInputByteFrequencyData / getOutputByteFrequencyData

Methods that return `Uint8Array`s containg the current input/output frequency data. See [AnalyserNode.getByteFrequencyData](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData) for more information.


# Python SDK

Conversational AI SDK: deploy customized, interactive voice agents in minutes.

<Info>
  Also see the [Conversational AI
  overview](/conversational-ai/docs/introduction)
</Info>

## Installation

Install the `elevenlabs` Python package in your project:

```shell
pip install elevenlabs
# or
poetry add elevenlabs
```

If you want to use the default implementation of audio input/output you will also need the `pyaudio` extra:

```shell
pip install "elevenlabs[pyaudio]"
# or
poetry add "elevenlabs[pyaudio]"
```

<Info>
  The `pyaudio` package installation might require additional system dependencies.

  See [PyAudio package README](https://pypi.org/project/PyAudio/) for more information.

  <Tabs>
    <Tab title="Linux">
      On Debian-based systems you can install the dependencies with:

      ```shell
      sudo apt install portaudio19
      ```
    </Tab>

    <Tab title="macOS">
      On macOS with Homebrew you can install the dependencies with:

      ```shell
      brew install portaudio
      ```
    </Tab>
  </Tabs>
</Info>

## Usage

In this example we will create a simple script that runs a conversation with the ElevenLabs Conversational AI agent.
You can find the full code in the [ElevenLabs examples repository](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai-python).

First import the necessary dependencies:

```python
import os
import signal

from elevenlabs.client import ElevenLabs
from elevenlabs.conversational_ai.conversation import Conversation
from elevenlabs.conversational_ai.default_audio_interface import DefaultAudioInterface
```

Next load the agent ID and API key from environment variables:

```python
agent_id = os.getenv("AGENT_ID")
api_key = os.getenv("ELEVENLABS_API_KEY")
```

The API key is only required for non-public agents that have authentication enabled.
You don't have to set it for public agents and the code will work fine without it.

Then create the `ElevenLabs` client instance:

```python
client = ElevenLabs(api_key=API_KEY)
```

Now we initialize the `Conversation` instance:

```python
conversation = Conversation(
    # API client and agent ID.
    client,
    AGENT_ID,

    # Assume auth is required when API_KEY is set.
    requires_auth=bool(API_KEY),

    # Use the default audio interface.
    audio_interface=DefaultAudioInterface(),

    # Simple callbacks that print the conversation to the console.
    callback_agent_response=lambda response: print(f"Agent: {response}"),
    callback_agent_response_correction=lambda original, corrected: print(f"Agent: {original} -> {corrected}"),
    callback_user_transcript=lambda transcript: print(f"User: {transcript}"),

    # Uncomment if you want to see latency measurements.
    # callback_latency_measurement=lambda latency: print(f"Latency: {latency}ms"),
)
```

We are using the `DefaultAudioInterface` which uses the default system audio input/output devices for the conversation.
You can also implement your own audio interface by subclassing `elevenlabs.conversational_ai.conversation.AudioInterface`.

Now we can start the conversation:

```python
conversation.start_session()
```

To get a clean shutdown when the user presses `Ctrl+C` we can add a signal handler which will call `end_session()`:

```python
signal.signal(signal.SIGINT, lambda sig, frame: conversation.end_session())
```

And lastly we wait for the conversation to end and print out the conversation ID (which can be used for reviewing the conversation history and debugging):

```python
conversation_id = conversation.wait_for_session_end()
print(f"Conversation ID: {conversation_id}")
```

All that is left is to run the script and start talking to the agent:

```shell
# For public agents:
AGENT_ID=youragentid python demo.py

# For private agents:
AGENT_ID=youragentid ELEVENLABS_API_KEY=yourapikey python demo.py
```


# React SDK

Conversational AI SDK: deploy customized, interactive voice agents in minutes.

<Info>
  Also see the [Conversational AI
  overview](/conversational-ai/docs/introduction)
</Info>

## Installation

Install the package in your project through package manager.

```shell
npm install @11labs/react
# or
yarn add @11labs/react
# or
pnpm install @11labs/react
```

## Usage

### useConversation

React hook for managing websocket connection and audio usage for ElevenLabs Conversational AI.

#### Initialize conversation

First, initialize the Conversation instance.

```tsx
const conversation = useConversation();
```

Note that Conversational AI requires microphone access.
Consider explaining and allowing access in your apps UI before the Conversation kicks off.

```js
// call after explaning to the user why the microphone access is needed
await navigator.mediaDevices.getUserMedia();
```

#### Options

The Conversation can be initialized with certain options. Those are all optional.

```tsx
const conversation = useConversation({
  /* options object */
});
```

*   **onConnect** - handler called when the conversation websocket connection is established.
*   **onDisconnect** - handler called when the conversation websocket connection is ended.
*   **onMessage** - handler called when a new message is received. These can be tentative or final transcriptions of user voice, replies produced by LLM, or debug message when a debug option is enabled.
*   **onError** - handler called when a error is encountered.

#### Methods

##### startConversation

`startConversation` method kick off the websocket connection and starts using microphone to communicate with the ElevenLabs Conversational AI agent.\
The method accepts options object, with the `url` or `agentId` option being required.

Agent ID can be acquired through [ElevenLabs UI](https://elevenlabs.io/app/conversational-ai) and is always necessary.

```js
const conversation = useConversation();
const conversationId = await conversation.startSession({ url });
```

For the public agents, define `agentId` - no signed link generation necessary.

In case the conversation requires authorization, use the REST API to generate signed links. Use the signed link as a `url` parameter.

`startSession` returns promise resolving to `conversationId`. The value is a globally unique conversation ID you can use to identify separate conversations.

```js
// your server
const requestHeaders: HeadersInit = new Headers();
requestHeaders.set("xi-api-key", process.env.XI_API_KEY); // use your ElevenLabs API key

const response = await fetch(
  "https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id={{agent id created through ElevenLabs UI}}",
  {
    method: "GET",
    headers: requestHeaders,
  }
);

if (!response.ok) {
  return Response.error();
}

const body = await response.json();
const url = body.signed_url; // use this URL for startConversation method.
```

##### endSession

A method to manually end the conversation. The method will end the conversation and disconnect from websocket.

```js
await conversation.endSession();
```

##### setVolume

A method to set the output volume of the conversation. Accepts object with volume field between 0 and 1.

```js
await conversation.setVolume({ volume: 0.5 });
```

##### status

A React state containing the current status of the conversation.

```js
const { status } = useConversation();
console.log(status); // "connected" or "disconnected"
```

##### isSpeaking

A React state containing the information of whether the agent is currently speaking.
This is helpful for indicating the mode in your UI.

```js
const { isSpeaking } = useConversation();
console.log(isSpeaking); // boolean
```


# iOS SDK

Conversational AI SDK: deploy customized, interactive voice agents in your Swift applications.

<Info>
  Also see the [Conversational AI
  overview](/conversational-ai/docs/introduction)
</Info>

## Installation

Add the ElevenLabs Swift SDK to your project using Swift Package Manager:

<Steps>
  <Step title="Add the Package Dependency">
    <>
      1.  Open your project in Xcode
      2.  Go to `File` > `Add Packages...`
      3.  Enter the repository URL: `https://github.com/elevenlabs/ElevenLabsSwift`
      4.  Select your desired version
    </>
  </Step>

  <Step title="Import the SDK">
    <>
      ```swift
      import ElevenLabsSDK
      ```
    </>
  </Step>
</Steps>

<Warning>
  Ensure you add `NSMicrophoneUsageDescription` to your Info.plist to explain
  microphone access to users.
</Warning>

## Usage

This library is primarily designed for Conversational AI integration in Swift applications. Please use an alternative dependency for other features, such as speech synthesis.

### Initialize Conversation

First, create a session configuration and set up the necessary callbacks:

```swift
// Configure the session
let config = ElevenLabsSDK.SessionConfig(agentId: "your-agent-id")

// Set up callbacks
var callbacks = ElevenLabsSDK.Callbacks()
callbacks.onConnect = { conversationId in
    print("Connected with ID: \(conversationId)")
}
callbacks.onDisconnect = {
    print("Disconnected")
}
callbacks.onMessage = { message, role in
    print("\(role.rawValue): \(message)")
}
callbacks.onError = { error, info in
    print("Error: \(error), Info: \(String(describing: info))")
}
callbacks.onStatusChange = { status in
    print("Status changed to: \(status.rawValue)")
}
callbacks.onModeChange = { mode in
    print("Mode changed to: \(mode.rawValue)")
}
callbacks.onVolumeUpdate = { volume in
    print("Volume updated: \(volume)")
}
```

### Session Configuration

There are two ways to initialize a session:

<Tabs>
  <Tab title="Using Agent ID">
    You can obtain an Agent ID through the [ElevenLabs UI](https://elevenlabs.io/app/conversational-ai):

    ```swift
    let config = ElevenLabsSDK.SessionConfig(agentId: "<your-agent-id>")
    ```
  </Tab>

  <Tab title="Using Signed URL">
    For conversations requiring authorization, implement a server endpoint that requests a signed URL:

    ```swift
    // Swift example using URLSession
    func getSignedUrl() async throws -> String {
        let url = URL(string: "https://api.elevenlabs.io/v1/convai/conversation/get_signed_url")!
        var request = URLRequest(url: url)
        request.setValue("YOUR-API-KEY", forHTTPHeaderField: "xi-api-key")
        
        let (data, _) = try await URLSession.shared.data(for: request)
        let response = try JSONDecoder().decode(SignedUrlResponse.self, from: data)
        return response.signedUrl
    }

    // Use the signed URL
    let signedUrl = try await getSignedUrl()
    let config = ElevenLabsSDK.SessionConfig(signedUrl: signedUrl)
    ```
  </Tab>
</Tabs>

### Starting the Conversation

Initialize the conversation session asynchronously:

```swift
Task {
    do {
        let conversation = try await ElevenLabsSDK.Conversation.startSession(
            config: config,
            callbacks: callbacks
        )
        // Use the conversation instance
    } catch {
        print("Failed to start conversation: \(error)")
    }
}
```

### Audio Sample Rates

The ElevenLabs SDK currently uses a default input sample rate of `16,000 Hz`. However, the output sample rate is configurable based on the agent's settings. Ensure that the output sample rate aligns with your specific application's audio requirements for smooth interaction.

<Note>
  The SDK does not currently support ulaw format for audio encoding. For compatibility, consider using alternative formats.
</Note>

### Managing the Session

<CodeGroup>
  ```swift:End Session
  // Starts the session
  conversation.startSession()
  // Ends the session
  conversation.endSession()
  ```

  ```swift:Recording Controls
  // Start recording
  conversation.startRecording()

  // Stop recording
  conversation.stopRecording()
  ```
</CodeGroup>

### Example Implementation

For a full, working example, check out the [example application on GitHub](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/conversational-ai-swift-example).

Here's an example SwiftUI view implementing the conversation interface:

```swift
struct ConversationalAIView: View {
    @State private var conversation: ElevenLabsSDK.Conversation?
    @State private var mode: ElevenLabsSDK.Mode = .listening
    @State private var status: ElevenLabsSDK.Status = .disconnected
    @State private var audioLevel: Float = 0.0

    private func startConversation() {
        Task {
            do {
                let config = ElevenLabsSDK.SessionConfig(agentId: "your-agent-id")
                var callbacks = ElevenLabsSDK.Callbacks()

                callbacks.onConnect = { conversationId in
                    status = .connected
                }
                callbacks.onDisconnect = {
                    status = .disconnected
                }
                callbacks.onModeChange = { newMode in
                    DispatchQueue.main.async {
                        mode = newMode
                    }
                }
                callbacks.onVolumeUpdate = { newVolume in
                    DispatchQueue.main.async {
                        audioLevel = newVolume
                    }
                }

                conversation = try await ElevenLabsSDK.Conversation.startSession(
                    config: config,
                    callbacks: callbacks
                )
            } catch {
                print("Failed to start conversation: \(error)")
            }
        }
    }

    var body: some View {
        VStack {
            // Your UI implementation
            Button(action: startConversation) {
                Text(status == .connected ? "End Call" : "Start Call")
            }
        }
    }
}
```

<Note>
  This SDK is currently experimental and under active development. While it's
  stable enough for testing and development, it's not recommended for production
  use yet.
</Note>


# Project Examples





# How to dub video and audio with ElevenLabs

Learn how to automate the dubbing of audio and video files into various languages using the ElevenLabs API

## Introduction

Dubbing videos and audio files from one language to another can be a great way to reach a wider audience. The ElevenLabs API provides a convenient way to automatically dub media files using state-of-the-art technology. In this guide, we will walk you through how to upload a video or audio file, dub it, and download the translated video. We'll also discuss how to directly dub a link such as a YouTube, TikTok, or Twitter video.

If you're looking to jump straight into the action, the complete code is available on the following repos:

*   [Python example repo](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/dubbing/python).

<Tip>
  On the 8th of May 2024 we launched the Dubbing API for all ElevenLabs tiers
</Tip>

## How to upload and dub a video or audio file

### Requirements

Before proceeding, please ensure that you have the following:

*   An ElevenLabs account with an API key (here’s how to [find your API key](/api-reference/text-to-speech#authentication)).
*   Python or Node.js installed on your machine

Then, install the ElevenLabs SDK as shown below

<CodeGroup>
  ```bash Python
  pip install elevenlabs
  ```
</CodeGroup>

Install the necessary packages to manage your environmental variables:

<CodeGroup>
  ```bash Python
  pip install python-dotenv
  ```
</CodeGroup>

Next, create a `.env` file in your project directory and fill it with your credentials like so:

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

### Start the dubbing

First we want to send the file to the ElevenLabs dubbing service

<CodeGroup>
  ```python Python

  def create_dub_from_file(
      input_file_path: str,
      file_format: str,
      source_language: str,
      target_language: str,
  ) -> Optional[str]:
      """
      Dubs an audio or video file from one language to another and saves the output.

      Args:
          input_file_path (str): The file path of the audio or video to dub.
          file_format (str): The file format of the input file.
          source_language (str): The language of the input file.
          target_language (str): The target language to dub into.

      Returns:
          Optional[str]: The file path of the dubbed file or None if operation failed.
      """
      if not os.path.isfile(input_file_path):
          raise FileNotFoundError(f"The input file does not exist: {input_file_path}")

      with open(input_file_path, "rb") as audio_file:
          response = client.dubbing.dub_a_video_or_an_audio_file(
              file=(os.path.basename(input_file_path), audio_file, file_format), # Optional file
              target_lang=target_language, # The target language to dub the content into. Can be none if dubbing studio editor is enabled and running manual mode
              mode="automatic", # automatic or manual.
              source_lang=source_language, # Source language
              num_speakers=1, # Number of speakers to use for the dubbing.
              watermark=False,  # Whether to apply watermark to the output video.
          )

      # rest of the code

  ```
</CodeGroup>

### Check for completion

The `wait_for_dubbing_completion()` function within the `dubbing_utils.py` file polls the API to check whether the dubbing process is complete. If completed, it proceeds to the next step; otherwise, it reports the status or failure.

<CodeGroup>
  ```python Python

  def wait_for_dubbing_completion(dubbing_id: str) -> bool:
      """
      Waits for the dubbing process to complete by periodically checking the status.

      Args:
          dubbing_id (str): The dubbing project id.

      Returns:
          bool: True if the dubbing is successful, False otherwise.
      """
      MAX_ATTEMPTS = 120
      CHECK_INTERVAL = 10  # In seconds

      for _ in range(MAX_ATTEMPTS):
          metadata = client.dubbing.get_dubbing_project_metadata(dubbing_id)
          if metadata.status == "dubbed":
              return True
          elif metadata.status == "dubbing":
              print(
                  "Dubbing in progress... Will check status again in",
                  CHECK_INTERVAL,
                  "seconds.",
              )
              time.sleep(CHECK_INTERVAL)
          else:
              print("Dubbing failed:", metadata.error_message)
              return False

      print("Dubbing timed out")
      return False

  ```
</CodeGroup>

### Save the video locally

Upon completion of dubbing, the `download_dubbed_file()` function in `dubbing_utils.py` will save the dubbed file to a local directory, typically under the `data/{dubbing_id}/{language_code}.mp4`.

<CodeGroup>
  ```python Python

  def download_dubbed_file(dubbing_id: str, language_code: str) -> str:
      """
      Downloads the dubbed file for a given dubbing ID and language code.

      Args:
          dubbing_id: The ID of the dubbing project.
          language_code: The language code for the dubbing.

      Returns:
          The file path to the downloaded dubbed file.
      """
      dir_path = f"data/{dubbing_id}"
      os.makedirs(dir_path, exist_ok=True)

      file_path = f"{dir_path}/{language_code}.mp4"
      with open(file_path, "wb") as file:
          for chunk in client.dubbing.get_dubbed_file(dubbing_id, language_code):
              file.write(chunk)

      return file_path

  ```
</CodeGroup>

### Putting it together

We add the `wait_for_dubbing_completion`(`waitForDubbingCompletion`) function and the `download_dubbed_file`(`downloadDubbedFile`) function together to create the final function.

<CodeGroup>
  ```python Python
  def create_dub_from_file(
      input_file_path: str,
      file_format: str,
      source_language: str,
      target_language: str,
  ) -> Optional[str]:
      """
      Dubs an audio or video file from one language to another and saves the output.

      Args:
          input_file_path (str): The file path of the audio or video to dub.
          file_format (str): The file format of the input file.
          source_language (str): The language of the input file.
          target_language (str): The target language to dub into.

      Returns:
          Optional[str]: The file path of the dubbed file or None if operation failed.
      """
      if not os.path.isfile(input_file_path):
          raise FileNotFoundError(f"The input file does not exist: {input_file_path}")

      with open(input_file_path, "rb") as audio_file:
          response = client.dubbing.dub_a_video_or_an_audio_file(
              file=(os.path.basename(input_file_path), audio_file, file_format),
              target_lang=target_language,
              mode="automatic",
              source_lang=source_language,
              num_speakers=1,
              watermark=False,  # reduces the characters used if enabled, only works for videos not audio
          )

      dubbing_id = response.dubbing_id
      if wait_for_dubbing_completion(dubbing_id):
          output_file_path = download_dubbed_file(dubbing_id, target_language)
          return output_file_path
      else:
          return None

  ```
</CodeGroup>

We then use the final the function as shown below.

<CodeGroup>
  ```python create_a_dub_from_file.py (Python)

  if __name__ == "__main__":
      result = create_dub_from_file(
          "../example_speech.mp3",  # Input file path
          "audio/mpeg",  # File format
          "en",  # Source language
          "es",  # Target language
      )
      if result:
          print("Dubbing was successful! File saved at:", result)
      else:
          print("Dubbing failed or timed out.")

  ```
</CodeGroup>

## How to dub a video from YouTube, TikTok, Twitter or Vimeo

For dubbing web-based content, instead of uploading a file you can pass in a URL. This supports popular platforms like YouTube, TikTok, Twitter, and Vimeo.

<CodeGroup>
  ```python Python

  def create_dub_from_url(
      source_url: str,
      source_language: str,
      target_language: str,
  ) -> Optional[str]:
      """
      Downloads a video from a URL, and creates a dubbed version in the target language.

      Args:
          source_url (str): The URL of the source video to dub. Can be a YouTube link, TikTok, X (Twitter) or a Vimeo link.
          source_language (str): The language of the source video.
          target_language (str): The target language to dub into.

      Returns:
          Optional[str]: The file path of the dubbed file or None if operation failed.
      """

      response = client.dubbing.dub_a_video_or_an_audio_file(
        source_url=source_url, # URL of the source video/audio file.
        target_lang=target_language, # The Target language to dub the content into. Can be none if dubbing studio editor is enabled and running manual mode
        mode="automatic", # automatic or manual.
        source_lang=source_language, # Source language.
        num_speakers=1, # Number of speakers to use for the dubbing.
        watermark=True,  # Whether to apply watermark to the output video.
      )

      dubbing_id = response.dubbing_id
      if wait_for_dubbing_completion(dubbing_id):
          output_file_path = download_dubbed_file(dubbing_id, target_language)
          return output_file_path
      else:
          return None

  ```
</CodeGroup>

You can then call the function as shown below.

<CodeGroup>
  ```python Python

  if __name__ == "__main__":
      source_url = "https://www.youtube.com/watch?v=0EqSXDwTq6U"  # Charlie bit my finger
      source_language = "en"
      target_language = "fr"
      result = create_dub_from_url(source_url, source_language, target_language)
      if result:
          print("Dubbing was successful! File saved at:", result)
      else:
          print("Dubbing failed or timed out.")

  ```
</CodeGroup>

## Conclusion

With this guide and the accompanying code structure, you now have a basic setup for dubbing audio and video content using the ElevenLabs API. Whether you're working with local files or content from URLs, you can create multilingual versions of your media to cater to diverse audiences.

Remember to always follow the best practices when dealing with API keys and sensitive data, and consult the ElevenLabs API documentation for more advanced features and options. Happy dubbing!

For additional information on dubbing capabilities, translation services, and available languages, please refer to the [ElevenLabs API documentation](https://elevenlabs.docs.buildwithfern.com/docs/developers/api-reference/dubbing/dub-a-video-or-an-audio-file).

Should you encounter any issues or have questions, our [GitHub Issues page](https://github.com/elevenlabs/elevenlabs-docs/issues) is open for your queries and feedback.

## List of supported languages for dubbing

| No | Language Name | Language Code |
| -- | ------------- | ------------- |
| 1  | English       | en            |
| 2  | Hindi         | hi            |
| 3  | Portuguese    | pt            |
| 4  | Chinese       | zh            |
| 5  | Spanish       | es            |
| 6  | French        | fr            |
| 7  | German        | de            |
| 8  | Japanese      | ja            |
| 9  | Arabic        | ar            |
| 10 | Russian       | ru            |
| 11 | Korean        | ko            |
| 12 | Indonesian    | id            |
| 13 | Italian       | it            |
| 14 | Dutch         | nl            |
| 15 | Turkish       | tr            |
| 16 | Polish        | pl            |
| 17 | Swedish       | sv            |
| 18 | Filipino      | fil           |
| 19 | Malay         | ms            |
| 20 | Romanian      | ro            |
| 21 | Ukrainian     | uk            |
| 22 | Greek         | el            |
| 23 | Czech         | cs            |
| 24 | Danish        | da            |
| 25 | Finnish       | fi            |
| 26 | Bulgarian     | bg            |
| 27 | Croatian      | hr            |
| 28 | Slovak        | sk            |
| 29 | Tamil         | ta            |


# How to Use Pronunciation Dictionaries

How to add, view, and remove rules to pronunciation dictionaries with the Python SDK

In this tutorial, you'll learn how to use a pronunciation dictionary with the ElevenLabs Python SDK. Pronunciation dictionaries are useful for controlling the specific pronunciation of words. We support both [IPA](https://en.wikipedia.org/wiki/International_Phonetic_Alphabet) and [CMU](https://en.wikipedia.org/wiki/CMU_Pronouncing_Dictionary) alphabets. It is useful for correcting rare or specific pronunciations, such as names or companies. For example, the word `nginx` could be pronounced incorrectly. Instead, we can add our version of pronunciation. Based on IPA, `nginx` is pronounced as `/ˈɛndʒɪnˈɛks/`. Finding IPA or CMU of words manually can be difficult. Instead, LLMs like ChatGPT can help you to make the search easier.

We'll start by adding rules to the pronunciation dictionary from a file and comparing the text-to-speech results that use and do not use the dictionary. After that, we'll discuss how to add and remove specific rules to existing dictionaries.

If you want to jump straight to the finished repo you can find it [here](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/pronunciation-dictionaries/python)

<Info>
  Alias tags are supported by all models excluding `eleven_turbo_v2_5`. Phoneme
  tags only work with the models `eleven_turbo_v2` and `eleven_monolingual_v1`.
  If you use phoneme tags with other models, they will silently skip the word.
</Info>

## Requirements

*   An ElevenLabs account with an API key (here’s how to [find your API key](/api-reference/text-to-speech#authentication)).
*   Python installed on your machine
*   FFMPEG to play audio

## Setup

### Installing our SDK

Before you begin, make sure you have installed the necessary SDKs and libraries. You will need the ElevenLabs SDK for the updating pronunciation dictionary and using text-to-speech conversion. You can install it using pip:

```bash
pip install elevenlabs
```

Additionally, install `python-dotenv` to manage your environmental variables:

```bash
pip install python-dotenv
```

Next, create a `.env` file in your project directory and fill it with your credentials like so:

```
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

## Initiate the Client SDK

We'll start by initializing the client SDK.

```python
import os
from elevenlabs.client import ElevenLabs

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
client = ElevenLabs(
    api_key=ELEVENLABS_API_KEY,
)
```

## Create a Pronunciation Dictionary From a File

To create a pronunciation dictionary from a File, we'll create a `.pls` file for our rules.

This rule will use the "IPA" alphabet and update the pronunciation for `tomato` and `Tomato` with a different pronunciation. PLS files are case sensitive which is why we include it both with and without a capital "T". Save it as `dictionary.pls`.

```xml filename="dictionary.pls"
<?xml version="1.0" encoding="UTF-8"?>
<lexicon version="1.0"
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
      alphabet="ipa" xml:lang="en-US">
  <lexeme>
    <grapheme>tomato</grapheme>
    <phoneme>/tə'meɪtoʊ/</phoneme>
  </lexeme>
  <lexeme>
    <grapheme>Tomato</grapheme>
    <phoneme>/tə'meɪtoʊ/</phoneme>
  </lexeme>
</lexicon>
```

In the following snippet, we start by adding rules from a file and get the uploaded result. Finally, we generate and play two different text-to-speech audio to compare the custom pronunciation dictionary.

```python
import requests
from elevenlabs import play, PronunciationDictionaryVersionLocator

with open("dictionary.pls", "rb") as f:
    # this dictionary changes how tomato is pronounced
    pronunciation_dictionary = client.pronunciation_dictionary.add_from_file(
        file=f.read(), name="example"
    )

audio_1 = client.generate(
    text="Without the dictionary: tomato",
    voice="Rachel",
    model="eleven_turbo_v2",
)

audio_2 = client.generate(
    text="With the dictionary: tomato",
    voice="Rachel",
    model="eleven_turbo_v2",
    pronunciation_dictionary_locators=[
        PronunciationDictionaryVersionLocator(
            pronunciation_dictionary_id=pronunciation_dictionary.id,
            version_id=pronunciation_dictionary.version_id,
        )
    ],
)

# play the audio
play(audio_1)
play(audio_2)
```

## Remove Rules From a Pronunciation Dictionary

To remove rules from a pronunciation dictionary, we can simply call `remove_rules_from_the_pronunciation_dictionary` method in the pronunciation dictionary module. In the following snippet, we start by removing rules based on the rule string and get the updated result. Finally, we generate and play another text-to-speech audio to test the difference. In the example, we take pronunciation dictionary version id from `remove_rules_from_the_pronunciation_dictionary` response because every changes to pronunciation dictionary will create a new version, so we need to use the latest version returned from the response. The old version also still available.

```python
pronunciation_dictionary_rules_removed = (
    client.pronunciation_dictionary.remove_rules_from_the_pronunciation_dictionary(
        pronunciation_dictionary_id=pronunciation_dictionary.id,
        rule_strings=["tomato", "Tomato"],
    )
)

audio_3 = client.generate(
    text="With the rule removed: tomato",
    voice="Rachel",
    model="eleven_turbo_v2",
    pronunciation_dictionary_locators=[
        PronunciationDictionaryVersionLocator(
            pronunciation_dictionary_id=pronunciation_dictionary_rules_removed.id,
            version_id=pronunciation_dictionary_rules_removed.version_id,
        )
    ],
)

play(audio_3)
```

## Add Rules to Pronunciation Dictionary

We can add rules directly to the pronunciation dictionary with `PronunciationDictionaryRule_Phoneme` class and call `add_rules_to_the_pronunciation_dictionary` from the pronunciation dictionary. The snippet will demonstrate adding rules with the class and get the updated result. Finally, we generate and play another text-to-speech audio to test the difference. This example also use pronunciation dictionary version returned from `add_rules_to_the_pronunciation_dictionary` to ensure we use the latest dictionary version.

```python
from elevenlabs import PronunciationDictionaryRule_Phoneme

pronunciation_dictionary_rules_added = client.pronunciation_dictionary.add_rules_to_the_pronunciation_dictionary(
    pronunciation_dictionary_id=pronunciation_dictionary_rules_removed.id,
    rules=[
        PronunciationDictionaryRule_Phoneme(
            type="phoneme",
            alphabet="ipa",
            string_to_replace="tomato",
            phoneme="/tə'meɪtoʊ/",
        ),
        PronunciationDictionaryRule_Phoneme(
            type="phoneme",
            alphabet="ipa",
            string_to_replace="Tomato",
            phoneme="/tə'meɪtoʊ/",
        ),
    ],
)

audio_4 = client.generate(
    text="With the rule added again: tomato",
    voice="Rachel",
    model="eleven_turbo_v2",
    pronunciation_dictionary_locators=[
        PronunciationDictionaryVersionLocator(
            pronunciation_dictionary_id=pronunciation_dictionary_rules_added.id,
            version_id=pronunciation_dictionary_rules_added.version_id,
        )
    ],
)

play(audio_4)
```

## Conclusion

You know how to use a pronunciation dictionary for generating text-to-speech audio. These functionailities open up opportunities to generate text-to-speech audio based on your pronunciation dictionary, making it more flexible for your use case.

For more details, visit our [example repo](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/pronunciation-dictionaries/python) to see the full project files which give a clear structure for setting up your application:

*   `env.example`: Template for your environment variables.
*   `main.py`: The complete code for snippets above.
*   `dictionary.pls`: Custom dictionary example with XML format.
*   `requirements.txt`: List of python package used for this example.

If you have any questions please create an issue on the [elevenlabs-doc Github](https://github.com/elevenlabs/elevenlabs-docs/issues).


# Combine Multiple Generations

Learn how to keep your voice stable across multiple generations

## What is Request Stitching?

When one has a large text to convert into audio and sends the text in chunks without further context there can be abrupt changes in prosody from one chunk to another.

It would be much better to give the model context on what was already generated and what will be generated in the future, this is exactly what Request Stitching does.

As you can see below the difference between not using Request Stitching and using it is subtle but noticeable:

#### Without Request Stitching:

<video controls className="w-full" src="https://eleven-public-cdn.elevenlabs.io/audio/docs/without_request_stitching.mp3" style={{ height: 60 }} />

#### With Request Stitching:

<video controls className="w-full" src="https://eleven-public-cdn.elevenlabs.io/audio/docs/with_request_stitching.mp3" style={{ height: 60 }} />

## Conditioning on text

We will use Pydub for concatenating multiple audios together, you can install it using:

```bash
pip install pydub
```

One of the two ways on how to give the model context is to provide the text before and / or after the current chunk by using the 'previous\_text' and 'next\_text' parameters:

```python
import os
import requests
from pydub import AudioSegment
import io

YOUR_XI_API_KEY = "<insert your xi-api-key here>"
VOICE_ID = "21m00Tcm4TlvDq8ikWAM"  # Rachel
PARAGRAPHS = [
    "The advent of technology has transformed countless sectors, with education "
    "standing out as one of the most significantly impacted fields.",
    "In recent years, educational technology, or EdTech, has revolutionized the way "
    "teachers deliver instruction and students absorb information.",
    "From interactive whiteboards to individual tablets loaded with educational software, "
    "technology has opened up new avenues for learning that were previously unimaginable.",
    "One of the primary benefits of technology in education is the accessibility it provides.",
]
segments = []

for i, paragraph in enumerate(PARAGRAPHS):
    is_last_paragraph = i == len(PARAGRAPHS) - 1
    is_first_paragraph = i == 0
    response = requests.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream",
        json={
            "text": paragraph,
            "model_id": "eleven_multilingual_v2",
            "previous_text": None if is_first_paragraph else " ".join(PARAGRAPHS[:i]),
            "next_text": None if is_last_paragraph else " ".join(PARAGRAPHS[i + 1:])
        },
        headers={"xi-api-key": YOUR_XI_API_KEY},
    )

    if response.status_code != 200:
        print(f"Error encountered, status: {response.status_code}, "
               f"content: {response.text}")
        quit()

    print(f"Successfully converted paragraph {i + 1}/{len(PARAGRAPHS)}")
    segments.append(AudioSegment.from_mp3(io.BytesIO(response.content)))

segment = segments[0]
for new_segment in segments[1:]:
    segment = segment + new_segment

audio_out_path = os.path.join(os.getcwd(), "with_text_conditioning.wav")
segment.export(audio_out_path, format="wav")
print(f"Success! Wrote audio to {audio_out_path}")
```

## Conditioning on past generations

Text conditioning works well when there has been no previous or next chunks generated yet. If there have been however, it works much better to provide the actual past generations to the model instead of just the text.
This is done by using the previous\_request\_ids and next\_request\_ids parameters.

Every text-to-speech request has an associated request-id which is obtained by reading from the response header. Below is an example on how to use this request\_id in order to condition requests on the previous generations.

```python
import os
import requests
from pydub import AudioSegment
import io

YOUR_XI_API_KEY = "<insert your xi-api-key here>"
VOICE_ID = "21m00Tcm4TlvDq8ikWAM"  # Rachel
PARAGRAPHS = [
    "The advent of technology has transformed countless sectors, with education "
    "standing out as one of the most significantly impacted fields.",
    "In recent years, educational technology, or EdTech, has revolutionized the way "
    "teachers deliver instruction and students absorb information.",
    "From interactive whiteboards to individual tablets loaded with educational software, "
    "technology has opened up new avenues for learning that were previously unimaginable.",
    "One of the primary benefits of technology in education is the accessibility it provides.",
]
segments = []
previous_request_ids = []

for i, paragraph in enumerate(PARAGRAPHS):
    response = requests.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream",
        json={
            "text": paragraph,
            "model_id": "eleven_multilingual_v2",
            # A maximum of three next or previous history item ids can be send
            "previous_request_ids": previous_request_ids[-3:],
        },
        headers={"xi-api-key": YOUR_XI_API_KEY},
    )

    if response.status_code != 200:
        print(f"Error encountered, status: {response.status_code}, "
               f"content: {response.text}")
        quit()

    print(f"Successfully converted paragraph {i + 1}/{len(PARAGRAPHS)}")
    previous_request_ids.append(response.headers["request-id"])
    segments.append(AudioSegment.from_mp3(io.BytesIO(response.content)))

segment = segments[0]
for new_segment in segments[1:]:
    segment = segment + new_segment

audio_out_path = os.path.join(os.getcwd(), "with_previous_request_ids_conditioning.wav")
segment.export(audio_out_path, format="wav")
print(f"Success! Wrote audio to {audio_out_path}")
```

<b>Note that the order matters here</b>: When one converts a text split into 5
chunks and has already converted chunks 1, 2, 4 and 5 and now wants to convert
chunk 3 the previous\_request\_ids one neeeds to send would be
\[request\_id\_chunk\_1, request\_id\_chunk\_2] and the next\_request\_ids would be
\[request\_id\_chunk\_4, request\_id\_chunk\_5].

## Conditioning both on text and past generations

The best possible results are achieved when conditioning both on text and past generations so lets combine the two by providing previous\_text, next\_text and previous\_request\_ids in one request:

```python
import os
import requests
from pydub import AudioSegment
import io

YOUR_XI_API_KEY = "<insert your xi-api-key here>"
VOICE_ID = "21m00Tcm4TlvDq8ikWAM"  # Rachel
PARAGRAPHS = [
    "The advent of technology has transformed countless sectors, with education "
    "standing out as one of the most significantly impacted fields.",
    "In recent years, educational technology, or EdTech, has revolutionized the way "
    "teachers deliver instruction and students absorb information.",
    "From interactive whiteboards to individual tablets loaded with educational software, "
    "technology has opened up new avenues for learning that were previously unimaginable.",
    "One of the primary benefits of technology in education is the accessibility it provides.",
]
segments = []
previous_request_ids = []

for i, paragraph in enumerate(PARAGRAPHS):
    is_first_paragraph = i == 0
    is_last_paragraph = i == len(PARAGRAPHS) - 1
    response = requests.post(
        f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream",
        json={
            "text": paragraph,
            "model_id": "eleven_multilingual_v2",
            # A maximum of three next or previous history item ids can be send
            "previous_request_ids": previous_request_ids[-3:],
            "previous_text": None if is_first_paragraph else " ".join(PARAGRAPHS[:i]),
            "next_text": None if is_last_paragraph else " ".join(PARAGRAPHS[i + 1:])
        },
        headers={"xi-api-key": YOUR_XI_API_KEY},
    )

    if response.status_code != 200:
        print(f"Error encountered, status: {response.status_code}, "
               f"content: {response.text}")
        quit()

    print(f"Successfully converted paragraph {i + 1}/{len(PARAGRAPHS)}")
    previous_request_ids.append(response.headers["request-id"])
    segments.append(AudioSegment.from_mp3(io.BytesIO(response.content)))

segment = segments[0]
for new_segment in segments[1:]:
    segment = segment + new_segment

audio_out_path = os.path.join(os.getcwd(), "with_full_conditioning.wav")
segment.export(audio_out_path, format="wav")
print(f"Success! Wrote audio to {audio_out_path}")
```

## Things to note

1.  Providing wrong previous\_request\_ids and next\_request\_ids will not result in an error.
2.  In order to use the request\_id of a request for conditioning it needs to have processed completely. In case of streaming this means the audio has to be read completely from the response body.
3.  How well Request Stitching works varies greatly dependent on the model, voice and voice settings used.
4.  previous\_request\_ids and next\_request\_ids should contain request\_ids which are not too old. When the request\_ids are older than two hours it will diminish the effect of conditioning.
5.  Enterprises with increased privacy requirements will have Request Stitching disabled.


# How to Use the Text to Sound Effects API

Learn how to use the text to sound effects API to generate sound effects from text.

## Introduction

Our [text to sound effects](https://elevenlabs.io/sound-effects) model enables you to create high-quality sound effects from a short description. These sound effects could be used in a variety of applications, including game development and building apps for music production.

In this tutorial, we will use the text to sound effects API to generate a sound effect from a short description using the Python SDK. We'll then save this sound effect to a file.

<Tip>
  For general tips on prompting, see the [sound effects product
  docs](/product/sound-effects/overview). And for information on the API
  configuration visit [the API reference](/api-reference/sound-generation).
</Tip>

## How to generate a sound effect with the API

### Requirements

Before proceeding, please ensure that you have the following:

*   An ElevenLabs account with an API key (here’s how to [find your API key](/api-reference/text-to-speech#authentication))
*   Python or Node.js installed on your machine

Then, install the ElevenLabs SDK as shown below

<CodeGroup>
  ```bash Python
  pip install elevenlabs
  ```
</CodeGroup>

Install the necessary packages to manage your environmental variables:

<CodeGroup>
  ```bash Python
  pip install python-dotenv
  ```
</CodeGroup>

Next, create a `.env` file in your project directory and fill it with your credentials like so:

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

### Using the sound effects SDK

Now we can use the SDK to generate a sound effect from a short description and save it to a file as shown below.

```python

import os
from elevenlabs.client import ElevenLabs

from dotenv import load_dotenv

load_dotenv()

elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))


def generate_sound_effect(text: str, output_path: str):
    print("Generating sound effects...")

    result = elevenlabs.text_to_sound_effects.convert(
        text=text,
        duration_seconds=10,  # Optional, if not provided will automatically determine the correct length
        prompt_influence=0.3,  # Optional, if not provided will use the default value of 0.3
    )

    with open(output_path, "wb") as f:
        for chunk in result:
            f.write(chunk)

    print(f"Audio saved to {output_path}")


if __name__ == "__main__":
    generate_sound_effect("Dog barking", "output.mp3")

```

## Configuration

*   `duration_seconds`: The duration of the sound effect in seconds. If not provided, the API will automatically determine the correct length. The maximum value is 22
*   `prompt_influence`: The amount of influence the prompt has on the generated sound effect. If not provided, the API will use the default value of 0.3

### API pricing

The API is charged at 100 characters per generation with automatic duration or 25 characters per second with a set duration.

### Next steps

We're excited to see what you build with the API. Here are some ideas of what you might want to use it for:

*   Adding sound effect generation to a video editing application
*   Enabling users to create on-demand samples for their music production
*   A new type of video game where every sound is generated dynamically

For higher rate limits of volume based discounts please [contact sales](https://elevenlabs.io/contact-sales).


# How to use text to speech with streaming in Python or Node.js

How to convert text into speech, upload to S3, and share with a signed URL

In this tutorial, you'll learn how to convert [text to speech](https://elevenlabs.io/text-to-speech) with the ElevenLabs SDK. We’ll start by talking through how to generate speech and receive a file and then how to generate speech and stream the response back. Finally, as a bonus we’ll show you how to upload the generated audio to an AWS S3 bucket, and share it through a signed URL. This signed URL will provide temporary access to the audio file, making it perfect for sharing with users by SMS or embedding into an application.

If you want to jump straight to the finished repo you can find it.

*   [Python](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-speech/python).
*   [Node.js](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-speech/node).

## Requirements

*   An ElevenLabs account with an API key (here’s how to [find your API key](/developer-guides/quickstart#authentication)).
*   Python(Node.js, TypeScript) installed on your machine
*   (Optionally) an AWS account with access to S3.

## Setup

### Installing our SDK

Before you begin, make sure you have installed the necessary SDKs and libraries. You will need the ElevenLabs SDK for the text to speech conversion. You can install it using pip:

<CodeGroup>
  ```bash Python
  pip install elevenlabs
  ```

  ```bash TypeScript
  npm install elevenlabs
  ```
</CodeGroup>

Additionally, install necessary packages to manage your environmental variables:

<CodeGroup>
  ```bash Python
  pip install python-dotenv
  ```

  ```bash TypeScript
  npm install dotenv
  npm install @types/dotenv --save-dev
  ```
</CodeGroup>

Next, create a `.env` file in your project directory and fill it with your credentials like so:

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

## Convert text to speech (file)

To convert text to speech and save it as a file, we’ll use the `convert` method of the ElevenLabs SDK and then it locally as a `.mp3` file.

<CodeGroup>
  ```python text_to_speech_file.py (Python)

  import os
  import uuid
  from elevenlabs import VoiceSettings
  from elevenlabs.client import ElevenLabs

  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
  client = ElevenLabs(
      api_key=ELEVENLABS_API_KEY,
  )


  def text_to_speech_file(text: str) -> str:
      # Calling the text_to_speech conversion API with detailed parameters
      response = client.text_to_speech.convert(
          voice_id="pNInz6obpgDQGcFmaJgB", # Adam pre-made voice
          output_format="mp3_22050_32",
          text=text,
          model_id="eleven_turbo_v2_5", # use the turbo model for low latency
          voice_settings=VoiceSettings(
              stability=0.0,
              similarity_boost=1.0,
              style=0.0,
              use_speaker_boost=True,
          ),
      )

      # uncomment the line below to play the audio back
      # play(response)

      # Generating a unique file name for the output MP3 file
      save_file_path = f"{uuid.uuid4()}.mp3"

      # Writing the audio to a file
      with open(save_file_path, "wb") as f:
          for chunk in response:
              if chunk:
                  f.write(chunk)

      print(f"{save_file_path}: A new audio file was saved successfully!")

      # Return the path of the saved audio file
      return save_file_path

  ```

  ```typescript text_to_speech_file.ts (Typescript)
  import { ElevenLabsClient } from "elevenlabs";
  import { createWriteStream } from "fs";

  import { v4 as uuid } from "uuid";

  import * as dotenv from "dotenv";

  dotenv.config();

  const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

  const client = new ElevenLabsClient({
    apiKey: ELEVENLABS_API_KEY,
  });

  export const createAudioFileFromText = async (
    text: string
  ): Promise<string> => {
    return new Promise<string>(async (resolve, reject) => {
      try {
        const audio = await client.generate({
          voice: "Rachel",
          model_id: "eleven_turbo_v2_5",
          text,
        });
        const fileName = `${uuid()}.mp3`;
        const fileStream = createWriteStream(fileName);

        audio.pipe(fileStream);
        fileStream.on("finish", () => resolve(fileName)); // Resolve with the fileName
        fileStream.on("error", reject);
      } catch (error) {
        reject(error);
      }
    });
  };
  ```
</CodeGroup>

You can then run this function with:

<CodeGroup>
  ```python Python
  text_to_speech_file("Hello World")
  ```

  ```typescript TypeScript
  await createAudioFileFromText("Hello World");
  ```
</CodeGroup>

## Convert text to speech (streaming)

If you prefer to stream the audio directly without saving it to a file, you can use our streaming feature.

<CodeGroup>
  ```python text_to_speech_stream.py (Python)

  import os
  from typing import IO
  from io import BytesIO
  from elevenlabs import VoiceSettings
  from elevenlabs.client import ElevenLabs

  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
  client = ElevenLabs(
      api_key=ELEVENLABS_API_KEY,
  )


  def text_to_speech_stream(text: str) -> IO[bytes]:
      # Perform the text-to-speech conversion
      response = client.text_to_speech.convert(
          voice_id="pNInz6obpgDQGcFmaJgB", # Adam pre-made voice
          output_format="mp3_22050_32",
          text=text,
          model_id="eleven_multilingual_v2",
          voice_settings=VoiceSettings(
              stability=0.0,
              similarity_boost=1.0,
              style=0.0,
              use_speaker_boost=True,
          ),
      )

      # Create a BytesIO object to hold the audio data in memory
      audio_stream = BytesIO()

      # Write each chunk of audio data to the stream
      for chunk in response:
          if chunk:
              audio_stream.write(chunk)

      # Reset stream position to the beginning
      audio_stream.seek(0)

      # Return the stream for further use
      return audio_stream

  ```

  ```typescript text_to_speech_stream.ts (Typescript)
  import { ElevenLabsClient } from "elevenlabs";
  import * as dotenv from "dotenv";

  dotenv.config();

  const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

  if (!ELEVENLABS_API_KEY) {
    throw new Error("Missing ELEVENLABS_API_KEY in environment variables");
  }

  const client = new ElevenLabsClient({
    apiKey: ELEVENLABS_API_KEY,
  });

  export const createAudioStreamFromText = async (
    text: string
  ): Promise<Buffer> => {
    const audioStream = await client.generate({
      voice: "Rachel",
      model_id: "eleven_turbo_v2_5",
      text,
    });

    const chunks: Buffer[] = [];
    for await (const chunk of audioStream) {
      chunks.push(chunk);
    }

    const content = Buffer.concat(chunks);
    return content;
  };
  ```
</CodeGroup>

You can then run this function with:

<CodeGroup>
  ```python Python
  text_to_speech_stream("This is James")
  ```

  ```typescript TypeScript
  await createAudioStreamFromText("This is James");
  ```
</CodeGroup>

## Bonus - Uploading to AWS S3 and getting a secure sharing link

Once your audio data is created as either a file or a stream you might want to share this with your users. One way to do this is to upload it to an AWS S3 bucket and generate a secure sharing link.

<AccordionGroup>
  <Accordion title="Creating your AWS credentials">
    To upload the data to S3 you’ll need to add your AWS access key ID, secret access key and AWS region name to your `.env` file. Follow these steps to find the credentials:

    1.  Log in to your AWS Management Console: Navigate to the AWS home page and sign in with your account.

    <Frame caption="AWS Console Login">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_console_login.png" />
    </Frame>

    2.  Access the IAM (Identity and Access Management) Dashboard: You can find IAM under "Security, Identity, & Compliance" on the services menu. The IAM dashboard manages access to your AWS services securely.

    <Frame caption="AWS IAM Dashboard">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_iam_dashboard.png" />
    </Frame>

    3.  Create a New User (if necessary): On the IAM dashboard, select "Users" and then "Add user". Enter a user name.

    <Frame caption="Add AWS IAM User">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_iam_add_user.png" />
    </Frame>

    4.  Set the permissions: attach policies directly to the user according to the access level you wish to grant. For S3 uploads, you can use the AmazonS3FullAccess policy. However, it's best practice to grant least privilege, or the minimal permissions necessary to perform a task. You might want to create a custom policy that specifically allows only the necessary actions on your S3 bucket.

    <Frame caption="Set Permission for AWS IAM User">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_iam_set_permission.png" />
    </Frame>

    5.  Review and create the user: Review your settings and create the user. Upon creation, you'll be presented with an access key ID and a secret access key. Be sure to download and securely save these credentials; the secret access key cannot be retrieved again after this step.

    <Frame caption="AWS Access Secret Key">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_access_secret_key.png" />
    </Frame>

    6.  Get AWS region name: ex. us-east-1

    <Frame caption="AWS Region Name">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_region_name.png" />
    </Frame>

    If you do not have an AWS S3 bucket, you will need to create a new one by following these steps:

    1.  Access the S3 dashboard: You can find S3 under "Storage" on the services menu.

    <Frame caption="AWS S3 Dashboard">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_s3_dashboard.png" />
    </Frame>

    2.  Create a new bucket: On the S3 dashboard, click the "Create bucket" button.

    <Frame caption="Click Create Bucket Button">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_s3_create_bucket.png" />
    </Frame>

    3.  Enter a bucket name and click on the "Create bucket" button. You can leave the other bucket options as default. The newly added bucket will appear in the list.

    <Frame caption="Enter a New S3 Bucket Name">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_s3_enter_bucket_name.png" />
    </Frame>

    <Frame caption="S3 Bucket List">
      <img src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/aws_s3_bucket_list.png" />
    </Frame>
  </Accordion>

  <Accordion title="Installing the AWS SDK and adding the credentials">
    Install `boto3` for interacting with AWS services using `pip` and `npm`.

    <CodeGroup>
      ```bash Python
      pip install boto3
      ```

      ```bash TypeScript
      npm install @aws-sdk/client-s3
      npm install @aws-sdk/s3-request-presigner
      ```
    </CodeGroup>

    Then add the environment variables to `.env` file like so:

    ```
    AWS_ACCESS_KEY_ID=your_aws_access_key_id_here
    AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key_here
    AWS_REGION_NAME=your_aws_region_name_here
    AWS_S3_BUCKET_NAME=your_s3_bucket_name_here
    ```
  </Accordion>

  <Accordion title="Uploading to AWS S3 and generating the signed URL">
    Add the following functions to upload the audio stream to S3 and generate a signed URL.

    <CodeGroup>
      ```python s3_uploader.py (Python)

      import os
      import boto3
      import uuid

      AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
      AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
      AWS_REGION_NAME = os.getenv("AWS_REGION_NAME")
      AWS_S3_BUCKET_NAME = os.getenv("AWS_S3_BUCKET_NAME")

      session = boto3.Session(
          aws_access_key_id=AWS_ACCESS_KEY_ID,
          aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
          region_name=AWS_REGION_NAME,
      )
      s3 = session.client("s3")


      def generate_presigned_url(s3_file_name: str) -> str:
          signed_url = s3.generate_presigned_url(
              "get_object",
              Params={"Bucket": AWS_S3_BUCKET_NAME, "Key": s3_file_name},
              ExpiresIn=3600,
          )  # URL expires in 1 hour
          return signed_url


      def upload_audiostream_to_s3(audio_stream) -> str:
          s3_file_name = f"{uuid.uuid4()}.mp3"  # Generates a unique file name using UUID
          s3.upload_fileobj(audio_stream, AWS_S3_BUCKET_NAME, s3_file_name)

          return s3_file_name

      ```

      ```typescript s3_uploader.ts (TypeScript)
      import {
        S3Client,
        PutObjectCommand,
        GetObjectCommand,
      } from "@aws-sdk/client-s3";
      import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
      import { v4 as uuid } from "uuid";
      import * as dotenv from "dotenv";

      dotenv.config();

      const {
        AWS_ACCESS_KEY_ID,
        AWS_SECRET_ACCESS_KEY,
        AWS_REGION_NAME,
        AWS_S3_BUCKET_NAME,
      } = process.env;

      if (
        !AWS_ACCESS_KEY_ID ||
        !AWS_SECRET_ACCESS_KEY ||
        !AWS_REGION_NAME ||
        !AWS_S3_BUCKET_NAME
      ) {
        throw new Error(
          "One or more environment variables are not set. Please check your .env file."
        );
      }

      const s3 = new S3Client({
        credentials: {
          accessKeyId: AWS_ACCESS_KEY_ID,
          secretAccessKey: AWS_SECRET_ACCESS_KEY,
        },
        region: AWS_REGION_NAME,
      });

      export const generatePresignedUrl = async (objectKey: string) => {
        const getObjectParams = {
          Bucket: AWS_S3_BUCKET_NAME,
          Key: objectKey,
          Expires: 3600,
        };
        const command = new GetObjectCommand(getObjectParams);
        const url = await getSignedUrl(s3, command, { expiresIn: 3600 });
        return url;
      };

      export const uploadAudioStreamToS3 = async (audioStream: Buffer) => {
        const remotePath = `${uuid()}.mp3`;
        await s3.send(
          new PutObjectCommand({
            Bucket: AWS_S3_BUCKET_NAME,
            Key: remotePath,
            Body: audioStream,
            ContentType: "audio/mpeg",
          })
        );
        return remotePath;
      };
      ```
    </CodeGroup>

    You can then call uploading function with the audio stream from the text.

    <CodeGroup>
      ```python Python
      s3_file_name = upload_audiostream_to_s3(audio_stream)
      ```

      ```typescript TypeScript
      const s3path = await uploadAudioStreamToS3(stream);
      ```
    </CodeGroup>

    After uploading the audio file to S3, generate a signed URL to share access to the file. This URL will be time-limited, meaning it will expire after a certain period, making it secure for temporary sharing.

    You can now generate a URL from a file with:

    <CodeGroup>
      ```python Python
      signed_url = generate_presigned_url(s3_file_name)
      print(f"Signed URL to access the file: {signed_url}")
      ```

      ```typescript TypeScript
      const presignedUrl = await generatePresignedUrl(s3path);
      console.log("Presigned URL:", presignedUrl);
      ```
    </CodeGroup>

    If you want to use the file multiple times, you should store the s3 file path in your database and then regenerate the signed URL each time you need rather than saving the signed URL directly as it will expire.
  </Accordion>

  <Accordion title="Putting it all together">
    To put it all together, you can use the following script:

    <CodeGroup>
      ```python main.py (Python)

      import os

      from dotenv import load_dotenv

      load_dotenv()

      from text_to_speech_stream import text_to_speech_stream
      from s3_uploader import upload_audiostream_to_s3, generate_presigned_url


      def main():
          text = "This is James"

          audio_stream = text_to_speech_stream(text)
          s3_file_name = upload_audiostream_to_s3(audio_stream)
          signed_url = generate_presigned_url(s3_file_name)

          print(f"Signed URL to access the file: {signed_url}")


      if __name__ == "__main__":
          main()

      ```

      ```typescript index.ts (Typescript)
      import "dotenv/config";
      import { createAudioFileFromText } from "./text_to_speech_file";
      import { createAudioStreamFromText } from "./text_to_speech_stream";
      import { generatePresignedUrl, uploadAudioStreamToS3 } from "./s3_uploader";

      (async () => {
        // save the audio file to disk
        const fileName = await createAudioFileFromText(
          "Today, the sky is exceptionally clear, and the sun shines brightly."
        );

        console.log("File name:", fileName);

        // OR stream the audio, upload to S3, and get a presigned URL
        const stream = await createAudioStreamFromText(
          "Today, the sky is exceptionally clear, and the sun shines brightly."
        );

        const s3path = await uploadAudioStreamToS3(stream);

        const presignedUrl = await generatePresignedUrl(s3path);

        console.log("Presigned URL:", presignedUrl);
      })();
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Conclusion

You now know how to convert text into speech and generate a signed URL to share the audio file. This functionality opens up numerous opportunities for creating and sharing content dynamically.

Here are some examples of what you could build with this.

1.  **Educational Podcasts**: Create personalized educational content that can be accessed by students on demand. Teachers can convert their lessons into audio format, upload them to S3, and share the links with students for a more engaging learning experience outside the traditional classroom setting.

2.  **Accessibility Features for Websites**: Enhance website accessibility by offering text content in audio format. This can make information on websites more accessible to individuals with visual impairments or those who prefer auditory learning.

3.  **Automated Customer Support Messages**: Produce automated and personalized audio messages for customer support, such as FAQs or order updates. This can provide a more engaging customer experience compared to traditional text emails.

4.  **Audio Books and Narration**: Convert entire books or short stories into audio format, offering a new way for audiences to enjoy literature. Authors and publishers can diversify their content offerings and reach audiences who prefer listening over reading.

5.  **Language Learning Tools**: Develop language learning aids that provide learners with audio lessons and exercises. This makes it possible to practice pronunciation and listening skills in a targeted way.

For more details, visit the following to see the full project files which give a clear structure for setting up your application:

For Python: [example repo](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-speech/python)

For TypeScript: [example repo](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/text-to-speech/node)

If you have any questions please create an issue on the [elevenlabs-doc Github](https://github.com/elevenlabs/elevenlabs-docs/issues).


# How to use text-to-speech with websocket streaming in Python or Node.js

How to convert text to speech via websocket and save to mp3

Websocket streaming is a method of sending and receiving data over a single, long-lived connection. This method is useful for real-time applications where you need to stream audio data as it becomes available.

If you want to quickly test out the latency (time to first byte) of a websocket connection to the ElevenLabs text-to-speech API, you can install `elevenlabs-latency` via `npm` and follow the instructions [here](https://www.npmjs.com/package/elevenlabs-latency?activeTab=readme).

## Requirements

*   An ElevenLabs account with an API key (here’s how to [find your API key](/api-reference/text-to-speech#authentication)).
*   Python or Node.js/Typescript installed on your machine

## Setup

Install dotenv package to manage your environmental variables:

<CodeGroup>
  ```bash Python
  pip install python-dotenv
  pip install websockets
  ```

  ```bash TypeScript
  npm install dotenv
  npm install @types/dotenv --save-dev
  npm install ws
  ```
</CodeGroup>

Next, create a `.env` file in your project directory and fill it with your credentials like so:

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

Last, create a new file to write the code in. You can name it `text-to-speech-websocket.py` for Python or `text-to-speech-websocket.ts` for Typescript.

## Initiate the websocket connection

Pick a voice from the voice library and a text-to-speech model; Then initiate a websocket connection to the text-to-speech API.

<CodeGroup>
  ```python text-to-speech-websocket.py (Python)
  import os
  from dotenv import load_dotenv
  import websockets

  # Load the API key from the .env file
  load_dotenv()
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")

  voice_id = 'kmSVBPu7loj4ayNinwWM'
  model_id = 'eleven_turbo_v2'

  async def text_to_speech_ws_streaming(voice_id, model_id):
      uri = f"wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id={model_id}"

      async with websockets.connect(uri) as websocket:
         ...
  ```

  ```typescript text-to-speech-websocket.ts (Typescript)
  import * as dotenv from "dotenv";
  // @ts-ignore
  import WebSocket from "ws";

  // Load the API key from the .env file
  dotenv.config();
  const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

  const voiceId = "Xb7hH8MSUJpSbSDYk0k2";
  const model = "eleven_turbo_v2";
  const uri = `wss://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream-input?model_id=${model}`;
  const websocket = new WebSocket(uri, {
    headers: { "xi-api-key": `${ELEVENLABS_API_KEY}` },
  });
  ```
</CodeGroup>

For TypeScript, create a write stream ahead for saving the audio into mp3 which can be passed to the websocket listener.

```typescript text-to-speech-websocket.ts (Typescript)
import * as fs from "node:fs";

const outputDir = "./output";
try {
  fs.accessSync(outputDir, fs.constants.R_OK | fs.constants.W_OK);
} catch (err) {
  fs.mkdirSync(outputDir);
}
const writeStream = fs.createWriteStream(outputDir + "/test.mp3", {
  flags: "a",
});
```

## Send the input text

Once the websocket connection is open, set up voice settings first. Next, send the text message to the API.

<CodeGroup>
  ```python text-to-speech-websocket.py (Python)
  async def text_to_speech_ws_streaming(voice_id, model_id):
      async with websockets.connect(uri) as websocket:
          await websocket.send(json.dumps({
              "text": " ",
              "voice_settings": {"stability": 0.5, "similarity_boost": 0.8, "use_speaker_boost": False},
              "generation_config": {
                  "chunk_length_schedule": [120, 160, 250, 290]
              },
              "xi_api_key": ELEVENLABS_API_KEY,
          }))

          text = "The twilight sun cast its warm golden hues upon the vast rolling fields, saturating the landscape with an ethereal glow. Silently, the meandering brook continued its ceaseless journey, whispering secrets only the trees seemed privy to."
          await websocket.send(json.dumps({"text": text}))

          // Send empty string to indicate the end of the text sequence which will close the websocket connection
          await websocket.send(json.dumps({"text": ""}))
  ```

  ```typescript text-to-speech-websocket.ts (Typescript)
  const text =
    "The twilight sun cast its warm golden hues upon the vast rolling fields, saturating the landscape with an ethereal glow. ";

  websocket.on("open", async () => {
    websocket.send(
      JSON.stringify({
        text: " ",
        voice_settings: {
          stability: 0.5,
          similarity_boost: 0.8,
          use_speaker_boost: false,
        },
        generation_config: { chunk_length_schedule: [120, 160, 250, 290] },
      })
    );

    websocket.send(JSON.stringify({ text: text }));

    // Send empty string to indicate the end of the text sequence which will close the websocket connection
    websocket.send(JSON.stringify({ text: "" }));
  });
  ```
</CodeGroup>

## Save the audio to file

Read the incoming message from the websocket connection and write the audio chunks to a local file.

<CodeGroup>
  ```python text-to-speech-websocket.py (Python)
  import asyncio

  async def write_to_local(audio_stream):
      """Write the audio encoded in base64 string to a local mp3 file."""

      with open(f'./output/test.mp3', "wb") as f:
          async for chunk in audio_stream:
              if chunk:
                  f.write(chunk)

  async def listen(websocket):
      """Listen to the websocket for audio data and stream it."""

      while True:
          try:
              message = await websocket.recv()
              data = json.loads(message)
              if data.get("audio"):
                  yield base64.b64decode(data["audio"])
              elif data.get('isFinal'):
                  break

          except websockets.exceptions.ConnectionClosed:
              print("Connection closed")
              break

  async def text_to_speech_ws_streaming(voice_id, model_id):
      async with websockets.connect(uri) as websocket:
            ...
            # Add listen task to submit the audio chunks to the write_to_local function
            listen_task = asyncio.create_task(write_to_local(listen(websocket)))

            await listen_task

  asyncio.run(text_to_speech_ws_streaming(voice_id, model_id))
  ```

  ```typescript text-to-speech-websocket.ts (Typescript)
  // Helper function to write the audio encoded in base64 string into local file
  function writeToLocal(base64str: any, writeStream: fs.WriteStream) {
    const audioBuffer: Buffer = Buffer.from(base64str, "base64");
    writeStream.write(audioBuffer, (err) => {
      if (err) {
        console.error("Error writing to file:", err);
      }
    });
  }

  // Listen to the incoming message from the websocket connection
  websocket.on("message", function incoming(event) {
    const data = JSON.parse(event.toString());
    if (data["audio"]) {
      writeToLocal(data["audio"], writeStream);
    }
  });

  // Close the writeStream when the websocket connection closes
  websocket.on("close", () => {
    writeStream.end();
  });
  ```
</CodeGroup>

## Run the script

You can run the script by executing the following command in your terminal. An mp3 audio file will be saved in the `output` directory.

<CodeGroup>
  `python Python python text-to-speech-websocket.py ` `typescript
    Typescript tsx text-to-speech-websocket.ts `
</CodeGroup>

## Understanding buffering

A key concept to understand when using websockets is buffering. The API only runs model generations when a certain amount of text above a threshold has been sent. This is to optimize the quality of the generated audio by maximising the amount of context available to the model while balancing latency.

For example, if the threshold is set to 120 characters and you send 'Hello, how are you?', the audio won't be generated immediately. This is because the sent message has only 19 characters which is below the threshold. However, if you keep sending text, the API will generate audio once the total text sent since the last generation has at least 120 characters.

In the case that you want force the immediate return of the audio, you can use `flush=true` to clear out the buffer and force generate any buffered text. This can be useful, for example, when you have reached the end of a document and want to generate audio for the final section.

In addition, closing the websocket will automatically force generate any buffered text.

## Best practice

*   We suggest using the default setting for `chunk_length_schedule` in `generation_config`. Avoid using `try_trigger_generation` as it is deprecated.
*   When developing a real-time conversational AI application, we advise using `flush=true` along with the text at the end of conversation turn to ensure timely audio generation.
*   If the default setting doesn't provide optimal latency for your use case, you can modify the `chunk_length_schedule`. However, be mindful that reducing latency through this adjustment may come at the expense of quality.

## Tips

*   The API maintains a internal buffer so that it only runs model generations when a certain amount of text above a threshold has been sent. For short texts with a character length smaller than the value set in `chunk_length_schedule`, you can use `flush=true` to clear out the buffer and force generate any buffered text.
*   The websocket connection will automatically close after 20 seconds of inactivity. To keep the connection open, you can send a single space character `" "`. Please note that this string must include a space, as sending a fully empty string, `""`, will close the websocket.
*   Send an empty string to close the websocket connection after sending the last text message.
*   You can use `alignment` to get the word-level timestamps for each word in the text. This can be useful for aligning the audio with the text in a video or for other applications that require precise timing.


# How to send an AI message through a phone call using Twilio and ElevenLabs in Node.js



In this guide, you’ll learn how to send an AI generated message through a phone call using Twilio and ElevenLabs. This process allows you to send high-quality voice messages directly to your callers.

## Create accounts with Twilio and ngrok

We’ll be using Twilio and ngrok for this guide, so go ahead and create accounts with them.

*   [twilio.com](https://www.twilio.com)
*   [ngrok.com](https://ngrok.com)

## Get the code

If you want to get started quickly, you can get the entire code for this guide on [GitHub](https://github.com/elevenlabs/elevenlabs-examples/tree/main/examples/twilio/call)

## Create the server with Express

### Initialize your project

Create a new folder for your project

```
mkdir elevenlabs-twilio
cd elevenlabs-twilio
npm init -y
```

### Install dependencies

```
npm install elevenlabs express express-ws twilio
```

### Install dev dependencies

```
npm i @types/node @types/express @types/express-ws @types/ws dotenv tsx typescript
```

### Create your files

```ts
// src/app.ts

import 'dotenv/config';
import express, { Response } from 'express';
import ExpressWs from 'express-ws';
import VoiceResponse from 'twilio/lib/twiml/VoiceResponse';
import { ElevenLabsClient } from 'elevenlabs';
import { type WebSocket } from 'ws';
import { Readable } from 'stream';

const app = ExpressWs(express()).app;
const PORT: number = parseInt(process.env.PORT || '5000');

const elevenlabs = new ElevenLabsClient();
const voiceId = '21m00Tcm4TlvDq8ikWAM';
const outputFormat = 'ulaw_8000';
const text = 'This is a test. You can now hang up. Thank you.';

function startApp() {
  app.post('/call/incoming', (_, res: Response) => {
    const twiml = new VoiceResponse();

    twiml.connect().stream({
      url: `wss://${process.env.SERVER_DOMAIN}/call/connection`,
    });

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  });

  app.ws('/call/connection', (ws: WebSocket) => {
    ws.on('message', async (data: string) => {
      const message: {
        event: string;
        start?: { streamSid: string; callSid: string };
      } = JSON.parse(data);

      if (message.event === 'start' && message.start) {
        const streamSid = message.start.streamSid;
        const response = await elevenlabs.textToSpeech.convert(voiceId, {
          model_id: 'eleven_turbo_v2_5',
          output_format: outputFormat,
          text,
        });

        const readableStream = Readable.from(response);
        const audioArrayBuffer = await streamToArrayBuffer(readableStream);

        ws.send(
          JSON.stringify({
            streamSid,
            event: 'media',
            media: {
              payload: Buffer.from(audioArrayBuffer as any).toString('base64'),
            },
          }),
        );
      }
    });

    ws.on('error', console.error);
  });

  app.listen(PORT, () => {
    console.log(`Local: http://localhost:${PORT}`);
    console.log(`Remote: https://${process.env.SERVER_DOMAIN}`);
  });
}

function streamToArrayBuffer(readableStream: Readable) {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];

    readableStream.on('data', (chunk) => {
      chunks.push(chunk);
    });

    readableStream.on('end', () => {
      resolve(Buffer.concat(chunks).buffer);
    });

    readableStream.on('error', reject);
  });
}

startApp();
```

```env
# .env
SERVER_DOMAIN=
ELEVENLABS_API_KEY=
```

## Understanding the code

### Handling the incoming call

When you call your number, Twilio makes a POST request to your endpoint at `/call/incoming`.
We then use twiml.connect to tell Twilio that we want to handle the call via our websocket by setting the url to our `/call/connection` endpoint.

```ts
function startApp() {
  app.post('/call/incoming', (_, res: Response) => {
    const twiml = new VoiceResponse();

    twiml.connect().stream({
      url: `wss://${process.env.SERVER_DOMAIN}/call/connection`,
    });

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  });
```

### Creating the text to speech

Here we listen for messages that Twilio sends to our websocket endpoint. When we receive a `start` message event, we generate audio using the ElevenLabs [TypeScript SDK](https://github.com/elevenlabs/elevenlabs-js).

```ts
  app.ws('/call/connection', (ws: WebSocket) => {
    ws.on('message', async (data: string) => {
      const message: {
        event: string;
        start?: { streamSid: string; callSid: string };
      } = JSON.parse(data);

      if (message.event === 'start' && message.start) {
        const streamSid = message.start.streamSid;
        const response = await elevenlabs.textToSpeech.convert(voiceId, {
          model_id: 'eleven_turbo_v2_5',
          output_format: outputFormat,
          text,
        });
```

### Sending the message

Upon receiving the audio back from ElevenLabs, we convert it to an array buffer and send the audio to Twilio via the websocket.

```ts
const readableStream = Readable.from(response);
const audioArrayBuffer = await streamToArrayBuffer(readableStream);

ws.send(
  JSON.stringify({
    streamSid,
    event: 'media',
    media: {
      payload: Buffer.from(audioArrayBuffer as any).toString('base64'),
    },
  }),
);
```

## Point ngrok to your application

Twilio requires a publicly accessible URL. We’ll use ngrok to forward the local port of our application and expose it as a public URL.

Run the following command in your terminal:

```
ngrok http 5000
```

Copy the ngrok domain (without https\://) to use in your environment variables.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/ngrok.png" />

## Update your environment variables

Update the `.env` file with your ngrok domain and ElevenLabs API key.

```
# .env
SERVER_DOMAIN=*******.ngrok.app
ELEVENLABS_API_KEY=*************************
```

## Start the application

Run the following command to start the app:

```
npm run dev
```

## Set up Twilio

Follow Twilio’s guides to create a new number. Once you’ve created your number, navigate to the “Configure” tab in Phone Numbers -> Manage -> Active numbers

In the “A call comes in” section, enter the full URL to your application (make sure to add the`/call/incoming` path):

E.g. https\://\*\*\*\*\*\*\*ngrok.app/call/incoming

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/twilio.png" />

## Make a phone call

Make a call to your number. You should hear a message using the ElevenLabs voice.

## Tips for deploying to production

When running the application in production, make sure to set the `SERVER_DOMAIN` environment variable to that of your server. Be sure to also update the URL in Twilio to point to your production server.

## Conclusion

You should now have a basic understanding of integrating Twilio with ElevenLabs voices. If you have any further questions, or suggestions on how to improve this blog post, please feel free to select the “Suggest edits” or “Raise issue” button below.


# Models



ElevenLabs is the leading provider of AI-powered audio technology. This guide helps developers choose the right model for their use case.

<CardGroup cols={2}>
  <Card title="Eleven Multilingual v2">
    Our most advanced speech synthesis model.

    <br />

    <Icon icon="check" iconType="solid" /> Highest realism, emotional range

    <Icon icon="check" iconType="solid" /> Best for voiceovers, audiobooks, content
  </Card>

  <Card title="Eleven Turbo v2.5">
    High quality, low latency Turbo model

    <br />

    <Icon icon="check" iconType="solid" /> Ultra-low latency (\~300ms)

    <Icon icon="check" iconType="solid" /> Ideal for real-time, multi-language AI
  </Card>
</CardGroup>

# Flagship Models

<Success>
  These models are maintained for backward compatibility but are not recommended for new projects.
</Success>

| Model ID                     | Description                                | Max Characters | Languages    | Best For                                                    |
| ---------------------------- | ------------------------------------------ | -------------- | ------------ | ----------------------------------------------------------- |
| `eleven_multilingual_v2`     | Most life-like, emotionally rich model     | 10,000         | 29 languages | Voice overs, audiobooks, content creation                   |
| `eleven_turbo_v2_5`          | High quality, low-latency model            | 40,000         | 32 languages | Developer use cases requiring speed and multiple languages  |
| `eleven_turbo_v2`            | High quality, low-latency model            | 30,000         | English only | Developer use cases requiring speed (English only)          |
| `eleven_english_sts_v2`      | State-of-the-art speech-to-speech          | 5,000          | English only | Maximum control over content and prosody                    |
| `eleven_multilingual_sts_v2` | Cutting-edge multilingual speech-to-speech | 10,000         | 29 languages | Advanced multilingual speech synthesis with prosody control |

<Accordion title="Older Models">
  <Warning>
    These models are maintained for backward compatibility but are not recommended for new projects.
  </Warning>

  | Model ID                 | Description                | Max Characters | Languages    | Best For                                    |
  | ------------------------ | -------------------------- | -------------- | ------------ | ------------------------------------------- |
  | `eleven_monolingual_v1`  | First generation TTS model | 10,000         | English only | Legacy model (outclassed by newer versions) |
  | `eleven_multilingual_v1` | First multilingual model   | 10,000         | 9 languages  | Legacy model (outclassed by newer versions) |
</Accordion>

# Model Selection Guide

Choose your model based on these primary considerations:

<Steps>
  <Step title="Latency Requirements">
    • *Quality over Speed?* Use Standard Multilingual models <br /> • *Need
    real-time?* Use Turbo models
  </Step>

  <Step title="Language Support">
    • *English only?* → Consider `eleven_turbo_v2` <br /> • *Multiple
    languages?* → Use `eleven_multilingual_v2` or `eleven_turbo_v2_5`
  </Step>

  <Step title="Use Case">
    • *Content Creation* → `eleven_multilingual_v2` <br /> • *Conversational AI*
    → `eleven_turbo_v2_5` <br /> • *Professional Voice Clones* → Either model{" "}
    <br /> • *Speech to Speech?* → `eleven_english_sts_v2` or
    `eleven_multilingual_sts_v2` family
  </Step>
</Steps>

<Note>
  For detailed language support information and troubleshooting guidance, refer
  to our [help documentation](https://help.elevenlabs.io).
</Note>


# Quickstart

Start generating your first text-to-speech using Python and ElevenLabs API

## Accessing the API

With all plans, including the free plan, you gain full access to the ElevenLabs API, enabling you to generate speech programmatically across our entire range of features.

<Info>
  Both the API and the website draw from a shared quota pool. Usage on either platform will affect your total available usage quota.
</Info>

## Authentication

All requests to the ElevenLabs API must include an `xi-api-key` header with your API key. If using Client SDKs, this header is set automatically; otherwise, include it manually in each request. API keys can be restricted to specific routes, disabled or deleted as needed.

To get your API key, [create an account](https://elevenlabs.io/sign-up), log in, and click on **"API Keys"** in the bottom left corner of the console.

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/api-reference/images/api_key.png" />
</Frame>

<Warning>
  Your API key is a secret. Do not share it or expose it in client-side code (browsers, apps). Load it securely from an environment variable or key management service on your backend server.
</Warning>

## Fetching the voice\_id

The [Text-To-Speech](https://elevenlabs.io/docs/api-reference/text-to-speech) (TTS) endpoint transforms text into speech in a given voice. The input consists of text, voice, and voice settings with an option to specify model.

Before we can generate anything, we need to get the `voice_id` for the voice we want to use.

The easiest way to get the `voice_id` is via the website. You can find the article on how to do that [here](https://help.elevenlabs.io/hc/en-us/articles/14599760033937-How-do-I-find-my-voice's-ID-of-my-voices-via-the-website-and-through-the-API-).

A better approach, especially when dealing with the API, is to retrieve the voices accessible to your account using the `GET /v1/voices` endpoint. If you do not receive the expected voices, you will either encounter an error or just see the pre-made voices, which is most likely indicating that you are not passing your API key correctly.

You can find more information in the [Get Voices](https://elevenlabs.io/docs/api-reference/get-voices) endpoint documentation. This endpoint is crucial if your application requires any form of flexibility in the voices you want to use via the API, as it provides information about each voice, including the `voice_id` for each of them. This `voice_id` is necessary when querying the TTS endpoint.

The API offers a wide range of capabilities, such as adding new voices, but we won't discuss that here. To gain a better understanding of how to do that, you will need to read through the documentation.

You can use the Python code below to print a list of the voices in your account, along with their names and associated voice\_ids, which will be required to use the voices via the API. Simply using the name won't be sufficient.

```python
# The 'requests' and 'json' libraries are imported.
# 'requests' is used to send HTTP requests, while 'json' is used for parsing the JSON data that we receive from the API.
import requests
import json

# An API key is defined here. You'd normally get this from the service you're accessing. It's a form of authentication.
XI_API_KEY = "<xi-api-key>"

# This is the URL for the API endpoint we'll be making a GET request to.
url = "https://api.elevenlabs.io/v1/voices"

# Here, headers for the HTTP request are being set up.
# Headers provide metadata about the request. In this case, we're specifying the content type and including our API key for authentication.
headers = {
  "Accept": "application/json",
  "xi-api-key": XI_API_KEY,
  "Content-Type": "application/json"
}

# A GET request is sent to the API endpoint. The URL and the headers are passed into the request.
response = requests.get(url, headers=headers)

# The JSON response from the API is parsed using the built-in .json() method from the 'requests' library.
# This transforms the JSON data into a Python dictionary for further processing.
data = response.json()

# A loop is created to iterate over each 'voice' in the 'voices' list from the parsed data.
# The 'voices' list consists of dictionaries, each representing a unique voice provided by the API.
for voice in data['voices']:
  # For each 'voice', the 'name' and 'voice_id' are printed out.
  # These keys in the voice dictionary contain values that provide information about the specific voice.
  print(f"{voice['name']}; {voice['voice_id']}")
```

## Text-to-speech

Once you have you've gotten the `voice_id` from the voices endpoint, you are ready to query the [Text-to-speech](https://elevenlabs.io/docs/api-reference/text-to-speech) endpoint.

First, you need to decide whether you want to use the streaming response or not. In general, we recommend streaming unless your client doesn't support it. You can find more information about the [streaming](https://elevenlabs.io/docs/api-reference/streaming) endpoint in our documentation.

Second, you need to choose your voice settings. We recommend using the default voice settings before experimenting with the expressivity and similarity settings. You can find more information about the [settings](https://elevenlabs.io/docs/speech-synthesis/voice-settings) in our documentation.

After generating something, we store each audio you generate together with other metadata in your personal history. You can retrieve all your history items via the `/v1/history` endpoint. We also provide endpoints for retrieving audio, deletion, and download of history items. You can find more information about how to use the [history](https://elevenlabs.io/docs/api-reference/get-generated-items) endpoint in our documentation. The only thing that is not saved is websocket streaming queries to save latency.

In the basic Python example below, we send a request to the text-to-speech endpoint and receive a stream of audio bytes in return. All you need to do is set your XI API Key first and try it out! If you cannot find it, please follow this article [here](https://help.elevenlabs.io/hc/en-us/articles/14599447207697-How-to-authorize-yourself-using-your-xi-api-key-).

You will need to replace the constants by inserting your `<xi-api-key>`, setting the correct `<voice-id>`, and entering the `<text>` you want the AI to convert to speech. You can change the settings `stability` and `similarity_boost` if you want, but they are set to good default values.

Of course, the code below is only to showcase the very bare minimum to get the system up and running, and you can then use more advanced code to create a nice GUI with sliders for the variables, a list for the voices, and anything else that you want to add.

```python
# Import necessary libraries
import requests  # Used for making HTTP requests
import json  # Used for working with JSON data

# Define constants for the script
CHUNK_SIZE = 1024  # Size of chunks to read/write at a time
XI_API_KEY = "<xi-api-key>"  # Your API key for authentication
VOICE_ID = "<voice-id>"  # ID of the voice model to use
TEXT_TO_SPEAK = "<text>"  # Text you want to convert to speech
OUTPUT_PATH = "output.mp3"  # Path to save the output audio file

# Construct the URL for the Text-to-Speech API request
tts_url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream"

# Set up headers for the API request, including the API key for authentication
headers = {
    "Accept": "application/json",
    "xi-api-key": XI_API_KEY
}

# Set up the data payload for the API request, including the text and voice settings
data = {
    "text": TEXT_TO_SPEAK,
    "model_id": "eleven_multilingual_v2",
    "voice_settings": {
        "stability": 0.5,
        "similarity_boost": 0.8,
        "style": 0.0,
        "use_speaker_boost": True
    }
}

# Make the POST request to the TTS API with headers and data, enabling streaming response
response = requests.post(tts_url, headers=headers, json=data, stream=True)

# Check if the request was successful
if response.ok:
    # Open the output file in write-binary mode
    with open(OUTPUT_PATH, "wb") as f:
        # Read the response in chunks and write to the file
        for chunk in response.iter_content(chunk_size=CHUNK_SIZE):
            f.write(chunk)
    # Inform the user of success
    print("Audio stream saved successfully.")
else:
    # Print the error message if the request was not successful
    print(response.text)
```

## Speech-to-Speech

Generating speech-to-speech involves a similar process to text-to-speech, but with some adjustments in the API parameters. Instead of providing text when calling the API, you provide the path to an audio file that you would like to convert from one voice to another. Here's a modified version of your code to illustrate how to generate speech-to-speech using the given API:

```python
# Import necessary libraries
import requests  # Used for making HTTP requests
import json  # Used for working with JSON data

# Define constants for the script
CHUNK_SIZE = 1024  # Size of chunks to read/write at a time
XI_API_KEY = "<xi-api-key>"  # Your API key for authentication
VOICE_ID = "<voice-id>"  # ID of the voice model to use
AUDIO_FILE_PATH = "<path>"  # Path to the input audio file
OUTPUT_PATH = "output.mp3"  # Path to save the output audio file

# Construct the URL for the Speech-to-Speech API request
sts_url = f"https://api.elevenlabs.io/v1/speech-to-speech/{VOICE_ID}/stream"

# Set up headers for the API request, including the API key for authentication
headers = {
    "Accept": "application/json",
    "xi-api-key": XI_API_KEY
}

# Set up the data payload for the API request, including model ID and voice settings
# Note: voice settings are converted to a JSON string
data = {
    "model_id": "eleven_english_sts_v2",
    "voice_settings": json.dumps({
        "stability": 0.5,
        "similarity_boost": 0.8,
        "style": 0.0,
        "use_speaker_boost": True
    })
}

# Set up the files to send with the request, including the input audio file
files = {
    "audio": open(AUDIO_FILE_PATH, "rb")
}

# Make the POST request to the STS API with headers, data, and files, enabling streaming response
response = requests.post(sts_url, headers=headers, data=data, files=files, stream=True)

# Check if the request was successful
if response.ok:
    # Open the output file in write-binary mode
    with open(OUTPUT_PATH, "wb") as f:
        # Read the response in chunks and write to the file
        for chunk in response.iter_content(chunk_size=CHUNK_SIZE):
            f.write(chunk)
    # Inform the user of success
    print("Audio stream saved successfully.")
else:
    # Print the error message if the request was not successful
    print(response.text)
```

This code takes an input audio file (`<path>` should be something like `C:/User/Documents/input.mp3`), sends a request to the speech-to-speech endpoint, and receives a stream of audio bytes in return. It then saves the streamed audio to the specified output path (`output.mp3` if no specific path is specified, it will be saved in the same folder as the .py code file).

Make sure to replace placeholders like `<xi-api-key>` and `<voice-id>` with your actual API key and voice ID respectively. Additionally, adjust paths and settings as needed.


# Reducing Latency

Seven methods for reducing streaming latency, in order of highest to lowest effectiveness:

***

## 1. Use the [Turbo v2.5 model](https://elevenlabs.io/api)

Our cutting-edge Eleven Turbo v2.5 is ideally suited for tasks demanding extremely low latency. The new turbo model\_id is `eleven_turbo_v2_5`.

## 2. Use the [streaming API](/api-reference/streaming)

ElevenLabs provides three text-to-speech endpoints:

1.  A **regular** text-to-speech endpoint
2.  A **streaming** text-to-speech endpoint
3.  A **websockets** text-to-speech endpoint

The regular endpoint renders the audio file before returning it in the response. The streaming endpoint streams back the audio as it is being generated, resulting in much lower response time from request to first byte of audio received. For applications that require low latency, the streaming endpoint is therefore recommended.

## 3. Use the [input streaming Websocket](/api-reference/websockets)

For applications where the text prompts can be streamed to the text-to-speech endpoints (such as LLM output), this allows for prompts to be fed to the endpoint while the speech is being generated. You can also configure the streaming chunk size when using the websocket, with smaller chunks generally rendering faster. As such, we recommend sending content word by word, our model and tooling leverages context to ensure that sentence structure and more are persisted to the generated audio even if we only receive a word at a time.

## 4. Update to the [Enterprise plan](https://elevenlabs.io/enterprise)

Enterprise customers receive top priority in the rendering queue, which ensures that they always experience the lowest possible latency, regardless of model usage load.

## 5. Use Default Voices, Synthetic Voices, & IVCs rather than PVCs

Based on our testing, we've observed that default voices (formerly called 'premade' voices), synthetic voices, and Instant Voice Clones tend to have lower latency compared to Professional Voice Clones. A Professional Voice Clone allows for a much more accurate clone of the original samples, albeit with a slight increase in latency at present. Unfortunately, it is a slight tradeoff and we're currently working on optimizing the latency of the Professional Voice Clones for Turbo v2.5.

## 6. Reuse HTTPS Sessions When Streaming

When streaming through the websocket, reusing an established SSL/TLS session helps reduce latency by skipping the handshake process. This improves latency for all requests after the session’s first.

### 6a. Limit the Number of Websocket Connection Closures

Similarly, for websockets we leverage the WSS protocol and so an SSL/TLS handshake takes place at the beginning of a connection, which adds overhead. As such, we recommend to limit the number of times a connection is closed and reopened to the extent possible.

## 7. Leverage Servers Closer to the US

Today, our APIs are served from the US, and as such users may experience latency from increased network routing when communicating with these APIs outside of the United States.


# Specifying Server Location

How to control the server location for your requests

When using ElevenLabs API you have two options for selecting the server location:

## Using the closest servers (default)

Requests to `api.elevenlabs.io` are automatically routed to the closest available server location which minimizes network latency. We recommend using this option for most users.

## Manually specifying the server location

If needed, you can select a specific server location for your requests.

#### When using the client library

Provide the `environment` option when constructing the client:

<CodeGroup>
  ```python Python
  import elevenlabs

  client = elevenlabs.ElevenLabs(
      api_key="YOUR_API_KEY",
      # Use the US servers only.
      environment=elevenlabs.ElevenLabsEnvironment.PRODUCTION_US
  )
  ```

  ```typescript TypeScript
  import { ElevenLabsClient, ElevenLabsEnvironment } from "elevenlabs";

  const client = new ElevenLabsClient({
    apiKey: "YOUR_API_KEY",
    // Use the US servers only.
    environment: ElevenLabsEnvironment.ProductionUs,
  });
  ```
</CodeGroup>

#### When using direct API calls

Replace the `api.elevenlabs.io` hostname in your requests with one of the following values:

*   `api.us.elevenlabs.io`: Uses servers located in the US.


# How to set up an ElevenLabs audio player for your articles in React (Next.js, Vite)



Here's a guide on how you can use [Audio Native](/product/audio-native/overview) in your React projects. I'll be using Next.js, but this process will work for any React project.

Audio Native is an embedded audio player designed to vocalize the content of web pages through ElevenLabs' Text to Speech technology, as shown below.

<iframe width="100%" height="90" frameBorder="no" scrolling="no" seamless src="https://elevenlabs.io/player/index.html?publicUserId=4d7f6f3d38ae27705f5b516ffd3e413a09baa48667073d385e5be1be773eaf69&projectId=gLj1spzTwuTgKuOtyfnX&small=true&textColor=rgba(0,%200,%200,%201)&backgroundColor=rgba(255,%20255,%20255,%201)" />

## Activate Audio Native within ElevenLabs

First you need to make sure that you activate Audio Native in your ElevenLabs account. After signing in, visit: [https://elevenlabs.io/audio-native](https://elevenlabs.io/audio-native)

Select “Click to start with Audio Native” to begin the setup. Don't worry about completing all the sections in the setup, as we just need to get to the code snippet at the end.

Once you've gone through the setup, you should see a page like this:

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an-1.png" />

This is the code snippet that is used to embed Audio Native on a normal website such as Wordpress, Ghost, or Webflow. However, you can't use this snippet directly in React.

## Creating the Audio Native React component

Here's a handy component that you can reuse across your project:

<AccordionGroup>
  <Accordion title="The React component - ElevenLabsAudioNative.tsx" defaultOpen>
    ```tsx
    // ElevenLabsAudioNative.tsx

    'use client';
    import { useEffect } from 'react';

    export type ElevenLabsProps = {
        publicUserId: string;
        textColorRgba?: string;
        backgroundColorRgba?: string;
        size?: 'small' | 'large';
        children?: React.ReactNode;
    };

    export const ElevenLabsAudioNative = ({
        publicUserId,
        size,
        textColorRgba,
        backgroundColorRgba,
        children,
    }: ElevenLabsProps) => {
        useEffect(() => {
            const script = document.createElement('script');

            script.src = 'https://elevenlabs.io/player/audioNativeHelper.js';
            script.async = true;
            document.body.appendChild(script);

            return () => {
            document.body.removeChild(script);
            };
        }, []);

        return (
            <div
            id="elevenlabs-audionative-widget"
            data-height={size === 'small' ? '90' : '120'}
            data-width="100%"
            data-frameborder="no"
            data-scrolling="no"
            data-publicuserid={publicUserId}
            data-playerurl="https://elevenlabs.io/player/index.html"
            data-small={size === 'small' ? 'True' : 'False'}
            data-textcolor={textColorRgba ?? 'rgba(0, 0, 0, 1.0)'}
            data-backgroundcolor={backgroundColorRgba ?? 'rgba(255, 255, 255, 1.0)'}
            >
            {children ? children : 'Elevenlabs AudioNative Player'}
            </div>
        );
    };

    export default ElevenLabsAudioNative;
    ```

    Here's a link to the component on GitHub - [ElevenLabsAudioNative.tsx](https://github.com/elevenlabs/elevenlabs-examples/blob/main/examples/audio-native/react/ElevenLabsAudioNative.tsx)
  </Accordion>

  <Accordion title="Code Walkthrough">
    ```tsx
    'use client';
    import { useEffect } from 'react';
    ```

    We add the `use client` directive at the top of the file. This is mainly for Next.js, as we are using `useEffect` which can only be used in client side components.

    ```tsx
    export type ElevenLabsProps = {
      publicUserId: string;
      textColorRgba?: string;
      backgroundColorRgba?: string;
      size?: "small" | "large";
      children?: React.ReactNode;
    };
    ```

    Helpful type for the props so that we can specify the public user ID (described later), customize colors and size, and set a default content if the player hasn't loaded. You can ignore this if you're not using TypeScript (TypeScript is great however!).

    ```tsx
    useEffect(() => {
      const script = document.createElement("script");

      script.src = "https://elevenlabs.io/player/audioNativeHelper.js";
      script.async = true;
      document.body.appendChild(script);

      return () => {
        document.body.removeChild(script);
      };
    }, []);
    ```

    In order to load the Audio Native player, we use the useEffect hook to dynamically append a script tag to the body and set the source to the URL of the Audio Native helper script.
    When the component is dismounted, we make sure to remove the script tag from the body. This ensures it doesn't get loaded twice if we remount the component.

    ```tsx
    <div
      id="elevenlabs-audionative-widget"
      data-height={size === "small" ? "90" : "120"}
      data-width="100%"
      data-frameborder="no"
      data-scrolling="no"
      data-publicuserid={publicUserId}
      data-playerurl="https://elevenlabs.io/player/index.html"
      data-small={size === "small" ? "True" : "False"}
      data-textcolor={textColorRgba ?? "rgba(0, 0, 0, 1.0)"}
      data-backgroundcolor={backgroundColorRgba ?? "rgba(255, 255, 255, 1.0)"}
    >
      {children ? children : "Elevenlabs AudioNative Player"}
    </div>
    ```

    Here is our main div element which will be where our Audio Native player will be placed. The children of the component can be used to show content before the player has been loaded (e.g. Loading audio player…).
  </Accordion>

  <Accordion title="Why can't I just use the snippet directly in React?">
    React components are rendered and managed entirely in JavaScript, and their rendering lifecycle is controlled by React's virtual DOM. When you try to include a script tag directly within a React component's JSX, it doesn't behave as it would when included directly in an HTML file. React's virtual DOM does not execute script tags inserted into the DOM as part of component rendering. This is a security feature to prevent unintended or malicious code execution.

    This is why, if we were to just paste the Audio Native code snippet into our React application, it would not work.
  </Accordion>
</AccordionGroup>

## Get the public user ID from the Audio Native snippet

Before you can use this component, you'll need to retrieve your public user ID from the code snippet. Go back to [https://elevenlabs.io/audio-native](https://elevenlabs.io/audio-native), and in the code snippet, copy the property called `publicuserid`.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an-2.png" />

This public user ID is used to identify your Audio Native project.

## Use the Audio Native component

Now that you have the public user ID, you can use the component on your page. Simply import it, then pass it the public user ID from the previous step.

```tsx
import { ElevenLabsAudioNative } from "./path/to/ElevenLabsAudioNative";

export default function Page() {
  return (
    <div>
      <h1>Your Blog Post Title</h1>

      <ElevenLabsAudioNative publicUserId="<your-public-user-id>" />

      <p>Your blog post...</p>
    </div>
  );
}
```

### Preview

Start your development server, if you haven't already, and view the page. You should see something similar to the following, stating that the URL is not allowed. (If you don't see anything, please see the Troubleshooting section below to perform a hard refresh)

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_url_not_allowed.png" />

### Troubleshooting

If you don't see the Audio Native player, try doing a hard refresh. This can sometimes be an issue because of the development server not properly reloading the script.

In Chrome it's: (⌘ or Ctrl) + Shift + R

### Why am I seeing “URL not allowed”?

Here's what's happening behind the scenes. Remember that script we loaded in the useEffect hook? This script is trying to scrape the content from your page to get all the text and convert it to audio. However, it can't load your page because it's on `localhost`. Audio Native can only process pages that are publicly accessible on the internet.

## Local testing with ngrok

This is where a service such as ngrok can help us. ngrok is a way to get your site on localhost to map to a public URL on the internet. They have a free tier, so visit their website [https://ngrok.com](https://ngrok.com), create an account and install it.

Here's their getting started guide - [https://ngrok.com/docs/getting-started](https://ngrok.com/docs/getting-started)

Once you have it installed, you can use a command similar to the one below to point your local React project to a public URL with ngrok. I'm running Next.js locally on port `3000`, so here's the command I run. Your details may vary.

```
ngrok http http://localhost:3000
```

Running this command will give you a URL that you can use in the next step.

### Update the allowed URLs to include the ngrok URL

Go to the Audio Native section:
[https://elevenlabs.io/audio-native](https://elevenlabs.io/audio-native)

Select the “My Websites” tab.

Enter the ngrok URL (from the previous step) in the “Allowed URLs” section.

This ensures that your player can only show on websites that you specify. This is very important, as someone else may otherwise be able to use your public user ID on their website.

Now visit your ngrok URL, you should see Audio Native processing your content. In the background, we are creating a project in your ElevenLabs account just for your page. This project contains the text from your page and converts it to audio.

View the newly created project here:
[https://elevenlabs.io/app/projects](https://elevenlabs.io/app/projects)

## Deploy to production

Make sure to also add the URL of your website to the allowed URLs once you've deployed your React app and you're ready to push to production.

We only used ngrok for local development, it's not needed for public facing URLs as ElevenLabs will directly grab the content from the website.

## Updating audio content

When updating the content on a page, you may notice that the audio from the Audio Native player won't update automatically.

In order to update the audio you'll have to go to the project in ElevenLabs and update the content from there manually. [https://elevenlabs.io/app/projects](https://elevenlabs.io/app/projects)

## Conclusion

Now that you have Audio Native working in your React project, go ahead and add the component to more pages on your website to begin converting content into high quality audio for your visitors.


# How to set up an ElevenLabs audio player for your articles in Framer



Before adding Audio Native to Framer, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to Framer. Go to Site Settings in Extract the \<script> tag from the ElevenLabs Embed Code and add it to your Framer Site Settings in the field: End of \<body> tag.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/framer_an_1.png" />

Now on your Framer blog page, add an Embed Element from Utilities.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/framer_an_2.png" />

In the config for the Embed Element, switch the type to HTML and the \<div> snippet from the ElevenLabs Embed Code.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/framer_an_3.png" />

Publish your changes and after a few minutes, the embedded audio player will appear and you can click play to hear the AI-generated audio blog.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/framer_an_4.png" />

Follow these steps for any Framer blog posts that you wish to turn into audio articles.


# How to set up an ElevenLabs audio player for your articles in Ghost



Before adding Audio Native to Ghost, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to your Ghost blog, sign in, and open the blog post you wish to narrate in the editor.

Next, add a line near the top of your blog post (above or below the main image is usually best). Click the “+” symbol on the left side and select “HTML” from the menu.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/ghost_an_1.png" />

Paste your Audio Native Embed code into the HTML box, as shown below, and press enter or click away.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/ghost_an_2.png" />

Click the “Update” button in the top right corner of the editor, which should now be highlighted in green text.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/ghost_an_3.png" />

Now, navigate to the live version of the blog post you just updated. You should see a message to let you know that the Audio Native project is being created. This means the text in your blog post is being converted to an audio article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/ghost_an_4.png" />

After a few minutes, the embedded audio player will appear and you can click play to hear the AI-generated audio blog.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/ghost_an_5.png" />

Follow these steps for any Ghost blog posts that you wish to turn into audio articles.


# Overview



## Embed ElevenLabs on any web page

<div id="elevenlabs-audionative-widget" data-height="90" data-width="100%" data-frameBorder="no" data-scrolling="no" data-publicUserId="8cb6f91dbb1d1b891d2cde8e21c96378281280fd9dac76faac4c7502f022075a" data-playerUrl="https://elevenlabs.io/player/index.html" data-small="True" data-textColor="rgba(0, 0, 0, 1.0)" data-backgroundColor="rgba(255, 255, 255, 1.0)">Loading the <a href="https://elevenlabs.io/text-to-speech" target="_blank" rel="noopener">Elevenlabs Text to Speech</a> AudioNative Player...</div>

<script src="https://elevenlabs.io/player/audioNativeHelper.js" />

Audio Native is an embedded audio player that automatically voices content of a web page using ElevenLab’s text-to-speech service. It can also be used to embed pre-generated content from a project into a web page. All it takes to deploy on your site is a brief snippet of html. In addition, Audio Native comes with built-in metrics so you can track audience engagement through a listener dashboard.

## Set up

Before creating and deploying Audio Native players, you’ll need to go through a few steps to configure Audio Native on your account.

It’s best not to skip any of these steps in order to understand how Audio Native works and prevent potential misuse of the service. Don’t worry about getting everything right the first time you configure Audio Native, you can always change the settings later!

1.  Navigate to Audio Native
    *   Go to Audio Native > Settings
    *   Or by directly navigating to [https://elevenlabs.io/app/audio-native/settings](https://elevenlabs.io/app/audio-native/settings)
2.  Configure whitelisted sites - these are the list of website domains that will be permitted to play your content. Your Audio Native players will only work on sites that begin with the domains that you specify in this list.
    *   Click on Add URL
    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_url_allowlist_empty_state.png" />
    *   If "elevenlabs.io/" is whitelisted, then the Audio Native player will work on any site on the elevenlabs website.
    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_url_elevenlabs.png" />
    *   However if we want to restrict it to just the blog page, then we can specify that in the whitelist by listing "elevenlabs.io/blog" instead. In this case, the Audio Native player will only work on any of the blog pages, and not other elevenlabs.io sites.
    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_url_elevenlabs_blog.png" />
    *   If you try to embed audio native on pages that don't follow that path, you will see the player briefly appear and then disappear, or you may see this message:
        <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_url_not_allowed.png" />You can resolve this by checking that the URL for the page is added to your URL list correctly.
3.  Configure your Audio Native player’s appearance and default settings.
    *   Click "Player" or directly navigate to [https://elevenlabs.io/app/audionative/settings/player](https://elevenlabs.io/app/audionative/settings/player)
    *   Select a default voice. This is the voice that will be used if you are using Audio Native to automatically convert content from the page it’s embedded in. If you use Audio Native to play content already generated in a Project, it will keep the voice used in the Project.
    *   You'll get an alert of your selected voice model is not optimized for the voice you've chosen.
    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_voice_wrong_model.png" />
    *   Customize your player's background and text color. This is how it will be displayed on your website.
    *   Set a fallback Title and Author to display on your player.
    *   Optionally add a [pronunciation dictionary](https://elevenlabs.io/docs/projects/overview#pronunciation-dictionaries) to specify the pronunciation of words unique to your brand.
    *   By default, our embedded player will create a voice over of all of the text content on your page. You can customize the content we target with CSS selectors.
4.  Now that you've finished customizing your player, head back to the General tab and grab your embed code.
    *   You'll use this code snippet to embed Audio Native into the html of any (whitelisted) site you’d like to have voiced by ElevenLabs.
    <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/an_embed_code.png" />

## Deploying Audio Native

To see an example implementation check out our [dubbing studio blog post](https://elevenlabs.io/blog/introducing-dubbing-studio/).

The embedded player automatically collects listening metrics, retention and more. Plus, it can be readily extended to any article through simple copy-pasting.

There are three ways to deploy your Audio Native Player

### Method 1: Embed and automatically voice the site

Take the code that you generated during Audio Native set up and embed it into your website. The next time the site is opened, Audio Native will:

1.  Create a new Project (make sure you have Project slots available otherwise it will throw an error)
2.  Grab the webpage’s contents and put it into the newly created Project
3.  Convert the Project into audio and deliver it to the Audio Native player

Once this process is complete, you can edit the Audio by editing the resulting Project. To update the audio after saving your edits to the project, select versions and publish the new version.

Here are specific implementation guides for some of the top CMS platforms:

*   Audio Native with [Webflow](https://elevenlabs.io/docs/audio-native/webflow)
*   Audio Native with [Framer](https://elevenlabs.io/docs/audio-native/framer)
*   Audio Native with [Squarespace](https://elevenlabs.io/docs/audio-native/squarespace)
*   Audio Native with [Wordpress](https://elevenlabs.io/docs/audio-native/wordpress)
*   Audio Native with [Ghost](https://elevenlabs.io/docs/audio-native/ghost)
*   Audio Native with [React Native](https://elevenlabs.io/docs/audio-native/audio-native-react)

***

### Method 2: Embed audio from an existing project

<video controls className="w-full" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/videos/Manual_Audio_Native.mp4" />

If you already have a Project converted to voice audio and would like to embed that voice audio in an Audio Native player, simply select share on the Project and use the generated html snippet to embed the voice audio on any whitelisted site.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/an8.png" />

***

### Method 3: Embed audio from content using our API

You can use our API to programmatically create an Audio Native player for your existing content.

Using [this API method](https://elevenlabs.io/docs/api-reference/creates-audionative-enabled-project) you can submit your content as either a .html or .txt file and we will return an embeddable html code for an Audio Native player which can be inserted into your website or blog. Our Audio Native HTML embed code follows a standardised format, with a unique identifier for the uploaded content.

In the background when this api is called it will automatically convert your content into an ElevenLabs Project, optionally convert the project into audio straight away, and then enable sharing on this project audio using the returned Audio Native player.

Future edits to the content can be done by calling this method again with the new content, or from within the Projects UI.

## Updating Audio Native player for existing projects

When you make changes to the default player, this does not apply to existing Audio Native projects.  As the settings for the player are saved for each project, these need to be updated individually for existing projects.

Here is how to do this:

1.  Open the project, either from the list on [Audio Native](https://elevenlabs.io/app/audio-native) by clicking "Edit audio", or from the list on [Projects](https://elevenlabs.io/app/projects) by clicking "Edit Project".

2.  Click "Convert", then select "Share".  Click "Audio Player Settings" to open the settings for the player.  Make your adjustments and click "Save".  These changes should reflect in the player.  You may need to refresh the page.


# How to set up an ElevenLabs audio player for your articles in Squarespace



Before adding Audio Native to Squarespace, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to your Squarespace blog, sign in, and open the blog post you wish to narrate in the editor.

Next, add a line near the top of your blog post (below the header is usually best). Click the “+” symbol and select "Code" from the menu.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/squarespace_an_1.png" />

Paste your Audio Native Embed code into the HTML box, as shown below, and press enter or click away.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/squarespace_an_2.png" />

Click the Save button in the top right left of the editor, which should now be highlighted.

Now, navigate to the live version of the blog post you just updated. You should see a message to let you know that the Audio Native project is being created. This means the text in your blog post is being converted to an audio article.
After a few minutes, the embedded audio player will appear and you can click play to hear the AI-generated audio blog.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/squarespace_an_4.png" />

Follow these steps for any Squarespace blog posts that you wish to turn into audio articles.


# How to add an ElevenLabs voiceover to your articles in Substack



Substack doesn't currently allow custom code embeds which means it's not possible to add Audio Native.
Fortunately you can still use ElevenLabs to generate automated voiceovers with Projects.

To start, copy the contents of your post.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_1.png" />

Head to [ElevenLabs Projects](https://elevenlabs.io/app/projects), create a new project, choose a voice, and paste the contents of your Substack article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_2.png" />

Hit "Convert" and we'll generate a full voiceover for your article read in the voice you chose.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_3.png" />

Now that you've generated your audio, it will be available for Download in the top right corner of your dashboard. Download it now.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_4.png" />

Head back to Substack, click the Audio icon -> Voiceover, and upload the audio you downloaded from our site.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_5.png" />

All that's left is to publish your changes and your voiceover will appear just above the body content on your post.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/substack_an_6.png" />

Repeat this process for your existing and new posts and watch your engagement grow.


# How to set up an ElevenLabs audio player for your articles in Webflow



Before adding Audio Native to Webflow, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to your Webflow blog, sign in, and navigate the editor.

Click the plus icon in the top left and search for the code embed.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_1.png" />

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_2.png" />

Paste your Audio Native Embed code into the HTML box, as shown below, and press Save & Close.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_code_embed.png" />

In the Navigator, reposition the code embed near the top of your blog post (or wherever you want it to show up on your page).

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_3.png" />

Publish your changes and navigate to the live version of the blog post you just updated. You should see a message to let you know that the Audio Native project is being created. This means the text in your blog post is being converted to an audio article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_4.png" />

After a few minutes, the embedded audio player will appear and you can click play to hear the AI-generated audio blog.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/webflow_an_5.png" />

You may only need to do this once if you have one page design for all of your blog content. Repeat these steps for any other page templates where you want to add narration.


# How to set up an ElevenLabs audio player for your articles in Wix



Before adding Audio Native to Wix, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to your Wix blog, sign in, and open the blog post you wish to narrate in the editor.
Next, copy the contents of your article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_1.png" />

Head to [ElevenLabs Projects](https://elevenlabs.io/app/projects), create a new project, choose a voice, and paste the contents of your Wix article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_2.png" />

Hit "Convert" and we'll generate a full voiceover for your article read in the voice you chose.
Head to back to [ElevenLabs Projects](https://elevenlabs.io/app/projects), find your project, click "Share", enable sharing, and copy your embed code.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_3.png" />

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_4.png" />

Head back to Wix click the “+” symbol at the top of your content and select "HTML Code" from the menu.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_5.png" />

Paste your Audio Native Embed code into the HTML box, as shown below, and press save.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_6.png" />

Now, navigate to the live version of the blog post you just updated. The embedded audio player will appear and you can click play to hear the AI-generated voiceover.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wix_an_7.png" />

Follow these steps for any Wix blog posts that you wish to turn into audio articles.


# How to set up an ElevenLabs audio player for your articles in Wordpress



Before adding Audio Native to Wordpress, you'll need to create & customize your player, whitelist your blog's domain, and copy your embed code. If you need help completing those steps, refer to our [Audio Native overview](https://elevenlabs.io/docs/audio-native/overview).

Now that you've created & customized your Audio Native player, navigate to your Wordpress blog, sign in, and navigate the editor.

You'll need to install a plugin for embedding Javascript. We used [WPCode](https://wpcode.com/) for this example.

Take the Audio Native embed script and add it in your plugin.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wordpress_an_1.png" />

Choose "Auto Insert" and set the Location to be "Insert Before Content".

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wordpress_an_2.png" />

Publish your changes and navigate to the live version of the blog post you just updated. You should see a message to let you know that the Audio Native project is being created. This means the text in your blog post is being converted to an audio article.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/audio-native/images/wordpress_an_3.png" />

After a few minutes, your player will appear. Repeat these steps for any other page templates where you want to add narration.


# Overview

Dubbing made easy: reach a broader audience with ElevenLabs.

## What is dubbing?

> **Dubbing** (ˈdʌbɪŋ)
>
> Noun
>
> provide (a film) with a soundtrack in a different language from the original

ElevenLabs was founded on the idea of creating amazing dubbing; a tool that would allow you to create a perfect dub in any language you desire, using the original voice of the actors and preserving the original performance, making all content more accessible.

## Getting Started

To get started, head over to the dubbing tab where you will be presented with a view of all your previously dubbed projects. When you open it up for the first time, it will be empty. If you've ever used [Projects](/product/projects) feature previously, this will feel very familiar to you.

To get started, click "Create New Dub", and you will be presented with a window containing a few different choices.

First, you will be asked to name the dub. You can also leave the name field empty if you wish to use the file name as the title of the dub.

Select the original language and the language it will be dubbed into.

Then you will be asked to select the video or audio you want to dub. You can crete a video dub on any subscription, but you need to be on the Creator plan or above to dub an audio file. You can either upload a video or audio file or import a video directly from YouTube, TikTok, X (Twitter), Vimeo, or other URL. There is a 500MB and 45-minute limit for the clip can be that you upload. You need to stay below both.

This limit can be extended by using our API, which allows for a maximum duration of 2.5 hours and a file size limit of 1 GB. You can learn more about our API and how to use it for dubbing in our guide, [How to dub video and audio with ElevenLabs](https://elevenlabs.io/docs/api-reference/how-to-dub-a-video)

For a reduced cost, you can opt to add a watermark to your video. This option is only available for videos, which means that you will always have to pay the full cost when using audio files. It's not possible to remove a watermark after the dub has been created.

Cost of dubbing:

*   Automatic dub with watermark - 2,000 credits per minute
*   Automatic dub without watermark - 3,000 credits per minute
*   Dubbing Studio with watermark - 5,000 credits per minute
*   Dubbing Studio without watermark - 10,000 credits per minute.

One of the available options is to create a Dubbing Studio project. By checking this option, you'll unlock access to the Dubbing Studio editor. This interface will help you to enhance your audio content in various ways. You can easily regenerate specific clips to refine their quality. You can also change the voices within the editor. Furthermore, you have the ability to modify both the original transcripts and their translations. Please see our [guide to Dubbing Studio](https://elevenlabs.io/docs/dubbing/studio) for more information.

We recommend that you manually choose the number of speakers. You can also allow the AI to automatically detect how many individual speakers are in the clip, but it might not guess the correct number accurately and this will take more time than manually setting the number. If you don’t want to dub the whole video and only a portion of it, you can change the range that you want dubbed here.

There are a few things going on in the background when you create a dub. The AI can handle fully mixed and mastered audio with multiple speakers. It will separate the speakers from the background at an extremely high quality, keeping the soundtrack and the sound effects and Foley intact. It will also separate individual speakers even if they are overlapping. At the moment, the AI can handle up to three simultaneous speakers at a time.

After finalizing all your settings, review the total cost for the dubbing project, which is displayed underneath the "Create dub" button. Click "Create dub" to initiate the generation process.

The dub will then appear on the list of dubs on your Dubbing page, and you can track it's progress by checking the status. Once it's ready, you can click the ellipsis icon for the available options.

*   View - this will bring up a preview of the dub, as well as show details about the dub such as the source, the source and target languages, and how many credits were used.
*   Download - this will download your dub.
*   Remove - this will delete the dub. Please note that it's not possible to restore deleted dubs.


# Studio

The ultimate end-to-end workflow for creating amazing dubs.

<iframe width="100%" height="400" src="https://www.youtube.com/embed/DwMcfofG0js" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

## Overview

If you selected the option to create a Dubbing Studio project, once your dub finishes generating, you will see "Edit" when you click the three dots next to the dub in the list of dubs on your Dubbing page. Click "Edit" to open your Dubbing Studio project.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/dubbing/images/dubbing_studio_overview.png" />

At first, when you open the studio, it might seem overwhelming, as there's a lot of information to take in. However, if you have used an audio or video editor before, you will most likely feel right at home with the layout of the studio.

*   First, it is important to note that the initial version of the dub is an automated dub, and cannot be personalised. We compensate for this by providing credits equal to the cost of creating the project that can be used within the project. These will allow you to edit your content at no extra cost, giving you the opportunity to fully customize and regenerate your dub at least once.
*   In the middle, you will see the speaker cards, which show the transcribed audio as well as the translated transcription. If you only see one set of cards, don't fret - to see both you have to select the language you want to work on. This defaults to the original.
*   On the right-hand side, you will see the video clip that you uploaded to be dubbed. You can move this clip around and place it wherever you want. You can also resize it by dragging the corners of the clip.
*   Below all of this, you have the timeline, which shows the different voices the AI extracted on individual tracks as well as clips indicating when a specific voice is speaking, along with the corresponding clips for the original audio.
*   The timeline is also divided into a few different parts. On the left side, you can see the names of each speaker track. You can rename them here to keep your project organized. You can click the cogwheel and change settings across the whole track. However, keep in mind that if you do this, you will have to regenerate the already generated audio clips.
*   In the middle section, you have the actual timeline, which includes all of the speech clips mentioned earlier.
*   On the right-hand side, you have the settings for individual clips. When you have a clip selected, this is where you change the settings for that specific clip. You can change the volume, voice settings, or even the voice itself for the selected clip.
*   Below this, you have the current dubs available for this project. You will see the original, which is just the original audio, and then all subsequent dubs that you have created for this project in all of the different languages. Click the plus button will add another dub to the project.

## Speaker Cards

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/dubbing/images/dubbing_studio_speaker_cards.png" />

Right in the middle of the studio view, you will see the speaker cards. These cards represent the text that is being spoken by a specific voice. You can both change the transcribed text – the text that the AI has automatically transcribed from the audio – and the translated text – the text the AI has automatically translated for you from the transcription.

When you first open the studio, you will most likely only see the transcribed text from the original audio and not the translated text. However, at the bottom, below the timeline, you will see a toggle where you can switch between all the languages the project is dubbed in. When you create it initially, you will only have the original language plus the language that you selected when creating the dub. If you click the other language, you should see that the speaker cards get split into two versions of the same text: one is the original text, and the second is the dubbed text.

This toggle also determines which language you hear the dub in. If you have the original selected, you will only hear the original language, but if you select one of the other languages that the video is dubbed into, you will hear those languages. I would recommend toggling the language that you have dubbed your project into so you can follow along with the guide a little bit easier.

## Timeline

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/dubbing/images/dubbing_studio_timeline.png" />

Below the speaker cards, you will find the timeline. This is where you will refine and change the actual audio generated from the text in the speaker cards. It is segmented into different parts. On the left side, you have the tracks for each voice in the audio. In the middle, you have the clips that represent when a voice is speaking. On the right-hand side, you have the settings for the currently selected clip. We will go through all of these parts.

### Tracks

When you create your dub, you either specify the number of speakers manually (this is the recommended method) or let the AI automatically detect the number of speakers. Each speaker will be assigned a track, and each speaker will have clips on that track which represent when they're speaking and when they are not. These clips then represent the speaker cards – more on that later in the clips section.

On the left-hand side of each track, you have a few options. You can click the name, which usually just says "speaker" when you first create the dub, and then change it to the character name to keep it more organized.

On each track with a dubbed voice (not the tracks with the original voices), you will see a little cogwheel. If you click this, it will bring up some very important settings for each track. Here, you can change things such as stability, similarity, style for the whole track, as well as change how the clone is created. For example, you can select to have a clone created for each clip on the track individually (Clip Clone), create a single clone created from all clips for this speaker (Track Clone), or select a voice that you already have saved in My Voices. There's a third way to create a clone, which I will go through in the clips section.

Lastly, on each track, you have three dots that you can click to access the ability to remove the track from the project if you feel like it was created incorrectly by the AI. Perhaps it picked up some background noise and thought it was a speaker, but it was not, which means you can discard this track.

### Clips

Subsequently, each of these tracks will contain clips that represent the dialogue, audio, and speaker cards. These will be automatically created when you first create your dub.

If you click on a clip, the speaker cards will also jump to the appropriate location so you can easily find and edit transcriptions, translations, and performances. You will see two clips on top of each other in the same color; the top clip represents the original audio, and the bottom represents the dubbed audio. You can move these clips independently to adjust the audio within them. When you click a clip, it will be highlighted both in the timeline and in the speaker cards. This makes it very easy to edit specific clips without having to sync both views, as they do that automatically.

On each clip that represents a dubbed section, you will find two circling arrows which you can click to regenerate that specific clip. This will need to be done each time you have, for example, changed the settings, the voice, or the translation. You will need to regenerate the clip where this change occurred. If a clip needs to be regenerated, it will say “stale” next to these arrows. Regeneratating clips will cost credits.

If you have two clips that are very close together, you can click the gray icon between the two clips to combine them into a single, longer clip. Additionally, where the playhead is, you can click this gray icon to separate a clip into two individual clips.

If you drag either edge of a clip, you will extend or truncate it. You might notice that when you extend or truncate, the voice will either speed up or slow down, and the pitch will either go up or down as well. This is just an approximation, but you will have to regenerate the clip for the AI to be able to generate speech that will fit within the clip length and sound natural.

On the right-hand side, you will also see a few options. In contrast to the left-hand side options, which affect the whole track, these are the individual clip options. Here, you can set and change settings that will only affect the currently selected clip instead of the whole track. For example, you can set different values for stability, similarity, style, as well as adjust the volume. You can even specify a particular clone to be used for that particular clip only.

Lastly, you can right-click a clip to access a few more options. You can transcribe the audio again if you feel like the transcription was incorrect or if you've made changes to the clip. You can also delete the clip if you feel it shouldn't be there. The most interesting option here is probably that you can create a clone from a specific clip. One helpful tip is to find a clip that you like, where you feel the voice is good, right-click to create a clone from that clip, and then assign that clone to the whole track to achieve a consistent voice throughout. This is just one tip and may not work for all circumstances, but it can work very well in some cases.

### Adding Voiceover and SFX Tracks

Below the track list, you will see the following options:

*   **Dubbed Speaker Tracks:** If you encounter multiple speakers mixed within a single track, you can create a new dubbed speaker track. This allows you to isolate and transfer clips containing additional voices to the new track.

*   **Voiceover Tracks:** Voiceover tracks create new Speakers. You can click and add clips on the timeline wherever you like. After creating a clip, start writing your desired text on the speaker cards above. You'll first need to translate that text, then you can press "Generate". You can also use our voice changer tool by clicking on the microphone icon on the right side of the screen to use your own voice and then change it into the selected voice.

*   **SFX Tracks:** Add a SFX track, then click anywhere on that track to create a SFX clip. Similar to our independent SFX feature, simply start writing your prompt in the Speaker card above and click “Generate” to create your new SFX audio. You can lengthen or shorten SFX clips and move them freely around your timeline to fit your project - make sure to press the “stale” button if you do so.

*   **Upload Audio:** This option allows you to upload a non voiced track such as sfx, music or background track. Please keep in mind that if voices are present in this track, they won't be detected so it will not be possible to translate or correct them.

### "Dynamic" vs. "Fixed" Generation

In Dubbing Studio, all regenerations made to the text are "Fixed" generations by default. This means that no matter how much text is in a Speaker card, that respective clip will not change its length. This is helpful to keep the timing of the video with the speech. However, this can be problematic if there are too many or too few words within the speaker card, as this can result in sped up or slowed down speech.

This is where "Dynamic" generation can help. You can access this by right clicking on a clip and selecting "Generate Audio (Dynamic Duration). You'll notice now that the length of the clip will more appropriately match the text spoken for that section. For example, the phrase **"I'm doing well!"** should only occupy a small clip - if the clip was very long, the speech would be slurred and drawn out. This is where Dynamic generation can be helpful.

Just note, though, that this could affect the syncing and timing of your video. Additionally, if you choose "Dynamic Duration" for a clip that has many words, the clip will need to lengthen - if there is a clip directly in front of it, it will not have enough room to generate properly, so make sure you leave some space between your clips!

## Manual Import

When creating your dub, you have a special option during the creation process that is only available to the dubbing studio; manual dubbing. This option allows you to create a manual dub where you upload all of the files individually. You can upload the video file, the background audio, and the audio of only the speakers. Additionally, you should include a CSV file indicating the names of the speakers, the start and end time of when they are speaking, the original text, and the translated text. It's similar to a subtitle file but with a lot more information. This file needs to adhere to a very strict format to work correctly.

> Timecodes supported in CSV file include:
>
> seconds ([example file](https://raw.githubusercontent.com/elevenlabs/elevenlabs-docs/main/resources/dubbingTestFile%20\(seconds\).csv))
>
> hours:minutes:seconds:frame ([example file](https://raw.githubusercontent.com/elevenlabs/elevenlabs-docs/main/resources/dubbingTestFile%20\(frames\).csv))
>
> hours:minutes:seconds,milliseconds ([example file](https://raw.githubusercontent.com/elevenlabs/elevenlabs-docs/main/resources/dubbingTestFile%20\(milliseconds\).csv))

| speaker | start\_time | end\_time   | transcription                     | translation                                  |
| ------- | ----------- | ----------- | --------------------------------- | -------------------------------------------- |
| Joe     | 0:00:00.000 | 0:00:02.000 | Hey!                              | Hallo!                                       |
| Maria   | 0:00:02.000 | 0:00:06.000 | Oh, hi, Joe. It has been a while. | Oh, hallo, Joe. Es ist schon eine Weile her. |
| Joe     | 0:00:06.000 | 0:00:11.000 | Yeah, I know. Been busy.          | Ja, ich weiß. War beschäftigt.               |
| Maria   | 0:00:11.000 | 0:00:17.000 | Yeah? What have you been up to?   | Ja? Was hast du gemacht?                     |
| Joe     | 0:00:17.000 | 0:00:23.000 | Traveling mostly.                 | Hauptsächlich gereist.                       |
| Maria   | 0:00:23.000 | 0:00:30.000 | Oh, anywhere I would know?        | Oh, irgendwo, das ich kenne?                 |
| Joe     | 0:00:30.000 | 0:00:36.000 | Spain.                            | Spanien.                                     |


# Creating an Account



##

To begin using ElevenLabs, you'll need to create an account. Follow these steps:

*   **Sign Up**: Visit the ElevenLabs website and click on the 'Sign Up' button. You can register using your email or through Google OAuth.
*   **Verify Email**: Check your email for a verification link from ElevenLabs. Click the link to verify your account.
*   **Initial Setup**: After verification, you'll be directed to the Speech Synthesis page where you can start generating audio from text.

**Exercise**: Try out an example to get started or type something, select a voice and click generate!

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/account-creation.png" />
</Frame>


# Dubbing: Multilingual Support



**Dubbing Studio** allows you to translate content across 29 languages in seconds with voice translation, speaker detection, and audio dubbing.

Automated Dubbing or Video Translation is a process for translating and replacing the original audio of a video with a new language, while preserving the unique characteristics of the original speakers' voices.

We offer two different types of Dubbing: Automatic and Studio.

**Automatic Dubbing** is the default, so let’s see the step by step for this type of dubbing.

### Step by step for Automatic Dubbing

1.  Go to the Dubbing Studio in your Navigation Menu.
2.  Enter the dub name and select the original and target languages.
3.  Upload a video/audio file or import one via URL (YouTube, TikTok, etc.).
4.  Opt for watermarking if needed.
5.  Leave the Create a Dubbing Studio project box unchecked.
6.  Click on the **Advanced Settings** option:
    *   Choose the number of speakers and video resolution.
    *   Select the specific range for dubbing if needed.
7.  Click on **Create** and sit back while ElevenLabs does its magic.

**Exercise**: Dub the video found [here](https://www.youtube.com/watch?v=WnNFZt0qjD0) from English to Spanish (or a language of your choosing). Select 6 speakers and keep the watermark.

### Dubbing Studio Project

*   This is the advanced Dubbing version, which you can access by checking the **Create a Dubbing Studio project** box.

### Step by step for Dubbing using Studio Project:

1.  Follow the same steps as you had with Automatic Dubbing, this time checking the **Create a Dubbing Studio project** box.
2.  Click on **Create**.
3.  The system will auto-generate a transcription of the original audio (or for more advanced users, you can manually input the transcription using the Manual upload option during the upload stage).
4.  Review the transcription in the speaker cards and edit if necessary.
5.  If needed, re-assign clips to the appropriate speaker(s) by dragging and dropping the audio clips from the track to the speaker timeline.
6.  Click on the language where you dubbed the video in at the bottom of the screen.
7.  You will see a new set of speaker cards appearing next to your transcription, as well as a new set of audio files that are highlighted in sync with the audio timeline.
    *   (Optional) If you have made any edits to the transcription, you can re-translate the text by clicking the arrow between the two speaker cards.
    *   (Optional) You can assign different voices and/or edit the voice settings for an audio track by clicking the cog icon available next to the speaker's name within the audio track.
8.  Use the timeline to view and adjust the placement of voice clips.
9.  **You can edit clips**:
    *   By dragging the clip edges to speed up or slow down speech within in select mode.
    *   Merge clips by selecting the merge button between clips in the original audio tracks.
    *   Split clips by selecting the split button in the clip panel with the split icon to save time.
10. You can export the final output in various formats and synchronize any video or audio you wish by selecting "Export".
11. Preview the dubbed video, export when ready.
12. This allows video clips to be generated. Choose the video format and size from available options.
13. Select the dubbed file to be generated.
14. **Additional Features**:
    *   **Manual Import**: Allows for manual uploading of video, background audio, and speaker audio files, along with CSV files specifying details for each clip.
    *   **Timing Adjustments**: Choose between fixed durations to maintain video timing or dynamic durations for more natural speech flow.

**Exercise**: Dub the video found [here](https://www.youtube.com/watch?v=WnNFZt0qjD0) using Dubbing Studio from English to Spanish (or a language of your choosing). Select 6 speakers and keep the watermark.

For more information, visit the [Dubbing Overview page](/product/dubbing/overview).


# Overview

Step by step worflow guides.

This guide covers everything from account creation to advanced voice cloning, speech synthesis techniques, dubbing, and expert voiceover.

## [Guides](/product/guides)

<CardGroup cols={2}>
  <Card title="Creating an Account" icon="user-plus" href="/product/guides/creating-the-account">
    Start your journey by setting up your account with ease.
  </Card>

  <Card title="Workspace: Collaborating with Your Team" icon="users" href="/product/guides/workspace">
    Learn how to work together with your team in a shared workspace.
  </Card>

  <Card title="Understanding the Landing Page" icon="page" href="/product/guides/landing-page">
    Get familiar with the main dashboard and navigation.
  </Card>

  <Card title="Managing Your Voices" icon="microphone" href="/product/guides/voices">
    Master the management of your custom voices.
  </Card>

  <Card title="Speech Synthesis: Generating Audio" icon="volume-high" href="/product/guides/speech-synthesis">
    Discover how to create audio from text with speech synthesis.
  </Card>

  <Card title="Sound Effects: From Text to Sounds" icon="headphones" href="/product/guides/sound-effects">
    Transform your text into engaging sound effects.
  </Card>

  <Card title="Managing Long-Form Content" icon="podcast" href="/product/guides/projects">
    Keep your long-form content organized and accessible.
  </Card>

  <Card title="Dubbing: Multilingual Support" icon="language" href="/product/guides/dubbing">
    Explore options for dubbing your content in multiple languages.
  </Card>

  <Card title="Voiceover Studio: The Best Way to Work with Voices" icon="microphone-lines" href="/product/guides/voiceover-studio">
    Utilize the ultimate tools for voiceover creation and management.
  </Card>

  <Card title="API Guides" icon="code" href="/api-reference">
    Interested in more? Check our API Guides!
  </Card>
</CardGroup>

***

### Creating an Account

To get started, sign up with your email or Google OAuth. Verify your email, and you'll be directed to the Speech Synthesis page to begin creating voiceovers. We strongly recommend adding 2FA to your account.

### Workspaces: How to Work Together

For teams that want to collaborate in ElevenLabs, we offer shared workspaces. Workspaces offer four benefits: Shared billing, Shared resources, Access management, and API Key management.

### Understanding the Landing Page

Your dashboard is the control center for all activities on ElevenLabs. Here, you can access VoiceLab, Speech Synthesis tools, and manage your projects and subscriptions.

### Voices: Cloning Your First Voice

Voices allows you to clone voices. This feature is available from the Starter tier and above. Use the Voice Design tool or select from the Voice Library to create custom voices.

### Speech Synthesis: Generating Audio

Generate audio by typing text into the input box and pressing "generate." Choose from pre-made or custom voices and adjust settings for desired output.

### Projects: Create Long-Form Content

Projects enable you to create voiceovers for long-form content like audiobooks. This tool streamlines the process, making it easy to manage and produce lengthy audio content.

### Dubbing: Create Your Content in Multiple Languages

Our dubbing feature supports multiple languages, maintaining the original voice and performance across translations. This is ideal for creating multilingual content efficiently.

### Sound Effects: From Text to Sounds

Sound effects enhance the realism and immersion of your audio projects. ElevenLabs offers a variety of sound effects that can be easily integrated into your voiceovers and projects.

### Voiceover Studio: The Best Way to Work with Voices

Voiceover Studio is a comprehensive toolset for creating high-quality voiceovers.

### Troubleshooting and Tips

Explore our troubleshooting section for common issues and solutions. Additionally, find tips and tricks to optimize your experience with ElevenLabs. Remember to use [enterprise@elevenlabs.io](mailto:enterprise@elevenlabs.io) for any issues, or reach out to [success@elevenlabs.io](mailto:success@elevenlabs.io).


# Understanding the Platform Landing Page



The landing page is your control center for managing all aspects of ElevenLabs. Here's a closer look at its sections:

### Landing Page Elements

1.  **Navigation Menu**: Access the ElevenLabs features broken down in the Create, Workflows, and Tools sections.
2.  **Character Quota**: Indicates the remaining characters for your workspace.
3.  **User Profile and Workspace Panel**: Clicking on the User Profile and Workspace Panel will provide you access to the following options:

    *   **Admin**:
        *   Profile + API key: This is where you can find your personal API key.
        *   Workspace Settings: Your hub for inviting users, managing workspace API keys, and configuring SSO.
        *   Subscription: This is where you will be able to see your current spend, view your invoices (by clicking on Manage Subscription), and enable usage-based billing (enabling you to go over your current subscription quota).
        *   Payouts.
        *   Usage analytics: Your Analytics hub, where you will be able to see usage per voice, user, API key, etc.
        *   Docs and resources: Link to our resources and documentation.
        *   Terms and privacy.
        *   Sign out.

    *   **User**:
        *   Profile + API key: This is where you can find your personal API key.
        *   Payouts.
        *   Usage analytics: Your Analytics hub, where you will be able to see usage per voice, user, API key, etc.
        *   Docs and resources: Link to our resources and documentation.
        *   Terms and privacy.
        *   Sign out.


# Projects: Managing Long-Form Content



**Projects** offer an end-to-end workflow for creating long-form content. You can upload a book, document, or import a webpage via URL. The AI generates a voiceover for the entire content, and you can download individual MP3 files for each chapter or a single file for the whole document or audiobook.

### Step by step on how to create a Project

1.  **Create a New Project**

    *   Go to Projects in your Navigation Menu.
    *   Click "Add a new Project."
    *   Enter the project name.
    *   Choose to create an empty project or import a file (EPUB, PDF, TXT) or a webpage via URL.
    *   Select the default voice and model, and set the quality settings.
    *   Click "Create Project".

2.  **Add and Manage Content**

    *   Add files by uploading documents or importing text from a URL.
    *   Organize your content into chapters.
    *   The system will auto-split well-structured files into chapters.

3.  **Generate Voiceover**

    *   Open your project and select the text to convert.
    *   Choose a voice model and adjust settings (e.g., voice stability, style, similarity).
    *   Click the play button to generate the voiceover for the selected text block.
    *   For continuous play, use the "Play until end" button to listen to multiple paragraphs sequentially.

4.  **Adjust Settings and Regenerate Audio**

    *   Use the "Voice settings" button to adjust the project's default voice and view model settings.
    *   Change voice settings for specific paragraphs.
    *   To regenerate a paragraph, select it and click the "Regenerate" button.

5.  **Download Audio Files**

    *   Once satisfied, download individual MP3 files for each paragraph or chapter.
    *   Click the "Convert" button to compile and download the entire project or specific chapters as a single audio file.
    *   Use the "Download" button for various download options, including project-wide or chapter-specific files.

6.  **Pronunciation Dictionaries**
    *   Upload a pronunciation dictionary in PLS (Pronunciation Lexicon Specification) format via project settings.
    *   Use phonemes or aliases to specify accurate pronunciations of words, ensuring consistency and clarity in the generated speech.

**Exercise**: Upload [*Alice's Adventures in Wonderland by Lewis Carroll*](https://www.gutenberg.org/ebooks/11) and convert a chapter of your choosing using the voice of your choosing. Download said chapter.

For more information on Projects, visit the [Projects Overview page](/product/projects/overview).


# Sound Effects: From Text to Sounds



**Sound effects** enhance the realism and immersion of your audio projects. ElevenLabs offers a variety of sound effects that can be easily integrated into your voiceovers and projects.

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/sound-effects.png" />
</Frame>

### Step by step on how to create a Sound Effect

1.  **Head over to the Sound Effects section on ElevenLabs.**
2.  **In the text box**, type a description of the sound effect you want (e.g., “person walking on grass”).
3.  **Click on and adjust the settings:**
    *   **Set the duration** for the generated sound.
    *   **Use the prompt influence slider** to control how closely the output matches your description.
4.  **Generate Sound**.
5.  You should have four different sounds generated. If you like none of them, adjust the prompt or settings as needed and regenerate.

**Exercise**: Create a Sound Effect using the following prompt: old-school funky brass stabs from an old vinyl sample, stem, 88bpm in F# minor.

As with Speech Synthesis, you have the option of seeing your generation history; similarly, we have some already-made sound effects for you to check out in the **Explore** tab.

For more information on how sound effects work visit the [Sound Effects Overview page](/product/sound-effects/overview).


# Speech Synthesis: Generating Audio



**Speech Synthesis** allows you to generate lifelike speech from text (**Text to Speech**) or audio (**Speech to Speech**) inputs. In this section, you can also see your generation history and thus retrieve past generations.

Selecting **Advanced Mode** allows you to select the model you would like to use for your generation as well as the voice settings (Stability, Similarity, Style, and Speaker Boost) on top of the existing options with Standard.

Let’s touch on models and voice settings briefly before generating our audio clip.

### Models

More detailed information about the models is available [here](product/speech-synthesis/models).

*   **Multilingual v2 (default)**: Supports 28 languages, known for its accuracy and stability, especially when using high-quality samples.
*   **Turbo v2.5**: Generates speech in 32 languages with low latency, ideal for real-time applications.
*   **Turbo v2**: Optimized for low-latency English text-to-speech, similar in performance to Turbo v2.5.
*   **English v1**: The oldest and fastest model, best for audiobooks but less accurate.
*   **Multilingual v1**: Experimental, surpassed by Multilingual v2, recommended for short text chunks.

### Voice Settings

More detailed information about the voice settings is available [here](product/speech-synthesis/voice-settings).

*   **Stability**: Adjusts the emotional range and consistency of the voice. Lower settings result in more variation and emotion, while higher settings produce a more stable, monotone voice.
*   **Similarity**: Controls how closely the AI matches the original voice. High settings may replicate artifacts from low-quality audio.
*   **Style Exaggeration**: Enhances the speaker's style, but can affect stability.
*   **Speaker Boost**: Increases the likeness to the original speaker, useful for weaker voices.

Now that we understand models and voice settings a bit better, let's jump into generating audio!

***

### Text to Speech (TTS)

**Step by step to Generate Text to Speech Audio**

1.  **Text Input**: Type or paste your text into the input box on the Speech Synthesis page.
2.  **Select Voice**: Select the voice you wish to use from your Voices at the bottom left of the screen.
3.  **Adjust Settings**: Modify the voice settings for the desired output.

**Generate**: Click the 'Generate' button to create your audio file.

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/text-to-speech.png" />
</Frame>

**Exercise**: Generate “All work and no play makes Jack a dull boy” using Alice’s voice (or a voice of your choosing).

***

### Speech to Speech (STS)

**Steps to Generate Speech to Speech Audio**

1.  **Audio Input**: Upload or record audio via the input box on the Speech Synthesis page.
2.  **Select Voice**: Select the voice you wish to use from your Voices at the bottom left of the screen.
3.  **Adjust Settings**: Modify the voice settings for the desired output.

**Generate**: Click the 'Generate' button to create your audio file.

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/speech-to-speech.png" />
</Frame>

<Tip>
  Speech to Speech is great for getting the right emotion across when the Text
  to Speech can’t get it right.
</Tip>

**Exercise**: Record yourself saying and generate “The cellar door is open, revealing a world of hidden treasures.” using Brian’s voice (or a voice of your choosing).


# Voiceover Studio



Similar to the Dubbing Studio, the new **Voiceover Studio** offers users the chance to create interactive content with greater flexibility. It integrates the Studio functionality with the Sound Effects feature, allowing users to create dialogues for multiple speakers from scratch and seamlessly incorporate their own creative sound effects throughout the project.

### Step by step to use Voiceover Studio

1.  **Click on the Voiceover Studio** in your Navigation Menu.
2.  Either **upload an existing video** you want to create the voiceover for, or start a project from scratch by clicking the **Create voiceover** button.
3.  At the bottom of the screen, you can **Add Voiceover and/or SFX Tracks** or **Upload Audio**.
4.  Enter the desired text into the speaker card.
5.  **Choose a voice** by clicking on the cog button next to the speaker name in the audio timeline and select the desired voice settings.
6.  **Add Speakers**: Click on "Speakers" to add different speaker profiles and assign clips.

**Exercise**: Upload your own video and follow along with Mike on how to use the Voiceover Studio [here](https://www.youtube.com/watch?v=Ka6ljU1MULc).

For more information, visit the [ElevenLabs Voiceover Studio overview](product/voiceover-studio/overview).


# Voices: Managing your Voices



<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/account-creation.png" />
</Frame>

The Voices feature allows you to manage and create voices, both private to you and the ones made publicly available by our community (via the Voice Library).

### My voices

Within the **My Voices** section, you will be able to see all the voices that you have added to your account as well as the voices provided to you by default.

Before adding new voices, it's important to understand the three types of voices that you are able to create using ElevenLabs:

1.  **Voice Design Voices** - Randomly computer-generated voices. More information available [here](/product/voices/voice-lab/voice-design).
2.  **Professional Voice Clones (PVCs)** - A PVC is an ultra-realistic, custom AI model of your voice. This is done by training our specialized model with longer voice data (at least 30 mins and up to 3 hours for optimum results) to make it sound just like the original voice.
3.  **Instant Voice Clones (ICVs)** - Voice clones based on short audio clips. Unlike PVCs that create an AI model of the voice, it relies on prior knowledge from training data to make an educated guess rather than training on the exact voice. More information available [here](/product/voices/voice-lab/instant-voice-cloning).

With that in mind, let’s create a brand-new voice!

<Frame>
  <img width="400" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/type-of-voice.png" />
</Frame>

### How to Create Voices

1.  **Click on Add a new Voice** to open the following pop-up and select the voice you would like to create, from there follow the guidelines provided by the in-app pop-up window to create the voice you desire.
2.  **Important for Voice Clones**:

<Note>
  {" "}

  With every Voice Clone, it is important that you have the person’s permission to
  clone their voice.
</Note>

*   Please ensure the audio is recorded without any background sounds, ideally with
    good equipment and with the tonality, cadence, and performance style you would like
    to recreate with your generations. Sub-par audio quality will influence the outputs
    of your generations. For optimal results, we highly recommend following our [guide
    to Audio Recording](/product/voices/pvc-step-by-step-guide#beginners-guide-to-audio-recording).
*   If background noises cannot be avoided, you can use [Voice Isolator](https://elevenlabs.io/blog/voice-isolator)
    to retrieve the voice and rid yourself of unwanted background noise. 3. Once you’re
    done generating or creating your voice, it will be made available to you and you
    alone in the **My Voices** section.

**Exercise**: Create a Voice Design voice (or clone a voice if you have the necessary permissions) with the knowledge you have gained from this section.

### Sharing your voice

1.  Click on the share button for the voice you want to share.
2.  Enable the sharing toggle.
3.  Share the link with the colleague or place it in your document/intranet.

**Exercise**: Share a voice with a colleague.

### Library voices

You are also able to add voices from our community marketplace via the **Library**. Simply click on the **Add Voice** button for the voice that you want to share.

**Exercise**: Add a voice from the Library to your **Voices**.


# Workspaces: Collaborating with your team



Workspaces in ElevenLabs are designed to facilitate collaboration, organization, and governance for Enterprise teams. Once you have been upgraded to Enterprise, your administrator will automatically be granted admin permissions for your workspace.

To get started with your workspace:

*   Click on your User Profile at the bottom left of your screen and select Workspace Settings.
    *   Here you are able to change the name of your workspace
    *   See how many seats and Professional Voice Clones (PVCs) you have associated with your workspace
    *   And most importantly add and remove members and select the type of user you would like them to be

<Note>
  **Important**: you are currently only able to invite users that do not have an
  ElevenLabs account already, please reach out to [success@elevenlabs.io](mailto:success@elevenlabs.io) if you
  are attempting to add someone with an account
</Note>

*   Next click on your User Profile again and click on Subscription to view your subscription
    details and track your usage. Keep an eye on your usage, and if you are worried you
    might be going over your current Tier, we strongly recommend enabling usage-based
    billing. This will enable you to exceed the allocated quota and, more importantly,
    prevent your account from being blocked if the character quota is reached.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/guides/images/workspaces.png" />

For more details, visit the [Workspace Overview page](/product/workspace/overview).


# Introduction

Explore our Guides and API Reference to get the most out of ElevenLabs.

## Welcome

In this documentation we will help you get started with [ElevenLabs](https://elevenlabs.io). Before we get started, we would like to mention that we also offer a [Help Center](https://help.elevenlabs.io/hc/en-us) which is more of an FAQ. Here, you can find answers to individual questions and interact with our chatbot. Additionally, you can submit tickets directly to our support team if you have any inquiries.

### Create

We will cover everything, beginning with Text to Speech and Speech to Speech, where you will generate your first audio using our Default Voices.

We also provide several features that extend beyond the realm of speech, including our Sound Effects Generator and our upcoming [Music Generator](https://www.youtube.com/watch?v=d8k4Pit4_ZU) (release date and name to be determined).

<AccordionGroup>
  <Accordion title="Text to Speech (Speech Synthesis)">
    Our Text-to-Speech technology, also known as Speech Synthesis, is the core of ElevenLabs. It serves as the foundation for many of the features we offer and powers many services worldwide. This technology transforms text into incredibly realistic speech.

    To ensure you get the most out of this feature, it is important to use an appropriate voice for what you are trying to achieve and to familiarize yourself with the different models we offer, as both of these factors have a tremendous effect on the delivery and quality of the output.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/speech-synthesis/overview" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/text-to-speech" />
  </Accordion>

  <Accordion title="Speech to Speech (Voice Changer)">
    Our Speech-to-Speech technology, also known as Voice Changer, converts a source voice (audio input) into a different voice while retaining the source voice's accent, cadence, and overall delivery, but with the timbre and vocal quality of the selected voice.

    This feature is great for standalone usage, as it provides your voice acting with a wider range of tonalities. Additionally, when used in conjunction with Text-to-Speech, it allows for easy correction of pronunciations and adds specific performances or characteristics, emulating subtle vocal nuances for a more human touch. You can make the AI whisper, sigh, laugh, or cry by simply acting it out and then using the voice changer.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/speech-synthesis/speech-to-speech" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/speech-to-speech" />
  </Accordion>

  <Accordion title="Sound Effects">
    Our Sound Effects generator allows you to create a wide range of audio effects by inputting descriptive prompts. This feature is great across variety of uses, such as film sound design, video game audio, music production, and much more. Users can generate sounds by typing a description into a text box, and the AI will produce multiple variations based on the given prompt.

    The tool offers settings to control the duration of the sound and how closely the output adheres to the prompt.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/sound-effects/overview" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/sound-generation" />
  </Accordion>

  <Accordion title="Music (in development)">
    <iframe width="100%" height="400" src="https://www.youtube.com/embed/d8k4Pit4_ZU?si=2zdtx-7zD7S9zGyU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
  </Accordion>
</AccordionGroup>

### Voices

Once you have created your first audio output, we will proceed to cloning or designing your first voice on the My Voices page. After setting up your voices, you will be able to use your own voices to generate audio.

<AccordionGroup>
  <Accordion title="Voice Design">
    Voice Design allows for the creation of unique voices from text prompts, filling gaps when specific voices aren't available in the Voice Library or where you might even prefer a synthetically generated voice. You can create both realistic voices, which focus on attributes like age, accent, and emotion, and character voices, which allow you to create more creative voices by using more creative language.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/voices/voice-lab/voice-design" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/ttv-create-previews" />
  </Accordion>

  <Accordion title="Instant Voice Cloning">
    Instant Voice Cloning enables you to create voice clones quickly from short audio samples, without the need for training. It uses a technology to create voice instantaneously, capturing its tone and inflections. While effective for many voices, it may struggle with unique accents or voices not encountered during training. High-quality, consistent audio samples are crucial for optimal results.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/voices/voice-lab/instant-voice-cloning" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/add-voice" />
  </Accordion>

  <Accordion title="Professional Voice Cloning">
    Professional Voice Cloning creates hyper-realistic voice models by training on larger datasets of a speaker's voice. Available from the Creator tier and above, it offers extremely higher accuracy and can capture intricate details, such as accents and tonal nuances. This method requires more audio data, between 1 - 3 hours, and a few hours to train the model but results in a voice clone that closely resembles the original.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/voices/voice-lab/professional-voice-cloning" />
  </Accordion>

  <Accordion title="Voice Library">
    The Voice Library is a marketplace where users can share and discover a wide variety of voices, including professional voice clones from real people who have cloned their voices and decided to share them with the rest of the community.

    It offers filters and search options to help users find specific voice styles, languages, and accents. Users can add voices to "My Voices" for use across ElevenLabs features, and shared voices can earn either credits or monetary rewards based on usage.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/voices/voice-library/overview" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/query-library" />
  </Accordion>
</AccordionGroup>

### Workflows

Moving on, we will also go through our workflow-specific section, where we offer a variety of tools and workflows for different needs.

First, we will start with Projects, which is our end-to-end solution for creating voiceovers for long-form content, such as articles or audiobooks, with just a few clicks.

We will cover Dubbing, our solution for making content more accessible in all languages while preserving the original voice and striving to maintain the same performance across languages. This service comes in two flavors: automatic and studio.

Our automatic solution allows users to create dubs in any language supported by the AI with just a few clicks. Meanwhile, the Dubbing Studio provides an end-to-end workflow with great controllability for producing perfect dubs.

Finally, we will cover our Conversation AI platform, which provides an easy setup process for quickly and easily deploying conversational AI, as well as API endpoints and SDKs, to allow for seamless integration into your existing applications or flows.

<AccordionGroup>
  <Accordion title="Projects">
    Projects is a comprehensive tool for creating long-form audio content, such as audiobooks. It allows users to upload documents or web pages and generate voiceover narrations. It is easy to manage and keep track of all of your projects, select voices, and adjust settings for quality and download options. Projects is available on paid tiers, offering an efficient workflow for producing lengthy audio content.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/projects/overview" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/add-project" />
  </Accordion>

  <Accordion title="Dubbing">
    Dubbing allows you to create high-quality dubs in various languages while preserving the original performance. You can upload or import video/audio files and select the original and target languages. The tool supports multiple formats and offers options for modifying specific parts of the dub. It's available on all plans, with advanced features in the Dubbing Studio.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/dubbing/overview" />

    <Accordion title="Automatic">
      Automatic Dubbing quickly translates and replaces the original audio of a video with a dub in a new language, maintaining the original speaker's voice characteristics. It provides a final output without the option for edits, making it ideal for fast and straightforward dubbing needs. You can upload files or import them via URL to start the process.

      <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/create-dub" />
    </Accordion>

    <Accordion title="Studio">
      Dubbing Studio offers an advanced dubbing experience, allowing you to edit and customize dubs extensively. It supports manual transcription adjustments, voice selection, and precise timing edits. You can manage speaker tracks, regenerate audio, and export the final output in various formats. This feature provides full control over the dubbing process, ideal for detailed and tailored projects.

      <Card title="Full Documentation" icon="book" horizontal="true" href="/product/dubbing/studio" />
    </Accordion>
  </Accordion>

  <Accordion title="Voiceover Studio">
    Voiceover Studio allows you to create interactive audio content with flexibility. It combines an audio timeline with text-to-speech, speech-to-speech, and sound effects, enabling the creation of dialogues between multiple speakers. You can upload videos or start projects from scratch, adding voiceover and sound effects tracks. Available on the Creator plan and above, it offers tools for crafting detailed and dynamic voiceover projects.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/voiceover-studio/overview" />
  </Accordion>

  <Accordion title="Audio Native">
    Audio Native is an embedded audio player that automatically voices web page content using ElevenLabs' text-to-speech service. It allows embedding pre-generated audio from projects into web pages with a simple HTML snippet. Available on the Creator plan and above, it includes metrics for tracking audience engagement through a listener dashboard.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/product/audio-native/overview" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/api-reference/creates-audionative-enabled-project" />
  </Accordion>

  <Accordion title="Conversational AI">
    Conversational AI is a platform for deploying interactive voice agents that can interact with you or your users in natural conversations. It integrates Speech to Text, Language Models, and Text to Speech, along with features like interruption handling and turn-taking logic. Users can customize agents with different voices and system prompts, making it suitable for applications like customer service, virtual assistants, and interactive characters.

    <Card title="Full Documentation" icon="book" horizontal="true" href="/conversational-ai" />

    <Card title="API Reference" icon="rectangle-code" horizontal="true" href="/conversational-ai/api-reference" />
  </Accordion>
</AccordionGroup>

## Signing up

You can sign up using the traditional method of email plus password or using Google OAuth.

If you choose to sign up with your email, you will be asked to verify your email address before you can start using the service. Once you have verified your email, you will be taken to the Speech Synthesis page, where you can immediately start using the service. Simply type anything into the box and press "generate" to convert the text into voiceover narration. Please note that each time you press "generate" anywhere on the website, it will deduct credits from your quota.

If you sign up using Google OAuth, your account will be intrinsically linked to your Google account, meaning you will not be able to change your email address, as it will always be linked to your Google email.

## Subscriptions

Once you sign up, you will be automatically assigned to the free tier. To view your subscription, click on "My Account" in the bottom left corner and select ["Subscription"](https://elevenlabs.io/app/subscription). You can read more about the different plans [here](https://elevenlabs.io/pricing). If you scroll down, you will find a comparison table that can be quite helpful in highlighting the differences between the various plans.

We offer five public plans: Free, Starter, Creator, Pro, Scale, and Business. In addition, we also offer a sixth option - Enterprise - tailored to the unique needs and usage of our clients.

You can see details of all our plans on the subscription page. This includes information about the total monthly credit quota, the number of custom voices you can have saved simultaneously, and the quality of audio produced.

Cloning is only available on the Starter tier and above. However, the free plan offers three custom voices that you can create using our Voice Design tool, or you can add voices from the Voice Library if they are not limited to paid tiers only.

You can upgrade your subscription at any time, and any unused quota from your previous plan will roll over to the new one. As long as you don’t cancel or downgrade, unused credits at the end of the month will carry over to the next month, up to a maximum of two months’ worth of credits. For more information, please visit our Help Center articles:

*   ["How does credit rollover work?"](https://help.elevenlabs.io/hc/en-us/articles/27561768104081-How-does-credit-rollover-work)
*   ["What happens to my subscription and quota at the end of the month?"](https://help.elevenlabs.io/hc/en-us/articles/13514114771857-What-happens-to-my-subscription-and-quota-at-the-end-of-the-month)

From the subscription page, you can also downgrade your subscription at any point in time if you would like. When downgrading, it won't take effect until the current cycle ends, ensuring that you won't lose any of the monthly quota before your month is up.

When generating content on our paid plans, you get commercial rights to use that content. If you are on the free plan, you can use the content non-commercially with attribution. Read more about the license in our [Terms of Service](https://elevenlabs.io/terms) and in our Help Center [here](https://help.elevenlabs.io/hc/en-us/articles/13313564601361-Can-I-publish-the-content-I-generate-on-the-platform-).

For more information on payment methods, please refer to the [Help Center](https://help.elevenlabs.io/).


# Overview

An in-depth overview of using Projects

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/projects.png" />

## Creating a Project

Projects is an end-to-end workflow for creating long-form content. It allows you to upload a full book or document. You can even import a whole webpage via a URL. The AI can then generate a voiceover narration for the entire book, document, or webpage. You can then download either individual MP3 files for each chapter or as a single MP3 file for the whole audiobook.

We will provide a brief walkthrough of this feature, but we recommend that you test it yourself by navigating to the Projects tab in the menu.

Once you enter the new tab, you will encounter a screen where you can create new projects or open existing ones. The number of projects you can have at any given time is determined by your subscription. The higher your subscription is, the more projects you can have concurrently.

Click "Add a new project” and you will be presented with a popup. Here, you can choose to create a new empty project, import an already existing EPUB, PDF, TXT or HTML file, which will then automatically be converted into a project, or import text directly from a website using the URL to have the page be converted into a project. You can then use our [Audio Native](/product/audio-native/overview) feature to easily and effortlessly embed any narration project onto your website.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/projects_new.png" />

For now, let's create a new empty project. You can name your project and choose the default voice. Additionally, you will need to select the model that will be used and decide the quality settings. The voice and its settings can be changed after the project is created.

<Note>
  Model and quality settings will remain locked after the project has been created and cannot be changed without creating a completely new project from scratch.
</Note>

The quality setting determines the quality of the rendered output of your projects. This setting decides the bitrate for the MP3/Lossless WAV and quality optimization. For most people, standard or high settings will be sufficient. However, for those who require the highest possible quality we offer Ultra and Ultra Lossless (an uncompressed WAV file) which might be preferable in certain cases. These different quality settings have different costs associated with them, as they require different computational resources. Ultra Lossless is quite computationally intensive, making it the most expensive option. You are more than welcome to experiment with these different quality settings to find the one that best suits your project.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/project_quality_updated.png" />

Once you set all the settings, press Create Project, you will be redirected to the editor.

## Settings and Buttons

Once inside the project, you will be presented with a blank page. However, if you choose to create a project by either importing a file or using a URL, you will be presented with that text as the system will automatically fill out the pages for you. If the EPUB, is well-structured and correctly formatted, it will also automatically split each chapter into its own chapter in Projects, making it very easy to navigate.

If you've ever used an online text editor, you will find yourself very at home with both the look and the structure of Projects, but we do have a few nifty features that will help you with especially long-form content.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/projects_overview.png" />

At the top, you have a few buttons. You can hover over some of these buttons to get more information.

Most of these are probably pretty self-explanatory, but let's go through all of them.

<Accordion title="1–7 Selection">
  **1. Play** will play currently selected paragraph, if it's not generated yet it will generate it. You can open options to change the button behaviour.
  **Play until end** means that when you play a paragraph, it will continue and play the next one once the first one finishes. This makes it so that you can listen to your audiobook without having to pre-render all of the paragraphs first.

  **2. Regenerate** will regenerate the currently selected paragraph and give you a new performance from your voice. This will replace previous generation, but you can restore it in **5. Generation history**. You can also select part of the paragraph to regenerate only one sentence.

  **3. Voice** will change the voice of selected paragraph(s). You can select multiple paragraphs to change voice for bigger selection. You can select fragment of the paragraph to have multiple speakers in one paragraph.

  **4. Voice settings** will change voice settings for currently used voice or current paragraph.

  **5. Paragraph type** allows you to set headings for easier reading. Headings have longer audio break after them.

  **6. Generation history** allows you to restore previous generations for each paragraph. It's helpful if you edited an already generated paragraph by mistake, or you liked the previous generation better.

  **7. Locking** allows you to disable paragraph editing after you are happy with the performance.
</Accordion>

<Accordion title="8–12 Project">
  **8. Project settings** allow you to change general settings, export settings and share settings.

  **9. Convert** allows you to convert a whole Project or Chapter at once. After you converted Project you can download .mp3 or .wav audio file and .zip file with every chapter.

  **10. Credits balance** allows you to control your spending.

  **11. Projects title section** allows you to change a Project's title and toggle visibility of the Chapter list.

  **12. Add a new chapter** creates a new chapter.
</Accordion>

<Accordion title="13–16 Editor">
  **13. Locked paragraph** is indicated by a Lock icon. You can't edit it unless you unlock it first.

  **14. Current paragraph** current paragraph is indicated by the highlight. Different colours indicate different speakers.

  **15. Chapters list** allows you to navigate between chapters, clicking currently picked chapter name allows you to rename it.

  **16. Unconverted paragraphs** have a grey line on the left. Converted paragraphs have a darker line next to them.
</Accordion>

## Using Projects

Now you can start writing. Please ensure that you use proper grammar and paragraph structures, as well as using line breaks where appropriate, as the AI will use these when generating. This goes for both Projects and Speech Synthesis, but it is even more important in Projects for optimal results.

When you have finished writing your text and are happy with it, you can generate a voiceover for it. You can click the paragraph - for which you want to generate audio. The current selection will be highlighted in colour. Then to generate that section to audio, just click the play button at the top. This will initiate the generation of audio for the specific section you have highlighted. Once the audio has finished generating, it will play. This process is similar to how audio generation works on the Speech Synthesis page.

Paragraphs that have already been generated are indicated by the black bar on the left-hand side of each paragraph. If you press the play button on the top bar and a paragraph has already been generated, it will just play that paragraph. However, if you press the regenerate button, with two circling arrows, it will regenerate the paragraph.  Once a paragraph has been generated at least once, you can select one or more words to regenerate only the selected text, rather than the whole paragraph.  For the best results, we recommend regenerating a complete phrase or sentence at a time.

If you press the play button, and the paragraph is fully generated, you can also download the paragraph by clicking the download button in the lower right corner of the player. This is exactly how it works in the Speech Synthesis. However, this button will only appear when something is finished generating. So, if you have "play until end" activated, it will not appear because the AI will keep generating the next section after the next section., meaning this only works for downloading individual paragraphs.

If you want to convert the entire chapter in one go, you can click the convert button in the upper right corner. This will open a page where you can choose to convert either your entire project or individual chapters. You can also download the entire project or individual chapters. Even after converting the whole chapter, you can still go back and regenerate sections of the book that you are not happy with before downloading the entire thing. However, if you make any changes, you will need to press convert once again for the changes to be reflected in the whole book, so you can download the entire chapter.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/projects_convert.png" />

After the conversion of either a whole project or individual chapters has finished, you will be able to see these conversions by clicking “Versions” next to either the project or the individual chapters. You can then download the different versions.

Once your Project is converted, you have several download options available.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/projects/images/projects_zip_dropdown.png" />

## Pronunciation Dictionaries

Sometimes you may want to specify the pronunciation of certain words, such as character/brand names, or to specify how acronyms should be read. Pronunciation dictionaries allow this functionality by enabling you to upload a lexicon or dictionary file that specifies pairs of words and how they should be pronounced, either using a phonetic alphabet or word substitutions. Whenever one of these words is encountered in a project, the AI model will pronounce the word using the specified replacement.

To provide a pronunciation dictionary file, open the settings for a project and upload a file in the [.PLS format](https://www.w3.org/TR/pronunciation-lexicon/). When a dictionary is added to a project it will automatically recalculate which pieces of the project will need to be re-converted using the new dictionary file and mark these as unconverted.

Currently we only support PLS files that specify replacements using Phonemes, or Aliases.

*   Phonemes. Phonemes are used to specify pronunciation using either the IPA (International Phonetic Alphabet) or CMU Arpabet alphabet. Phoneme rules are currently only supported by the Turbo v2 English model.
*   Aliases. Aliases are used to specify pronunciation using other words or phrases. For example, to specify that the "UN" should be read "United Nations" whenever it is encountered in a project.  You can use aliases with all models.

Both sets of rules specify a word or phrase they are looking for, referred to as a grapheme in the PLS files, and then their replacement. Please note that searches are case sensitive.

Here is an example PLS file that specifies in IPA the pronunciation of "Apple" with IPA of "ˈæpl̩" and "UN" with an alias of "United Nations":

```
<?xml version="1.0" encoding="UTF-8"?>
<lexicon version="1.0"
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
      alphabet="ipa" xml:lang="en-GB">
  <lexeme>
    <grapheme>Apple</grapheme>
    <phoneme>ˈæpl̩</phoneme>
  </lexeme>
  <lexeme>
    <grapheme>UN</grapheme>
    <alias>United Nations</alias>
  </lexeme>
</lexicon>
```

When checking for a replacement word in a pronunciation dictionary, the dictionary is checked from start to end and only the very first replacement is used.


# Overview

Get the most out of our Sound Effects Generator tool and learn how to create everything from blockbuster sound design for films to everyday sounds for your video game.

It is said that audio is more important than visuals. Most people can accept bad visuals, but most can't stand bad audio. Audio also evokes emotions and sets moods for your audience; it can be subtle, or it can be bombastic. Depending on the type of sounds and music that you use in your production, it can completely change the emotional context and meaning behind what you are trying to convey.

However, sometimes it's quite difficult to find that perfect sound. But it has now become much easier with ElevenLabs, as our sound effects generator allows you to generate any sound imaginable by inputting a prompt, streamlining the process tremendously. Of course, this is not only a great tool for independent filmmakers or indie game developers. It is also a fantastic resource for big productions, sound designers, and producers because you can generate such a vast array of sounds.

We will go through some of them here in this documentation. Keep in mind that this is just scratching the surface. While the feature might seem simple at first glance, the understanding that the AI has of natural language, combined with the type of sound effects it can generate, opens up infinite possibilities.

The general layout for sound effects is fairly straightforward. You have a window where you will input a prompt, some settings, and a generate button. When you first open the web page, you will have a few suggestions below the text box to showcase what some of the prompts might look like that you can easily try out.

Each time you press generate, the AI will create full variations of the prompt you've given. The cost for using the sound effects generator is based on the length of the generated audio. If you let the AI decide the audio length itself, the cost is 200 characters per generation. If you set the duration yourself, the cost is 40 characters per second.

## Prompting

A prompt is a piece of text or instruction that communicates to the AI model what kind of response or output is expected. The prompt serves as a starting point or context for the AI to understand the user's intent and generate relevant and coherent output accordingly.

In this section, we will go through how to construct a good prompt as well as what a prompt entails. We will then categorize these prompts into simple prompts and complex prompts. In general, simple prompts instruct the AI to generate one sound, while complex prompts guide the AI to generate a series of sounds.

The AI understands both natural language, which will be explored further in complex prompts, and a lot of music terminology. Sound Effects currently works best when prompts are written in English.

### Simple Prompts

Simple prompts are just that: they are straightforward, one-sided prompts where we try to get the AI to generate a single sound effect. This could be, for example, "person walking on grass" or "glass breaking." These types of prompts will generate a single type of sound effect with a few variations within the same generation or in subsequent generations. All in all, they are fairly simple.

However, there are ways to improve these prompts by adding a little more detail. Even if they are simple prompts, they can yield better output by enhancing the prompt itself. For example, something that sometimes works is adding details like "high-quality, professionally recorded footsteps on grass, sound effects foley." It may require some experimentation to find a good balance between being descriptive and keeping it brief enough for the AI to understand the prompt.

> Opening a creaking door

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_creaking-door_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_creaking-door_02.mp3`} />

> Chopping wood

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_chopping-wood_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_chopping-wood_02.mp3`} />

These types of prompts generate a single type of sound, but they might produce multiple variations of that sound within the same audio file. The AI is quite prone to doing that even without additional prompting, especially for short sounds like chopping wood, and also since that is a continuous action.

### Complex Prompts

When referring to complex prompts, we don't mean the length or the adjectives or adverbs used in the prompts. Although those can increase the complexity of the prompt, when we say complex prompts, we mean prompts where you have multiple sound effects or a sequence of sound effects happening in a specific order and the AI being able to replicate this.

> A man walks through a hallway and then falls down some stairs

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_walking+falling.mp3`} />

Let's take the prompt above as an example. The AI needs to understand both what a man walking through the hallway sounds like and what a man falling down some stairs sounds like. It needs to understand the sequence in which these two actions are supposed to occur based on how you wrote it and then combine these sounds to make both of them sound coherent and correct. This is what we mean by a complex prompt because it involves both an understanding of sound and an understanding of the natural language explaining what you want.

The AI can handle this; for example, the result for the example prompt above should ideally be accurate.

However, in general, this is much more complicated for the AI to do because it is more complex. For the best results, we recommend generating individual sound effects and then combining them in an audio editor of your choice, much like you would with a real production where you have individual sound effects that are then combined.

> A woman is singing in a church. Then someone coughs.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_singing+cough_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_singing+cough_02.mp3`} />

## Settings

Once you've set your prompt and know what you want to generate, you can adjust the settings. Set how long you want the generated audio to be and how influential the prompt should be to the output.

There are just two settings:

**Duration:** Determine how long your generations should be. Depending on what you set this as, you can get quite different results. For example, if I write "kick drum" and set the length to 11 seconds, I might get a full drum loop with a kick drum in it, but that might not be what I want. On the other hand, if I set the length to 1 second, I might just get a one-shot with a single instance of a kick drum.

**Prompt Influence:** Slide the scale to make your generation perfectly adhere to your prompt or allow for a little creativity. This setting ranges from giving the AI more creativity in how it interprets the prompt to telling the AI to be more strict in following the exact prompt that you've given.

## Sound Effects

Now that we are dealing with prompts, it is important to learn some terminology when it comes to audio to get the most out of the feature. You will have to prompt the AI with words and sentences in a way that it understands, and in this case, it understands both natural language and audio terminology.

There are many words that people working with audio know very well, and these are used in their daily vocabulary. However, for ordinary people, those words are completely foreign and might not mean anything. I will provide a short and very non-comprehensive list of some of the words you might want to test and that might be helpful to know.

**Foley:** The process of recreating and recording everyday sound effects like footsteps, movement, and object sounds in sync with the visuals of a film, TV show, or video game to enhance the audio quality and realism.

**Whoosh:** An effect that underscores movement, like a fist flying or a camera move. It's versatile and can range from fast, ghostly, slow-spinning, rhythmic, noisy, to tense.

**Impact:** The sound of an object making contact with another object or structure, like a book falling, a car crashing, or a mug shattering.

**Braam:** A big, brassy, cinematic hit that conveys something epic and grand is about to happen, commonly used in movie trailers.

**Glitch:** The sound of a malfunction, jittering, scratching, skipping, or moving erratically, used for transitions, logo reveals, or sci-fi soundscapes.

**Drone:** A continuous, textured sound that adds atmosphere and suspense, often used to underscore exploration or horror scenes.

Onomatopoeias like "oink," "meow," "roar," and "chirp" are also important sound effects that imitate natural sounds.

### Examples

> high-quality, wav, sound designed whoosh and braaam impact

In a case like this, it can sometimes be better to set the length instead of letting the AI decide. I know that I want a drawn-out "braaam" for this sound, so it will not be a very short sound. I will show you the results I get using both automatic and manual settings.

Duration set to 11 seconds:

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_braaam_set-duration_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_braaam_set-duration_02.mp3`} />

Duration set to automatic:

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_braaam_auto-duration_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_braaam_auto-duration_02.mp3`} />

> high-quality, wav, sound designed whoosh

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_whoosh_01.mp3`} />

> high-quality, wav, sound designed whoosh, aggressive

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_whoosh-aggressive_01.mp3`} />

> high-quality, wav, sound designed whoosh, aggressive, futuristic, electronic

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_whoosh-scifi_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fsfx_example_whoosh-scifi_02.mp3`} />

## Beyond Sound Effects

Even if the name of the feature is "Sound Effects," don't let that fool you. This is the perfect tool for sound designers, Foley artists, game developers, as well as producers and composers.

If you're a hip-hop producer looking for samples, whether new or more old school, and are tired of digging in crates or reusing the same overused samples that everyone else uses, this is the perfect tool for you. If you are an EDM producer looking for one-shots or other samples, it's perfect for you as well.

You can generate everything from individual one-shots to drum loops, instrumental loops, and unique new samples from big band sections and brass stabs—pretty much anything you can imagine.

I will go through a little bit of how to prompt this, but it involves a lot of trial and error to get what you want.

**Stem:** An individual track from a multitrack recording, such as isolated vocals, drums, or guitar.

**BPM:** Beats per minute, indicating the tempo of a piece of music.

**Key:** The scale in which a piece of music is set, such as C major or A minor.

**Loop:** A repeating section of sound material, commonly used in electronic music.

**Sample:** A portion of sound, typically a recording, used in musical compositions.

**One-shot:** A single, non-repeating sound or sample, often used in percussion.

These terms are, of course, just scratching the surface, as there are concepts such as synth pads, basslines, chord progressions, arpeggios, and many other musical terms that can be good to learn. However, the above can be a good starting point for generating musical material.

### Examples

You can create individual one-shot drum sounds.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_one-shot-kick_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_one-shot-snare_01.mp3`} />

> 90s hip-hop beat, drum loop sample

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_90s-drum-loop_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_90s-drum-loop_02.mp3`} />

> Old-school funky bassline sample, stem, 88 BPM in F# minor

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_funky_bassline_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_funky_bassline_02.mp3`} />

> Old-school funky brass section from an old vinyl sample, stem, 88 BPM in F# minor

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_funky-bigband-brass_01.mp3`} />

> Old-school funky brass stabs from an old vinyl sample, stem, 88 BPM in F# minor

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_funky-bigband-brass_02.mp3`} />

I do not remember the exact prompts for these, but they sounded good, so I wanted to include them. They showcase some other genres.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_synth-pulse-underscore_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_guitar-loop_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_dnd-drum-loop_01.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_full-drum-loop+instruments_01.mp3`} />

Then, you can, of course, take different types of samples and combine them to create full music. Anyone who's ever worked as a producer, especially those familiar with old-school hip-hop where sampling old tracks and editing is the essence of the genre, will find this a treasure trove of new samples to use.

A professional producer could create something amazing with these types of samples, and we are very excited to see what might be developed. Here is a quick demo to show what just a few generations and a couple of minutes of work can achieve.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_track_01_90s-drum-loop.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_track_01_funky_bassline.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_track_01_funky_brassline.mp3`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_track_01_string-stabs.mp3`} />

This is the final product.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fsound-effects%2Faudio%2Fmusic_example_track_01_combined-simple.mp3`} />


# Model Selection



As of September 2024, ElevenLabs offers two families of models: standard (high-quality) models and Turbo models, which are optimized for low latency. Each family includes both English-only and multilingual models, tailored for specific use cases with strengths in either speed, accuracy, or language diversity.

*   **Standard models** (Multilingual v2, Multilingual v1, English v1) are optimized for quality and accuracy, ideal for content creation. These models offer the best quality and stability but have higher latency.
*   **Turbo models** (Turbo v2, Turbo v2.5) are designed for low-latency applications like real-time conversational AI. They deliver great performance with faster processing speeds, though with a slight trade-off in accuracy and stability.

If you want to find more detailed specifications about which languages each model offers, you can find all that information in our help article [here](https://help.elevenlabs.io/hc/en-us/articles/17883183930129-What-models-do-you-offer-and-what-is-the-difference-between-them-).

For advice on how to deal with issues that might arise, please see our guide to [troubleshooting](/product/troubleshooting/overview).

<Frame caption="Voice Models">
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_models.png" />
</Frame>

## **Standard Models**

**Eleven Multilingual v2**

Our most advanced speech synthesis model, Multilingual v2, offers high stability, diverse language support, and exceptional accuracy in 29 languages. While slower than the Turbo models, it delivers more lifelike speech, making it ideal for content creation such as voiceovers, audiobooks, and post-production.

**Important notes**: The accuracy of this model depends heavily on the quality of the input samples. Lower-quality samples can introduce errors, which the AI might attempt to replicate. For the best results, use high-quality, consistent voice samples, especially when trying to preserve accents or tonal details across languages.

*   Best quality
*   Unparalleled accuracy
*   More stable
*   Higher latency

**Eleven English v1**

Our very first model, English v1, laid the groundwork for future advancements. While still functional, it is now outclassed by Multilingual v2 (for content creation) and Turbo v2.5 (for low-latency applications). We recommend using our newer models for better quality and speed.

**Eleven Multilingual v1**

Multilingual v1 was our first attempt at generating speech in multiple languages, but it is now considered experimental and has been surpassed by Multilingual v2 and Turbo v2.5. We recommend avoiding this model for production use due to its limitations and lower accuracy.

## **Turbo Models**

**Eleven Turbo v2.5**

Turbo v2.5 generates speech in 32 languages with low latency, optimized for real-time conversational AI use cases. This model is 300% faster than Multilingual v2 and now supports new languages such as Vietnamese, Hungarian, and Norwegian. It is best for developers requiring rapid, natural speech across multiple languages, but it lacks the stylistic range of Multilingual v2.

Latency is as low as 300ms, making it ideal for real-time interactions.

*   Great quality
*   High accuracy with Professional Voice Clones
*   Slightly less stable
*   Optimized for low latency

**Eleven Turbo v2**

A low-latency, English-only model optimized for conversational applications. Turbo v2 is similar in performance to Turbo v2.5 but focused exclusively on English, making it ideal for English-only use cases where speed is critical.

*   Great quality
*   High accuracy with Professional Voice Clones
*   Slightly less stable
*   Optimized for low latency


# Overview

A guide on how to generate voiceovers using your voice on ElevenLabs.

Our Text to Speech technology is the backbone of ElevenLabs. Many of the features we offer are built around this technology, and numerous excellent services around the web are powered by our technology, where the highest quality AI-generated speech is needed.

The speech model takes text and converts it into extremely realistic speech. On the surface, it’s a fairly simple concept, but the execution is anything but. There are a few things to keep in mind to achieve the best possible results, and we will try to cover most of it.

We are constantly working on improving our service and technology, adding new features and settings. Therefore, it can be helpful to check back periodically to ensure you have the latest information and are following the most recent guidelines.

There are two main factors that we emphasize as being of utmost importance to ensure the best possible experience when using our Text to Speech.

<Tabs>
  <Tab title="Voice Selection">
    <Frame caption="Voice Selection Dropdown">
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_voices.png" />
    </Frame>
  </Tab>

  <Tab title="Model Selection">
    <Frame caption="Model Selection">
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_models.png" />
    </Frame>
  </Tab>

  <Tab title="Voice Settings">
    <Frame caption="Voice Selection">
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_settings.png" />
    </Frame>
  </Tab>
</Tabs>

Getting yourself familiar with these different settings and options will be very important in getting the best possible result. For Text to Speech, there are three main selections you need to make.

<AccordionGroup>
  <Accordion title="Voices">
    We offer many types of voices, including Default Voices that have been specfically curated to be the highest quality; completely synthetic voices created using our Voice Design tool; you can create your own collection of cloned voices using our two technologies: Instant Voice Clones and Professional Voice Clones; browse through our voice library to find the perfect voice for your production.

    Not all voices are equal, and a lot depends on the source audio used to create that voice. Some voices will perform better than others, while some will be more stable than others. Additionally, certain voices will be more easily cloned by the AI than others, and some voices may work better with one model and one language compared to another. All of these factors are important to consider when selecting your voice.

    <Card title="Read more..." icon="book" horizontal="true" href="/product/speech-synthesis/voice-selection" />
  </Accordion>

  <Accordion title="Models">
    As of September 2024, ElevenLabs offers two families of models: standard (high-quality) models and Turbo models, which are optimized for low latency. Each family includes both English-only and multilingual models, tailored for specific use cases with strengths in either speed, accuracy, or language diversity.

    *   **Standard models** (Multilingual v2, Multilingual v1, English v1) are optimized for quality and accuracy, ideal for content creation. These models offer the best quality and stability but have higher latency.
    *   **Turbo models** (Turbo v2, Turbo v2.5) are designed for low-latency applications like real-time conversational AI. They deliver great performance with faster processing speeds, though with a slight trade-off in accuracy and stability.

    If you want to find more detailed specifications about which languages each model offers, you can find all that information in our help article [here](https://help.elevenlabs.io/hc/en-us/articles/17883183930129-What-models-do-you-offer-and-what-is-the-difference-between-them-).

    For advice on how to deal with issues that might arise, please see our [guide to troubleshooting.]()

    <Card title="Read more..." icon="book" horizontal="true" href="/product/speech-synthesis/models" />
  </Accordion>

  <Accordion title="Settings">
    Our users have found different workflows that work for them. The one you'll see most often is setting stability around 50 and similarity near 75, with minimal changes thereafter. Of course, this all depends on the original voice and the style of performance you're aiming for.

    It's important to note that the AI is non-deterministic; setting the sliders to specific values won't guarantee the same results every time. Instead, the sliders function more as a range, determining how wide the randomization can be between each generation. Setting stability low means a wider range of randomization, often resulting in a more emotive performance, but this is also highly dependent on the voice itself.

    For a more lively and dramatic performance, it is recommended to set the stability slider lower and generate a few times until you find a performance you like.

    On the other hand, if you want a more serious performance, even bordering on monotone on very high values, it is recommended to set the stability slider higher. And since it's more consistent and stable, you usually don't need to do as many generations to get what you are looking for. Experiment to find what works best for you!

    <Card title="Read more..." icon="book" horizontal="true" href="/product/speech-synthesis/voice-settings" />
  </Accordion>
</AccordionGroup>

## Good to know

<AccordionGroup>
  <Accordion title="Good input equals good output">
    The first factor, and one of the most important, is that good, high-quality, and consistent input will result in good, high-quality, and consistent output.

    If you provide the AI with audio that is less than ideal—for example, audio with a lot of noise, reverb on clear speech, multiple speakers, or inconsistency in volume or performance and delivery—the AI will become more unstable, and the output will be more unpredictable.

    If you plan on cloning your own voice, we strongly recommend that you go through our guidelines in the documentation for creating proper voice clones, as this will provide you with the best possible foundation to start from. Even if you intend to use only Instant Voice Clones, it is advisable to read the Professional Voice Cloning section as well. This section contains valuable information about creating voice clones, even though the requirements for these two technologies are slightly different.
  </Accordion>

  <Accordion title="Use the right voice">
    The second factor to consider is that the voice you select will have a tremendous effect on the output. Not only, as mentioned in the first factor, is the quality and consistency of the samples used to create that specific clone extremely important, but also the language and tonality of the voice.

    If you want a voice that sounds happy and cheerful, you should use a voice that has been cloned using happy and cheerful samples. Conversely, if you desire a voice that sounds introspective and brooding, you should select a voice with those characteristics.

    However, it is also crucial to use a voice that has been trained in the correct language. For example, all of the professional voice clones we offer as default voices are English voices and have been trained on English samples. Therefore, if you have them speak other languages, their performance in those languages can be unpredictable. It is essential to use a voice that has been cloned from samples where the voice was speaking the language you want the AI to then speak.
  </Accordion>

  <Accordion title="Use proper formatting">
    This may seem slightly trivial, but it can make a big difference. The AI tries to understand how to read something based on the context of the text itself, which means not only the words used but also how they are put together, how punctuation is applied, the grammar, and the general formatting of the text.

    This can have a small but impactful influence on the AI's delivery. If you were to misspell a word, the AI won't correct it and will try to read it as written.
  </Accordion>

  <Accordion title="Nondeterministic">
    The settings of the AI are nondeterministic, meaning that even with the same initial conditions (voice, settings, model), it will give you slightly different output, similar to how a voice actor will deliver a slightly different performance each time.

    This variability can be due to various factors, such as the options mentioned earlier: voice, settings, model. Generally, the breadth of that variability can be controlled by the stability slider. A lower stability setting means a wider range of variability between generations, but it also introduces inter-generational variability, where the AI can be a bit more performative.

    A wider variability can often be desirable, as setting the stability too high can make certain voices sound monotone as it does give the AI the same leeway to generate more variable content. However, setting the stability too low can also introduce other issues where the generations become unstable, especially with certain voices that might have used less-than-ideal audio for the cloning process.

    The default setting of 50 is generally a great starting point for most applications.
  </Accordion>
</AccordionGroup>


# Prompting

Effective techniques to guide ElevenLabs AI in adding pauses, conveying emotions, and pacing the speech.

## Pause

There are a few ways to introduce a pause or break and influence the rhythm and cadence of the speaker. The most consistent way is programmatically using the syntax `<break time="1.5s" />`. This will create an exact and natural pause in the speech. It is not just added silence between words, but the AI has an actual understanding of this syntax and will add a natural pause.

An example could look like this:

```
"Give me one second to think about it." <break time="1.0s" /> "Yes, that would work."
```

Break time should be described in seconds, and the AI can handle pauses of up to 3 seconds in length and can be used in Speech Synthesis and via the API. It is not yet available for Projects.

However, since this is more than just inserted silence, how the AI handles these pauses can vary. As usual, the voice used plays a pivotal role in the output. Some voices, for example, voices trained on data with "uh"s and "ah"s in them, have been shown to sometimes insert those vocal mannerisms during the pauses like a real speaker might. This is more prone to happen if you add a break tag at the very start or very end of your text.

<Info>Please avoid using an excessive number of break tags as that has shown to potentially cause some instability in the AI. The speech of the AI might start speeding up and become very fast, or it might introduce more noise in the audio and a few other strange artifacts. We are working on resolving this.</Info>

### Alternatives

<u>These options are inconsistent and might not always work</u>. We recommend using the syntax above for consistency.

One trick that seems to provide the most consistence output - sans the above option - is a simple dash `-` or the em-dash `—`. You can even add multiple dashes such as `-- --` for a longer pause.

```
"It - is - getting late."
```

Ellipsis `...` can <u>sometimes</u> also work to add a pause between words but usually also adds some "hesitation" or "nervousness" to the voice that might not always fit.

```
I... yeah, I guess so..."
```

## Pronunciation

<u>This feature is currently only supported by the "Eleven English V1" and "Eleven Turbo V2" models</u>.

In certain instances, you may want the model to pronounce a word, name, or phrase in a specific way. Pronunciation can be specified using standardised pronunciation alphabets. Currently we support the International Phonetic Alphabet (IPA) and the CMU Arpabet. Pronunciations are specified by wrapping words using the Speech Synthesis Markup Language (SSML) phoneme tag.

To use this feature, you need to wrap the desired word or phrase in the `<phoneme alphabet="ipa" ph="your-IPA-Pronunciation-here">word</phoneme>` tag for IPA, or `<phoneme alphabet="cmu-arpabet" ph="your-CMU-pronunciation-here">word</phoneme>` tag for CMU Arpabet. Replace `"your-IPA-Pronunciation-here"` or `"your-CMU-pronunciation-here"` with the desired IPA or CMU Arpabet pronunciation.

An example for IPA:

```
<phoneme alphabet="ipa" ph="ˈæktʃuəli">actually</phoneme>
```

An example for CMU Arpabet:

```
<phoneme alphabet="cmu-arpabet" ph="AE K CH UW AH L IY">actually</phoneme>
```

It is important to note that this only works per word. Meaning that if you, for example, have a name with a first and last name that you want to be pronounced a certain way, you will have to create the pronunciation for each word individually.

English is a lexical stress language, which means that within multi-syllable words, some syllables are emphasized more than others. The relative salience of each syllable is crucial for proper pronunciation and meaning distinctions. So, it is very important to remember to include the lexical stress when writing both IPA and ARPAbet as otherwise, the outcome might not be optimal.

Take the word "talon", for example.

Incorrect:

```
<phoneme alphabet="cmu-arpabet" ph="T AE L AH N">talon</phoneme>
```

Correct:

```
<phoneme alphabet="cmu-arpabet" ph="T AE1 L AH0 N">talon</phoneme>
```

The first example might switch between putting the primary emphasis on AE and AH, while the second example will always be pronounced reliably with the emphasis on AE and no stress on AH.

If you write it as:

```
<phoneme alphabet="cmu-arpabet" ph="T AE0 L AH1 N">talon</phoneme>
```

It will always put emphasis on AH instead of AE.

<Info>With the current implementation, we recommend using the CMU ARPAbet as it seems to be a bit more consistent and predictable with the current iteration of AI models. Some people get excellent results with IPA, but we have noticed that ARPAbet seems to work better with the current AI and be more consistent for a lot of users. However, we are working on improving this.</Info>

## Emotion

If you want the AI to express a specific emotion, the best approach is to write in a style similar to that of a book. To find good prompts to use, you can flip through some books and identify words and phrases that convey the desired emotion.

For instance, you can use dialogue tags to express emotions, such as `he said, confused`, or `he shouted angrily`. These types of prompts will help the AI understand the desired emotional tone and try to generate a voiceover that accurately reflects it. With this approach, you can create highly customized voiceovers that are perfect for a variety of applications.

```
"Are you sure about that?" he said, confused.
"Don’t test me!" he shouted angrily.
```

You will also have to somehow remove the prompt as the AI will read exactly what you give it. The AI can also sometimes infer the intended emotion from the text’s context, even without the use of tags.

```
"That is funny!"
"You think so?"
```

This is not always perfect since you are relying on the AI discretion to understand if something is sarcastic, funny, or just plain from the context of the text.

## Pacing

Based on varying user feedback and test results, it's been theorized that using a singular long sample for voice cloning has brought more success for some, compared to using multiple smaller samples. The current theory is that the AI stitches these samples together without any separation, causing pacing issues and faster speech. This is likely why some people have reported fast-talking clones.

To control the pacing of the speaker, you can use the same approach as in emotion, where you write in a style similar to that of a book. While it's not a perfect solution, it can help improve the pacing and ensure that the AI generates a voiceover at the right speed. With this technique, you can create high-quality voiceovers that are both customized and easy to listen to.

```
"I wish you were right, I truly do, but you're not," he said slowly.
```


# Overview

A guide on using our voice changer tool for the most natural-sounding speech-to-speech conversion

<iframe width="100%" height="400" src="https://www.youtube.com/embed/GBdOQClluIA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

Voice changer (previously Speech-to-Speech) allows you to convert one voice (source voice) into another (cloned voice) while preserving the tone and delivery of the original voice.

The possibilities are endless! Voice changer can be used to complement Text-to-Speech (TTS) by fixing pronunciation errors or infusing that special performance you've been wanting to exude. Voice changer is especially useful for emulating those subtle, idiosyncratic characteristics of the voice that give a more emotive and human feel. Some key features include:

*   **Greater accuracy with whispering**
*   **The ability to create audible sighs, laughs, or cries**
*   **Greatly improved detection of tone and emotion**
*   **Accurately follows the input speaking cadence**
*   **Language/accent retention**

**Source audio (Brian):**

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fspeech-synthesis%2Faudio%2Fsts_example_1_source_brian.mp3`} />

**Output audio (Lily):**

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Example&small=true&preview=true&audioSrc=https%3A%2F%2Fgithub.com%2Felevenlabs%2Felevenlabs-docs%2Fraw%2Fmain%2Fproduct%2Fspeech-synthesis%2Faudio%2Fsts_example_1_clone_lily.mp3`} />

## Record or Upload

Audio can be uploaded either directly with an audio file, or spoken live through a microphone. The audio file must be less than 50mb in size, and either the audio file or your live recording cannot exceed 5 minutes in length. This is consistent among all subscription tiers, and is to ensure a stable output. If you have material longer than 5 minutes, we recommend breaking it up into smaller sections and generating them separately. Additionally, if your file size is too large, you may need to compress/convert it to an mp3.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/STS_Audio_Box1.png" />

To upload, either click the "Upload Audio" button in the audio box, or drag and drop your audio file directly onto it.

To record, first press the "Record Audio" button in the audio box, and then once you are ready to begin recording, press the Microphone button to start. After you're finished recording, press the "Stop" button.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/STS_Audio_Box2.png" />

You will then see the audio file of this recording, which you can then playback to listen to - this is helpful to determine if you are happy with your performance/recording, or if you notice background noise that may inhibit the AI's ability to produce a clean output. The character cost will be displayed on the bottom-left corner, and you will not be charged this quota for recording anything - only when you press "Generate". **The cost for a voice changer generation is solely duration-based at 1000 characters per minute.**

If you need to re-do the recording, simply press the trash icon to remove it and start over. When you're happy with your recording, you can select any voice or model you prefer, and you do not need to re-record the input audio.

## Models

Voice changer is now available for all 29 languages currently supported by the Multilingual v2 model. The English v2 model is also available for specifically English speech, but the Multilingual v2 model generally performs better, even for English audio.

<Frame>
  <img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/STS_Models3.png" />
</Frame>

The settings for each model are consistent with the settings in our TTS m2 models. If the input audio is very expressive and energetic with lots of dynamic range, it's best to keep Style all the way down to 0% and Stability all the up to 100% - we don't want to inhibit the performance with the AI's interpretation, so this will give the most consistent and stable results.

## Other Tips and Tricks

Voice changer is exceptional in **preserving accents** and **natural speech cadences** with many different output voices you desire. For example, if you decide to upload an audio sample with a voice that is native to Portuguese, your output voices will adopt that same language and accent. Again, the input sample is the most important factor, and this is the data that voice changer will work with. If a British voice is chosen (let's take our Default voice "George" as an example), but your recorded voice is an American accent, the final output will be George's voice with an American accent.

When recording your voice, ensure that the input gain of your microphone is suitable. A quiet recording may make it more difficult for the AI to pick up what is being said, while a louder recording could produce audio clipping which is also undesirable. Additionally, try your best to **prevent background noise** from being present in the recording, as the AI will pick up everything, and it may try to "voice" any miscellaneous noises that it hears.

**Optional:** If you're recording in a noisy environment, you may want to use our [Voice Isolator tool](https://elevenlabs.io/app/voice-isolator) on the recording. You can then add the edited audio file to voice changer as an upload.

Be expressive! Whether you're shouting, crying, laughing, or anything in between, voice changer will copy that performance to a tee. We're constantly striving to increase the realism of AI through many different features, and voice changer is our most useful tool in this regard. You can get really creative here!


# Voice Selection



We offer many types of voices, including Default Voices that have been specifically curated to be of the highest quality; completely synthetic voices created using our Voice Design tool; and the option to create your own collection of cloned voices using our two technologies: Instant Voice Clones and Professional Voice Clones. You can browse through our voice library to find the perfect voice for your production.

Not all voices are equal, and a lot depends on the source audio used to create that voice. Some voices will perform better than others, while some will be more stable than others. Additionally, certain voices will be more easily cloned by the AI than others, and some voices may work better with one model and one language compared to another. All of these factors are important to consider when selecting your voice.

<Frame caption="Voice Selection Dropdown">
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_voices.png" />
</Frame>

## Default Voices

Default voices are a curated set of voices optimized for core use cases and available to all ElevenLabs users by default. They are designed to ensure long-term availability, consistent quality, and priority support for new model developments.

These voices are crafted through multi-year partnerships with voice actors, making them reliable for extended use.

## Clone Voices

Cloned voices are created using either Instant Voice Cloning or Professional Voice Cloning.

*   **Instant Voice Cloning** allows you to clone a voice using short audio samples, providing quick results but with less fidelity. This method is suitable for creating a basic clone without extensive training.

*   **Professional Voice Cloning** involves training a model on larger datasets of a specific speaker's voice, resulting in a more accurate and realistic clone. This method is available for users on the Creator plan or higher and requires more time and resources.

Cloned voices are private and not shared publicly unless specifically whitelisted or shared through the Voice Library.

## Synthetic Voices

Synthetic voices are generated by AI using the Voice Design tool. They are created from text prompts and offer flexibility in attributes like gender, age, and accent. These voices are not based on real human voices and can be used to fill gaps when specific voices aren't available in the Voice Library. Synthetic voices cannot be shared with others and are available to all users for creating unique voice outputs.

## Voice Library

The Voice Library is a marketplace where the community can share their Professional Voice Clones for others to use. It offers a wide variety of voices contributed by users, allowing you to explore and utilize different voice options. You can search for voices using filters like language, accent, and more to find the ideal voice for your needs.


# Voice Settings



Our users have found different workflows that work for them. The one you'll see most often is setting stability around 50 and similarity near 75, with minimal changes thereafter. Of course, this all depends on the original voice and the style of performance you're aiming for.

It's important to note that the AI is non-deterministic; setting the sliders to specific values won't guarantee the same results every time. Instead, the sliders function more as a range, determining how wide the randomization can be between each generation. Setting stability low means a wider range of randomization, often resulting in a more emotive performance, but this is also highly dependent on the voice itself.

For a more lively and dramatic performance, it is recommended to set the stability slider lower and generate a few times until you find a performance you like.

On the other hand, if you want a more serious performance, even bordering on monotone at very high values, it is recommended to set the stability slider higher. Since it's more consistent and stable, you usually don't need to do as many generations to get what you are looking for. Experiment to find what works best for you!

<Frame caption="Voice Settings">
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/speech-synthesis/images/tts_settings.png" />
</Frame>

## Stability

The stability slider determines how stable the voice is and the randomness between each generation. Lowering this slider introduces a broader emotional range for the voice. As mentioned before, this is also influenced heavily by the original voice. Setting the slider too low may result in odd performances that are overly random and cause the character to speak too quickly. On the other hand, setting it too high can lead to a monotonous voice with limited emotion.

## Similarity

The similarity slider dictates how closely the AI should adhere to the original voice when attempting to replicate it. If the original audio is of poor quality and the similarity slider is set too high, the AI may reproduce artifacts or background noise when trying to mimic the voice if those were present in the original recording.

## Style Exaggeration

With the introduction of the newer models, we also added a style exaggeration setting. This setting attempts to amplify the style of the original speaker. It does consume additional computational resources and might increase latency if set to anything other than 0. It's important to note that using this setting has shown to make the model slightly less stable, as it strives to emphasize and imitate the style of the original voice.

In general, we recommend keeping this setting at 0 at all times.

## Speaker Boost

This is another setting that was introduced in the new models. The setting itself is quite self-explanatory – it boosts the similarity to the original speaker. However, using this setting requires a slightly higher computational load, which in turn increases latency. The differences introduced by this setting are generally rather subtle.


# Overview

General troubleshooting guide and overview for some issues we've seen.

AI is a highly advanced field of technology and can, at times, be unpredictable as the output is based on the input and then interpreted by the AI. We have tried to minimize the unpredictability as much as possible and keep adding features and improvements that make it more predictable and controllable. However, there are still a few things you need to be mindful of, and this applies to all generative AI.

In this section, we will go through some of the issues we've encountered and that have been reported by users. Just because they are mentioned here doesn't mean that you will experience these issues, and in many cases, there are things you can do to prevent them from happening.

## Free regenerations

If you're using Speech Synthesis via the website, you can regenerate your audio up to twice for free in the following circumstances:

*   The prompt (for text-to-speech) or file (for voice changer), voice and model remain the same.  You can change the voice setting sliders.
*   The first generation was made less than two hours ago.
*   You haven't refreshed the page since generating the original audio.

If free regenerations are available, you will see "Regenerate speech", and the number of free regenerations remaining will be displayed if you hover over the "Regenerate speech" button:

Once your free regenerations have been used, the button will return to "Generate speech", and the number of credits that will be used for the generation will be displayed.

Free regenerations are only available in Speech Synthesis via the website.  They are not available in Projects, or Speech Synthesis via the API.

## General Troubleshooting

### Inconsistency in volume and quality

If your audio output is inconsistent or changes in volume or tone throughout, the issue often stems from the training audio, for example, if the training audio is inconsistent with a high dynamic range.

To fix this, use compression to reduce the dynamic range, ensuring your audio stays steady. Aim for an RMS (Root Mean Square) level between **-23 dB and -18 dB** and keep the true peak below **-3 dB**. RMS measures the average energy of your audio, while dB (decibels) indicates the loudness.

Dynamic range is the difference between the quietest and loudest parts of your audio, and compression helps to balance this range by reducing the volume of the louder parts. RMS, or Root Mean Square, is a statistical measure of the magnitude of a varying quantity. In audio terms, it represents the average power or energy of the audio signal. Maintaining an appropriate RMS level ensures that your audio is neither too quiet nor too loud, providing a consistent listening experience.

However, there are other reasons why this might happen. The speaker might go from whispering to shouting or from talking close to the mic to far away from the mic, resulting in very varying volume or inconsistent tonality. These types of issues can also occur if the input audio contains music, noise, rumble, or pops/plosives. These noises or sudden bursts of energy or consistent low-frequency energy can make the AI less stable. You should only include the actual voice you want to clone in the audio.

In general, for consistency, you should use around 1 to 2 minutes of audio when [Instant Voice Cloning](https://elevenlabs.io/docs/voices/voice-lab/instant-voice-cloning). This audio should be very consistent across all aspects such as tonality, performance, accent, quality, and so on, if you want the output to be consistent. Using more audio than that can make the AI too variable, which can cause inconsistency between generations.

For [Professional Voice Cloning](https://elevenlabs.io/docs/voices/voice-lab/professional-voice-cloning), we recommend at the very least 30 minutes of audio and suggest between 2 to 3 hours of audio for the best results. Keep in mind, the audio needs to be consistent throughout for the best result. You can find more in-depth information in the guide specifically about cloning.

If you clone a voice properly, one that is consistent throughout, of high quality, properly recorded without background noise or multiple speakers, and if you follow the guidelines, you should be able to get a very good and consistent clone. It might require a bit experimenting if you don't get it right the first time.

To minimize these issues if they do show up, consider breaking your text into smaller segments. This approach helps maintain a consistent volume and reduces the likelihood of degradation over longer audio generations. Utilizing our Projects feature can also be beneficial, as it allows you to generate several smaller audio segments simultaneously, ensuring better quality and consistency.

**Quick Tips:**

*   **Apply Compression:** Smooth out volume changes for a more uniform sound.
*   **Normalize Levels:** Ensure your audio stays within the recommended RMS and dB ranges.
*   **Clean Up Noise:** Remove background sounds like rumble or pops to enhance clarity.
*   **Projects:** Use our Projects feature to ensure more stable audio for long-form content.

We recommend that you read our guides on how to get the best possible [Instant Voice Clone](https://elevenlabs.io/docs/voices/voice-lab/instant-voice-cloning) and [Professional Voice Clone](https://elevenlabs.io/docs/voices/voice-lab/professional-voice-cloning) as they contain a lot of advice and best practices.

### Mispronunciation

The multilingual models may rarely mispronounce certain words, even in English. So far, the trigger seems somewhat arbitrary, but it appears to be voice and text-dependent. It seems to happen more often with certain voices and text than others, especially if you use words that appear in other languages as well.

The best way to deal with this is to use the [Projects](https://docs.elevenlabs.io/projects/overview) feature, which seems to minimize the issue as it is more prevalent across longer sections of text when using Speech Synthesis. It will not completely remove the issue, but it will hopefully help both avoid it and make it easier to just regenerate the specific section affected without redoing the whole text.

As with the above issue of [inconsistency](https://docs.elevenlabs.io/troubleshooting/overview#inconsistency), this issue also seems to be minimized by using a properly cloned voice, cloned in the languages you want the AI to speak.

When using our Projects feature, you may want to specify the pronunciation of certain words, such as characters and brand names, or to specify how acronyms should be read.  For more information on how to do this, please see the [Pronunciation Dictionary section](https://elevenlabs.io/docs/projects/overview#pronunciation-dictionaries) of our guide to Projects.

### Language Switching and Accent Drift

The AI can sometimes switch languages or accents throughout a single generation, especially if that generation is longer in length - very similar to the [mispronunciation](https://docs.elevenlabs.io/troubleshooting/overview#mispronunciation) issue above. This is also something we're working on fixing, hopefully with the next iteration, as there's not too much you can do right now. Using a proper clone, either an [Instant Voice Clone](https://docs.elevenlabs.io/voice-lab/instant-voice-cloning) or a [Professional Voice Clone](https://elevenlabs.io/docs/voices/voice-lab/professional-voice-cloning), trained on high-quality, consistent audio in the language you want the AI to speak should again help mitigate most of this, especially when paired with [Projects.](https://docs.elevenlabs.io/projects/overview)

The most important thing to remember is that Default and generated voices are English and might have an English accent when used to generate other languages. This means that they may not have the proper pronunciation and might be more prone to switching languages and accent. The best approach would be to clone a voice speaking the language you want the AI to speak with the accent you want. This will provide the most context for the AI to understand how to perform a passage and should minimize language switching.

There is currently no way to select the language you want the AI to speak. Instead, the way you "select" the language is by writing in the language you want the AI to speak. If you are using a voice that is not native to the language - for example, one of the pre-made voices since they are in English - the AI might have a slight English accent when speaking other languages.

To get optimal results, we recommend cloning a voice that speaks the original language with the correct accent. This is especially important when dealing with languages that are very similar and share a lot of common words. This ensures that the AI has the most information to understand which pronunciation and language it should choose.

Another important point to note is that the AI usually begins with one accent and can gradually shift over longer segments of text, which generally means text longer than a few hundred characters. We highly recommend using [Projects](https://elevenlabs.io/docs/projects/overview) feature to avoid many of these issues.  When using Text-to-Speech, we typically see the best results when generations are shorter than 800-900 characters.

### Mispronounced numbers, symbols or acronyms?

The multilingual models may mispronounce certain numbers, symbols and acronyms. For instance, 1, 2, 3 might be pronounced as "one," "two," "three." Therefore, if you need them to be pronounced in another language, it is recommended to write them out in words, exactly as you would like the AI to deliver them.

### Corrupt Speech

This is a very rare issue, but some users have encountered it. It seems to be a bit arbitrary when this happens, but sometimes the AI produces speech that is warped, sounding very muffled and strange. It sounds like it has some sort of effect on it. Unfortunately, we do not have any suggestions for it as we have not been able to replicate the issue or find any cause for it. If this happens, the best course of action is to just regenerate the section, and it should resolve itself, as it is very rare.

### Audio degrading over longer generations

We are aware that some voices have a tendency to degrade during longer audio generations, and our team is working hard to develop the technology to improve upon this. This issue is more prominent in the experimental Multilingual v1 model, which we no longer recommend using, unless it is required for a specific voice.

If you are encountering issues with the audio degrading, we recommend breaking down the text into shorter sections, preferably below 800 characters, as this can help maintain better quality.

Some voices are more prone to this issue than others.  If you're using cloned voices, the quality of the samples used is very important to the final output. Noise and other artifacts tend to be amplified during long generations.

Both stability and similarity can change how the voice acts as well as how prominent the artifacts are. Hovering over the `!` next to each side of the sliders will reveal some more information.

### Style Exaggeration

For some voices, this voice setting can lead to instability, including inconsistent speed, mispronunciation and the addition of extra sounds. We recommend keeping this setting at 0, especially if you find you are experiencing these issues in your generated audio.

## Models

### Turbo v2.5

Turbo v2.5 is optimised for low latency and should be used when this is the most important concern, for example, real-time conversational AI.
Where quality and accuracy are the primary concern, for example, for content creation, we recommend using our Multilingual v2 model.

### Multilingual v1

The multilingual model is generally only recommended for old PVC clones that require it, as it does exhibit a few issues that are not present in the newer models.

During generation, the audio may change in tone, quality, introduce noise and distortion, and the voice may transition from male to female or start whispering, and more. The prominence of these issues largely depends on the model and voice used.

## Projects

Projects is one of the world's most advanced workflows for creating long-form content using AI. Even despite its high complexity, there are very few issues with Projects, and in general, it works fantastically well if you use a proper voice paired with the appropriate model.  For more information, see our [Projects documentation.](https://elevenlabs.io/docs/projects/overview)

### Import Function

The import function will do its best to try and import the file you give it to the website. However, since there are so many variables related to websites and how a book can be formatted, including the presence of images, you should always double-check to ensure that everything is imported correctly.

One such issue you might encounter is when importing a book where each chapter starts with an image as the first letter. This can be very confusing for the AI, as it will not be able to extrapolate the letter. Therefore, you will have to add that letter to each chapter.

If something is imported as a single long paragraph instead of being split where a new line break starts, something is wrong, and it might not work properly. It should follow the same structure as the original book. If that doesn't work, you can try copying and pasting. If that also doesn't work, there might be something wrong with how the text is presented, and this book might not work without first converting it to another format or rewriting it fully. This is very unusual, but it's essential to keep in mind.

EPUB is the best file format to use to create your project.  If the EPUB is well-structured and correctly formatted, it will automatically split each chapter into its own chapter in Projects, making it very easy to navigate. To format your EPUB so that Projects can recognize your chapters, you need to make sure that each chapter heading is formatted as "Heading 1".

### Glitches between paragraphs

On rare occasions, you might encounter glitches or sharp breaths between paragraphs, which you might not experience with Speech Synthesis, as they operate differently. Generally, this issue is not extremely disruptive and is relatively rare, but we are actively working on resolving it. At the moment, there is no straightforward solution to completely avoid this problem. If you do happen to encounter an issue like this, we recommend regenerating the paragraph immediately before the issue occurs. These issues tend to occur at the end of paragraphs rather than at the beginning. So, if you hear a problem between two paragraphs, it's usually the preceding paragraph that is the cause of the issue.

## Error Messages

Here are some error messages you might encounter, and how to resolve them.

### The selected model can not be used for text-to-speech.

This error sometimes occurs when switching between speech-to-speech and text-to-speech, if the model does not switch correctly.  You might also see the message "The selected model can not be used for voice conversion".

You should be able to resolve this issue by selecting the model you want to use. If this does not resolve it, you might need to select a different model, then switch back to the model you want to use.

### Oops, something went wrong!

This error indicates a client-side error, which usually indicates an issue with your device or browser.

This issue can usually be resolved by clicking "Try again" or refreshing the page.  If this does not resolve the issue, please try clearing your browser's cache and cookies.

This error can also be caused by use of browser-based translation tools like Google Translate. While we work on a solution for this, you can still use the website by temporarily pausing the translation feature.

If you're still seeing this message after trying these suggestions, please [reach our to our support team.](https://help.elevenlabs.io/hc/en-us/requests/new?ticket_form_id=13145996177937)

### API Error Code 400 or 401

These error codes can have a number of causes.  The response message will indicate the cause of the error.

#### max\_character\_limit\_exceeded

The maximum number of characters per request depends on the model.

*   Turbo v2.5 - up to 40,000 characters (\~40 minutes of audio)
*   Turbo v2 - up to 30,000 characters (\~30 minutes of audio)
*   Multilingual v1 and v2 - up to 10,000 characters (\~10 minutes of audio)
*   English v1 and v2 - up to 10,000 characters (\~10 minutes of audio)

#### invalid\_api\_key

This means that you have not set your API key correctly.  Please make sure you're using "xi-api-key" exactly, with no typos, when setting your API key. 

#### voice\_not\_found

This means that you have entered the incorrect voice\_id.  Please check that you are using the correct voice\_id for the voice you want to use.  You can check this in My Voices.

#### quota\_exceeded

You have insufficient quota to complete the request.  On the Creator plan and above, you can enable usage-based billing from your Subscription page.

### API Error Code 429

API Error Code 429 can have two response messages: "too\_many\_concurrent\_requests" or "system\_busy".

If you see the response message "too\_many\_concurrent\_requests", this means that you have exceeded the concurrency limit for your subscription.  
The concurrency limit (concurrent requests running in parallel) depends on the plan you are on. Below are the current rates for each plan, but please note that we will likely revisit them in the future.

*   Free: 2
*   Starter: 3
*   Creator: 5
*   Pro: 10
*   Scale: 15
*   Business: 15

If you see the response message "system\_busy", this means that our services were experiencing high levels of traffic and your request could not be processed.  Generally, if you retry the request, it will succeed. Our infrastructure team actively monitors this situation and can scale resources as needed when it occurs too frequently.


# Overview

Elevate your projects with this guide into the Voiceover Studio.

<iframe width="100%" height="400" src="https://www.youtube.com/embed/GBdOQClluIA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

Similar to the Dubbing Studio, the new Voiceover Studio gives users an opportunity to create their own interactive content, but with a little more freedom. Voiceover Studio combines the audio timeline with our Sound Effects feature, giving you the ability to write a dialogue between any number of speakers, choose those speakers, and intertwine your own creative sound effects anywhere you like.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/vo_project_main.png" />

## Creating a Voiceover

To begin, click "Create a new voiceover".  Here you have the option to upload a video, audio or create your Voiceover from scratch. After that, it's as simple as pressing "Create voiceover" - you can name your Voiceover before or after it's created. Once in the Studio, you will notice it looks very similar to a Dubbing Studio project - and it is - with some notable additions. Let's briefly revisit the layout -

### Timeline

On the bottom half of your screen, you will see the audio timeline. This is a linear representation of your Voiceover project. Each row represents a track, and on the far left section you have the track information for voiceover or SFX tracks. In the middle, you can create the clips that represent when a voice is speaking or a SFX is playing. On the right-hand side, you have the settings for the currently selected clip.

### Speaker Cards

In Dubbing Studio, the AI creates the Speaker Cards automatically - in Voiceover Studio, you get to create these on your own!  Because of this, your Voiceover Project screen will begin blank after creation, and you will need to first add Tracks and Clips.

### Adding Tracks

There are three types of tracks you can add in the studio: Voiceover tracks,  SFX tracks and uploaded audio.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/voiceover_studio_1.png" />

*   **Voiceover Tracks:** Voiceover tracks create new Speakers. You can click and add clips on the timeline wherever you like. After creating a clip, start writing your desired text on the speaker cards above and click "Generate". Similar to Dubbing Studio, you will also see a little cogwheel on each Speaker track - simply click on it to adjust the voice settings or replace any speaker with a voice directly from your VoiceLab - including your own Professional Voice Clone if you have created one.

*   **SFX Tracks:** Add a SFX track, then click anywhere on that track to create a SFX clip. Similar to our independent SFX feature, simply start writing your prompt in the Speaker card above and click "Generate" to create your new SFX audio. You can lengthen or shorten SFX clips and move them freely around your timeline to fit your project - make sure to press  the "stale" button if you do so.

*   **Uploaded Audio:** Add an audio track including background music or sound effects.  It's best to avoid uploading audio with speakers, as any speakers in this track will not be detected, so you won't be able to translate or correct them.

### Track Features

Once you've created a new Voiceover Track, you will see on the left-hand side of each track that you have a few options. You can also click directly on "New Voiceover Speaker" to rename it to keep yourself more organized.

Click the cog to open the Track Voice Settings.  This is where you can change the voice and model used for this Voiceover Track, and adjust the voice settings.  If you make changes here before generating audio for the track, the audio will generate with the settings you choose.  If you change settings after audio has aleady been generated for the track, this audio will be labelled "Stale", and you will need to regenerate it, either by clicking the regenerate icon to generate a specific clip, or "Generate Stale Audio" to regenerate all the stale audio in your Voiceover project.

By clicking the small Headphones icon on either a Speaker or SFX track, you can "solo" that track which will mute all other tracks on playback. If you want to delete a track, simply click the three small dots next to the Headphones icon on the track.

### Key Differences from Dubbing Studio

If you chose not to upload a video when you created your Voiceover project, then the entire timeline is yours to work with and there are no time constraints. This differs from Dubbing Studio as it gives you a lot more freedom to create what you want and adjust the timing more easily.

When you Add a Voiceover Track, you will instantly be able to create clips on your timeline. Once you create a Voiceover clip, begin by writing in the Speaker Card above. After generating that audio, you will notice your clip on the timeline will automatically adjust its length based on the text prompt - this is called "Dynamic Generation". This option is also available in Dubbing Studio by right-clicking specific clips, but because syncing is more important with dubbed videos, the default generation type there is "Fixed Generation," meaning the clips' lengths are not affected.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/vo_project_clipshort.png" />

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/images/vo_project_cliplong.png" />

### Credit Costs

Voiceover Studio does not deduct credits to create your initial project. Credits are deducted every time material is generated. Similar to Speech-Synthesis, credit costs for Voiceover Clips are based on the length of the text prompt. SFX clips will deduct 80 credits per generation.

If you choose to Dub (translate) your Voiceover Project into different languages, this will also cost additional credits depending on how much material needs to be generated.  The cost is 1 credit per character for the translation, plus the cost of generating the new audio for the additional languages.

## Translating and Exporting

Similar to Dubbing Studio, after you've finished creating your Tracks and Clips and you've arranged them on the Timeline, you can click the "plus" icon on the bottom of the page to Dub your Voiceover into different languages. Click to add the desired language(s), and then make sure to generate by pressing "Generate Stale Audio" on the bottom right.

To export your Voiceover Project, simply click "Export" in the bottom right and choose your desired file type.  Once the file has been generated, it will be available for download.

## Uploading Scripts

With Voiceover Studio, you have the option to upload a script for your project as a CSV file.  You can either include speaker name and line, or speaker name, line, start time and end time.

Sample format, speaker and line

```
speaker,line,
Joe,"Hey!"
Maria,"Oh, hi Joe!  It's been a while."
```

Sample format, speaker, line, start time and end time.

```
speaker,line,start_time,end_time
Joe,"Hey!",0.1,1.5
Maria,"Oh, hi Joe! It's been a while.",1.6,2.0
```

Once your script has imported, make sure to assign voices to each speaker before you generate the audio.  To do this, click the cog icon in the information for each track, on the left.

If you don't specify start and end times for your clips, Voiceover Studio will estimate how long each clip will be, and distribute them along your timeline.

### Dynamic Duration

By default, Voiceover Studio uses Dynamic Duration, which means that the length of the clip will vary depending on the text input and the voice used.  This ensures that the audio sounds as natural as possible, but it means that the length of the clip might change after the audio has been generated.  You can easily reposition your clips along the timeline once they have been generated to get a natural sounding flow.  If you click "Generate Stale Audio", or use the generate button on the clip, the audio will be generated using Dynamic Duration.

This also applies if you do specify the start and end time for your clips.  The clips will generate based on the start time you specify, but if you use the default Dynamic Duration, the end time is likely to change once you generate the audio.

### Fixed Duration

If you need the clip to remain the length specified, you can choose to generate with Fixed Duration instead.  To do this, you need to right click on the clip and select "Generate Audio Fixed Duration".  This will adjust the length of the generated audio to fit the specified length of the clip.  This could lead to the audio sounding unnaturally quick or slow, depending on the length of your clip.

If you want to generate multiple clips at once, you can use shift + click to select multiple clips for a speaker at once, then right click on one of them to select "Generate Audio Fixed Duration" for all selected clips.

### We can't wait to see where your creativity takes you!


# Default Voices

A curated set of voices for our core use cases.

Default voices are a curated set of voices optimized for our core use cases and made available to all ElevenLabs users by default. They come with a few core guarantees:

*   **Long-term availability**: we make our default voices via multi-year partnerships with voice actors
*   **Consistent quality**: our team carefully crafts and QCs our default voices to ensure they perform well across a range of use cases
*   **Priority model support**: our default voices are the first to receive fine tunings for new models as they are released

**Note:** Default voices were previously referred to as "premade" voices. The latter term is still used when accessing default voices via the API, e.g. when filtering by `category == "premade"`. Please see the [voices API documentation](https://elevenlabs.io/docs/api-reference/get-voices) for more details.

## Using Default Voices

Unlike voices you add from the Voice Library or new <a href="/product/voices/voice-lab/instant-voice-cloning">Instant Voice Clones (IVCs)</a> or <a href="/product/voices/voice-lab/professional-voice-cloning">Professional Voice Clones (PVCs)</a> you create, default voices are not accessed via your <a href="/product/voices/voice-lab/overview">My Voices</a>.

There are several ways you can find and use default voices:

Instead, there are 2 ways to find and use default voices:

*   <b>My Voices</b>: Default voices can be found in My Voices, under either the
    "All" or the "Default" tabs. Default voices do not take up any of your custom
    voice slots, and cannot be removed from My Voices. You can use Default voices
    directly from My Voices by clicking "Use". This will open Speech Synthesis
    with the voice already selected.

*   <b>API</b>: Calls to the /voices endpoint will fetch all default voices in
    addition to voices added to My Voices. See the <a href="https://elevenlabs.io/docs/api-reference/get-voices">
    voices API documentation
    </a> for more details.{" "}

*   <b>Voice dropdown menu</b>: Default voices can be selected from the voice
    dropdown menu. In Speech Synthesis, this can be accessed by clicking the voice
    name in the bottom left-hand corner of the text-to-speech or voice changer
    screen:

    <Frame>
      <img width="600" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/images/voice-select.png" />
    </Frame>

    You'll find our default voices under the "Default" heading, or alternatively, you can search for the name of the voice you want to use. To hear a sample of the voice, click the circular icon next to the voice name.

    {" "}

    <Frame>
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/images/default-voices.png" />
    </Frame>

## Current Default Voices

Below is a list of our current default voices, including metadata and sample audio. Please note that all of our current default voices have fine tunings for our **Turbo v2, Turbo v2.5, and Multilingual v2 models**, which means they are optimized for use with these models.

<table width="100%" height="500">
  | name      | voice\_id            | gender     | age         | accent        | description   | use\_case      | preview\_url                                                                                                                             |
  | --------- | -------------------- | ---------- | ----------- | ------------- | ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
  | Alice     | Xb7hH8MSUJpSbSDYk0k2 | female     | middle-aged | British       | confident     | news           | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/Xb7hH8MSUJpSbSDYk0k2/d10f7534-11f6-41fe-a012-2de1e482d336.mp3) |
  | Aria      | 9BWtsMINqrJLrRacOk9x | female     | middle-aged | American      | expressive    | social media   | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/9BWtsMINqrJLrRacOk9x/405766b8-1f4e-4d3c-aba1-6f25333823ec.mp3) |
  | Bill      | pqHfZKP75CvOlQylNhV4 | male       | old         | American      | trustworthy   | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/pqHfZKP75CvOlQylNhV4/d782b3ff-84ba-4029-848c-acf01285524d.mp3) |
  | Brian     | nPczCjzI2devNBz1zQrb | male       | middle-aged | American      | deep          | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/nPczCjzI2devNBz1zQrb/2dd3e72c-4fd3-42f1-93ea-abc5d4e5aa1d.mp3) |
  | Callum    | N2lVS1w4EtoT3dr4eOWO | male       | middle-aged | Transatlantic | intense       | characters     | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/N2lVS1w4EtoT3dr4eOWO/ac833bd8-ffda-4938-9ebc-b0f99ca25481.mp3) |
  | Charlie   | IKne3meq5aSn9XLyUdCD | male       | middle aged | Australian    | natural       | conversational | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/IKne3meq5aSn9XLyUdCD/102de6f2-22ed-43e0-a1f1-111fa75c5481.mp3) |
  | Charlotte | XB0fDUnXU5powFXDhCwa | female     | young       | Swedish       | seductive     | characters     | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/XB0fDUnXU5powFXDhCwa/942356dc-f10d-4d89-bda5-4f8505ee038b.mp3) |
  | Chris     | iP95p4xoKVk53GoZ742B | male       | middle-aged | American      | casual        | conversational | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/iP95p4xoKVk53GoZ742B/3f4bde72-cc48-40dd-829f-57fbf906f4d7.mp3) |
  | Daniel    | onwK4e9ZLuTAKqWW03F9 | male       | middle-aged | British       | authoritative | news           | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/onwK4e9ZLuTAKqWW03F9/7eee0236-1a72-4b86-b303-5dcadc007ba9.mp3) |
  | Eric      | cjVigY5qzO86Huf0OWal | male       | middle-aged | American      | friendly      | conversational | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/cjVigY5qzO86Huf0OWal/d098fda0-6456-4030-b3d8-63aa048c9070.mp3) |
  | George    | JBFqnCBsd6RMkjVDRZzb | male       | middle aged | British       | warm          | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/JBFqnCBsd6RMkjVDRZzb/e6206d1a-0721-4787-aafb-06a6e705cac5.mp3) |
  | Jessica   | cgSgspJ2msm6clMCkdW9 | female     | young       | American      | expressive    | conversational | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/cgSgspJ2msm6clMCkdW9/56a97bf8-b69b-448f-846c-c3a11683d45a.mp3) |
  | Laura     | FGY2WhTYpPnrIDTdsKH5 | female     | young       | American      | upbeat        | social media   | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/FGY2WhTYpPnrIDTdsKH5/67341759-ad08-41a5-be6e-de12fe448618.mp3) |
  | Liam      | TX3LPaxmHKxFdv7VOQHJ | male       | young       | American      | articulate    | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/TX3LPaxmHKxFdv7VOQHJ/63148076-6363-42db-aea8-31424308b92c.mp3) |
  | Lily      | pFZP5JQG7iQjIQuC4Bku | female     | middle-aged | British       | warm          | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/pFZP5JQG7iQjIQuC4Bku/89b68b35-b3dd-4348-a84a-a3c13a3c2b30.mp3) |
  | Matilda   | XrExE9yKIg1WjnnlVkGX | female     | middle-aged | American      | friendly      | narration      | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/XrExE9yKIg1WjnnlVkGX/b930e18d-6b4d-466e-bab2-0ae97c6d8535.mp3) |
  | River     | SAz9YHcvj6GT2YYXdXww | non-binary | middle-aged | American      | confident     | social media   | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/SAz9YHcvj6GT2YYXdXww/e6c95f0b-2227-491a-b3d7-2249240decb7.mp3) |
  | Roger     | CwhRBWXzGAHq8TQ4Fs17 | male       | middle-aged | American      | confident     | social media   | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/CwhRBWXzGAHq8TQ4Fs17/58ee3ff5-f6f2-4628-93b8-e38eb31806b0.mp3) |
  | Sarah     | EXAVITQu4vr4xnSDxMaL | female     | young       | American      | soft          | news           | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/EXAVITQu4vr4xnSDxMaL/01a3e33c-6e99-4ee7-8543-ff2216a32186.mp3) |
  | Will      | bIHbv24MWmeRgasZH58o | male       | young       | American      | friendly      | social media   | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/bIHbv24MWmeRgasZH58o/8caf8f3d-ad29-4980-af41-53f20c72d7a4.mp3) |
</table>

## How do Default Voices sound in my language?

*   Our default voices can be used to generate audio in any of the [32 languages we support](https://elevenlabs.io/docs/api-reference/text-to-speech#supported-languages) by using them with one of our multilingual models (e.g. Multilingual v2 or Turbo v2.5).
*   Some default voices may have unpredicable accents in other languages.
*   We are working to provide a granular overview of how each default voice sounds in each of the languages we support and will update this page when this is ready.

## Legacy Voices

Below is a list of our legacy voices, which can be accesssed in 2 ways:

*   **UI**: Search for the name of the legacy voice you're looking for in any voice dropdown, or go to My Voices -> Default, and look for voices with "Legacy" in the name.
*   **API**: To see legacy voices when calling the /voices endpoint, you need to set the `show_legacy` query parameter to `True`. Please see the [voices API documentation](https://elevenlabs.io/docs/api-reference/get-voices) for more details.

**Note:** Legacy voices will remain available for the foreseeable future, but they are less consistent than default voices and will not receive priority support for future model releases. For more information on Legacy voices, please see [What are Legacy voices?](https://help.elevenlabs.io/hc/en-us/articles/26928417254801-What-are-Legacy-voices)

<table width="100%" height="500">
  | name     | voice\_id            | gender | age         | accent           | description    | use\_case  | preview\_url                                                                                                                             |
  | -------- | -------------------- | ------ | ----------- | ---------------- | -------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
  | Adam     | pNInz6obpgDQGcFmaJgB | male   | middle aged | american         | deep           | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/pNInz6obpgDQGcFmaJgB/d6905d7a-dd26-4187-bfff-1bd3a5ea7cac.mp3) |
  | Antoni   | ErXwobaYiN019PkySvjV | male   | young       | american         | well-rounded   | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/ErXwobaYiN019PkySvjV/2d5ab2a3-4578-470f-b797-6331e46a7d55.mp3) |
  | Arnold   | VR6AewLTigWG4xSOukaG | male   | middle aged | american         | crisp          | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/VR6AewLTigWG4xSOukaG/49a22885-80d5-48e8-87a3-076fc9193d9a.mp3) |
  | Clyde    | 2EiwWnXFnvU5JabPnv8n | male   | middle-aged | American         | war veteran    | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/2EiwWnXFnvU5JabPnv8n/65d80f52-703f-4cae-a91d-75d4e200ed02.mp3) |
  | Dave     | CYw3kZ02Hs0563khs1Fj | male   | young       | British          | conversational | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/CYw3kZ02Hs0563khs1Fj/872cb056-45d3-419e-b5c6-de2b387a93a0.mp3) |
  | Dorothy  | ThT5KcBeYPX3keUQqHPh | female | young       | British          | pleasant       | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/ThT5KcBeYPX3keUQqHPh/981f0855-6598-48d2-9f8f-b6d92fbbe3fc.mp3) |
  | Drew     | 29vD33N1CtxCmqQRPOHJ | male   | middle-aged | American         | well-rounded   | news       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/29vD33N1CtxCmqQRPOHJ/b99fc51d-12d3-4312-b480-a8a45a7d51ef.mp3) |
  | Emily    | LcfcDJNUP1GQjkzn1xUU | female | young       | American         | calm           | meditation | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/LcfcDJNUP1GQjkzn1xUU/e4b994b7-9713-4238-84f3-add8fccaaccd.mp3) |
  | Ethan    | g5CIjZEefAph4nQFvHAz | male   | young       | American         | soft           | ASMR       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/g5CIjZEefAph4nQFvHAz/26acfa99-fdec-43b8-b2ee-e49e75a3ac16.mp3) |
  | Fin      | D38z5RcWu1voky8WS1ja | male   | old         | Irish            | sailor         | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/D38z5RcWu1voky8WS1ja/a470ba64-1e72-46d9-ba9d-030c4155e2d2.mp3) |
  | Freya    | jsCqWAovK2LkecY7zXl4 | female | young       | American         | expressive     | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/jsCqWAovK2LkecY7zXl4/8e1f5240-556e-4fd5-892c-25df9ea3b593.mp3) |
  | George   | Yko7PKHZNXotIFUBG7I9 | male   | middle aged | british          |                | audiobook  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/Yko7PKHZNXotIFUBG7I9/02c66c93-a237-436f-8a7d-43e8c49bc6a3.mp3) |
  | Gigi     | jBpfuIE2acCO8z3wKNLl | female | young       | American         | childlish      | animation  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/jBpfuIE2acCO8z3wKNLl/3a7e4339-78fa-404e-8d10-c3ef5587935b.mp3) |
  | Giovanni | zcAOhNBS3c14rBihAFp1 | male   | young       | Italian          | foreigner      | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/zcAOhNBS3c14rBihAFp1/e7410f8f-4913-4cb8-8907-784abee5aff8.mp3) |
  | Glinda   | z9fAnlkpzviPz146aGWa | female | middle-aged | American         | witch          | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/z9fAnlkpzviPz146aGWa/cbc60443-7b61-4ebb-b8e1-5c03237ea01d.mp3) |
  | Grace    | oWAxZDx7w5VEj9dCyTzz | female | young       | American (South) | pleasant       | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/oWAxZDx7w5VEj9dCyTzz/84a36d1c-e182-41a8-8c55-dbdd15cd6e72.mp3) |
  | Harry    | SOYHLrjzK2X1ezoPC6cr | male   | young       | American         | anxious        | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/SOYHLrjzK2X1ezoPC6cr/86d178f6-f4b6-4e0e-85be-3de19f490794.mp3) |
  | James    | ZQe5CZNOzWyzPSCn5a3c | male   | old         | Australian       | calm           | news       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/ZQe5CZNOzWyzPSCn5a3c/35734112-7b72-48df-bc2f-64d5ab2f791b.mp3) |
  | Jeremy   | bVMeCyTHy58xNoL34h3p | male   | young       | Irish            | excited        | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/bVMeCyTHy58xNoL34h3p/66c47d58-26fd-4b30-8a06-07952116a72c.mp3) |
  | Jessie   | t0jbNlBVZ17f02VDIeMI | male   | old         | American         | raspy          | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/t0jbNlBVZ17f02VDIeMI/e26939e3-61a4-4872-a41d-33922cfbdcdc.mp3) |
  | Joseph   | Zlb1dXrM653N07WRdFW3 | male   | middle-aged | British          | articulate     | news       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/Zlb1dXrM653N07WRdFW3/daa22039-8b09-4c65-b59f-c79c48646a72.mp3) |
  | Josh     | TxGEqnHWrfWFTfGW9XjX | male   | young       | american         | deep           | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/TxGEqnHWrfWFTfGW9XjX/47de9a7e-773a-42a8-b410-4aa90c581216.mp3) |
  | Michael  | flq6f7yk4E4fJM5XTYuZ | male   | old         | American         | calm           | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/flq6f7yk4E4fJM5XTYuZ/c6431a82-f7d2-4905-b8a4-a631960633d6.mp3) |
  | Mimi     | zrHiDhphv9ZnVXBqCLjz | female | young       | Swedish          | childish       | animation  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/zrHiDhphv9ZnVXBqCLjz/decbf20b-0f57-4fac-985b-a4f0290ebfc4.mp3) |
  | Nicole   | piTKgcLEGmPE4e6mEKli | female | young       | American         | soft           | ASMR       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/piTKgcLEGmPE4e6mEKli/c269a54a-e2bc-44d0-bb46-4ed2666d6340.mp3) |
  | Patrick  | ODq5zmih8GrVes37Dizd | male   | middle-aged | American         | shouty         | characters | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/ODq5zmih8GrVes37Dizd/0ebec87a-2569-4976-9ea5-0170854411a9.mp3) |
  | Paul     | 5Q0t7uMcjvnagumLfvZi | male   | middle-aged | American         | authoritative  | news       | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/5Q0t7uMcjvnagumLfvZi/a4aaa30e-54c4-44a4-8e46-b9b00505d963.mp3) |
  | Rachel   | 21m00Tcm4TlvDq8ikWAM | female | young       | american         | calm           | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/21m00Tcm4TlvDq8ikWAM/b4928a68-c03b-411f-8533-3d5c299fd451.mp3) |
  | Sam      | yoZ06aMxZJJ28mfd3POQ | male   | young       | american         | raspy          | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/yoZ06aMxZJJ28mfd3POQ/b017ad02-8d18-4456-ad92-55c85ecf6363.mp3) |
  | Serena   | pMsXgVXv3BLzUgSXRplE | female | middle-aged | American         | pleasant       | narration  | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/pMsXgVXv3BLzUgSXRplE/d61f18ed-e5b0-4d0b-a33c-5c6e7e33b053.mp3) |
  | Thomas   | GBv7mTt0atIp3Br8iCZE | male   | young       | American         | calm           | meditation | [Sample](https://storage.googleapis.com/eleven-public-prod/premade/voices/GBv7mTt0atIp3Br8iCZE/98542988-5267-4148-9a9e-baa8c4f14644.mp3) |
</table>


# Overview

Discover all the voices ElevenLabs has to offer

## Voice Categories

There are 3 primary categories of voices on the ElevenLabs platform:

*   <a href="/docs/product/voices/default-voices">Default Voices</a> available to all
    users on the Speech page, in the "Default" tab of My Voices, and via the API -
    Long-term availability - Consistent quality for most use cases - Priority support
    for new models - Optimized for English
*   <a href="/docs/product/voices/voice-lab/voice-design">Generated voices</a> made
    using our Voice Design tool - Custom voice creation with gender, age, and accent
    options - Includes different English accents to choose from - May require multiple
    attempts to find the desired voice
*   Cloned voices made using our <a href="/docs/product/voices/voice-lab/instant-voice-cloning">Instant Voice Cloning (IVC)</a> or <a href="/docs/product/voices/voice-lab/professional-voice-cloning">Professional Voice Cloning (PVC)</a> products,
    including new ones you create and those added from the <a href="/docs/product/voices/voice-library/overview">Voice Library.</a>


# Step-by-step Guide

Step-by-step guide to creating the highest quality voice clone available

## What is a Professional Voice Clone (PVC)?

A Professional Voice Clone (PVC) is a special feature that is available to our Creator+ plans. A PVC is an ultra-realistic, custom AI model of your voice. This is done by training our specialized model with longer voice data (at least 30 mins and up to 3 hours for optimum results) to make it sound just like the original voice.

Essentially, a PVC is a more advanced version of our Instant Voice Cloning feature. For now, we only allow you to clone your own voice. You will be asked to go through a verification process with our voice Captcha before submitting your fine-tuning request.

Custom AI models require fine-tuning and training, so PVCs will take longer (about 4 to 8 hours) compared to Instant Voice Clones.

Video

<iframe width="100%" height="400" src="https://www.youtube.com/embed/bY9DO6wa_vs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

## How to create a PVC?

### A Step-by-step guide to create a high-quality PVC:

**1. Go to your VoiceLab by first clicking on the “Voices” tab:**

![](https://lh7-us.googleusercontent.com/2XaOuuOmIs-CJ90NnY3yt-C5fbk0AUtMgxVFyB-7AYHum9r0Ooxr8R__Fvo-uE_fmTCQ26w0wRy2JvHYkqWelBh8dwANrnPdIcmt2n7_sArxsoheSNxyEURaHzoMtBuYW55GADkfYSdKvYYUIWKlSIw)

**2. Click on “Add Generative or Cloned Voice” and choose “Professional Voice Cloning”:**

![](https://lh7-us.googleusercontent.com/vRCfOP45g8elNMzGsXLguRfhYsmXhIGSZaMDv3Wl0lT8JQ5NTLdm9i8TnfoYt5N0TpotzlCV63o2lJK655CVqgXDlKcsfiUPWvaOXc37yPI8Vrwxh5Ul4vqoJSZGyXNpTGX8Di1NXAImOiIjVUVLslY)

**3. Confirm that you have read our Guidelines and Rules and click “Start”:**

![](https://lh7-us.googleusercontent.com/PJfCTiW0Ka1qWnWVZdDGPIMQrOjsIN1TPhdAwUE089viKEwHj2mnXCdpJHcBsaQZTBetSXSUrhrHKXwPqDG4rV7yT9iPiAZPTWogEj3sjYhw7gxb9B2bp-U_x_RQWO__ay5FM423OqLjGFEKlegJS3Q)

**4. Name your PVC, Choose the Language, and Upload your recordings:**

![](https://lh7-us.googleusercontent.com/kGimSZIHq6T2l40V-qpQuZS-bCIJ9PoIkPtsYjt83oUVMQug3H_TmRZ4eJd_B7nXMQTtU2JCbKdKAE_EK5HBKbdU3yHzCPxCPU_Fu3L4i3Ye_gLrSrvEOiAkt3gPdA7WoEfz_519h4nXo8D7g3R02aY)

**5. Add Labels and a Description for your Professional Clone Voice (this can be changed later) and click “Create Professional Voice”:**

![](https://lh7-us.googleusercontent.com/l-ZCbkR-Hdu0DV0h-4yy-ZlRsm-uK7fwEYDHmhGXhSIu30ke4JGAr2Cr_Ozp4UcRZaGlAGMSNSmIMwogH_fOzn3OgIcYcBaEnUnwJ9z5ggEpybq09e44J5gk45hqHO6hMvq6PhYrzJCh573-4rnLymE)

**6. Once the PVC model has accepted all of your Audio Samples, you will then be asked to verify your voice:**

![](https://lh7-us.googleusercontent.com/8hHkdxNPtcpV2Zuvd0u8tEQzrg1EnLBeWAPucODJA2RSRJUcJ8nR5R_vPW3KFFYQ1pmx8xxPQatcQbZ-lFKwxbIT-Wc0URjmZ2bBU1CvPnJzZw75SBIyq0EYxiur3yXshQw2eXix-Vlmn8tM4_B9FB8)

Before moving on, ensure that your browser has access to your Microphone and that you are not muted. The AI will compare your voice to the samples you just submitted, so it’s important to use the same equipment that you used to record your uploaded audio samples - try your best to match the tone and delivery!

<Frame>
  ![](https://lh7-us.googleusercontent.com/F8Ix9L_a1GWr4Kj7bqTzVfzabwgCh4LoRs3W2uvK8Tv52FqKQJjJkyYrDFHR2jgvHxvdPPOCLYuPkXrMX20dFWSd2qHWdm9x_XlyzzP5_-lZJzcY5-QSy-7Ep6pNBhYvPStJaEb1cvG291cO3X3_Brw)
</Frame>

Once you’re ready, click “Start Recording” and you will see a generated captcha to read such as the following:

<Frame>
  ![](https://lh7-us.googleusercontent.com/Zb-vtAh4LYDRfcbT_AI4m5FuOZXFv8Endh1Cz1yHNOBGTQytmosx7xjb2oqlx4lj9ULaZZXAy2MJ2cz7142rImBWB21cptWXGT13qCQhreSciFz0sbwZ6nzKKRf1MuWfu4WrKrgQ7KEVlO_cgkQRdns)
</Frame>

If the AI detects a difference in the audio quality of your recordings, you may see an error message letting you know:

<Frame>
  ![](https://lh7-us.googleusercontent.com/AupFUKrsuEBcLpDzmaEA_tzfKjvcAqhdcvcGJ_Se8J-nxApuQ2iRFBm4f34sb__LBNdME13leBJuuY699zOstNokMGRkJryQiLP-8kWYxFJdbCp8TklFL__4fIbqWkNQoLmMcYvqJRya91qSK97rJkI)
</Frame>

Ensure that your audio quality matches your uploaded recordings, speak clearly and concisely, and try again:

<Frame>
  ![](https://lh7-us.googleusercontent.com/pvNzcYfMXCL_26eCDMIe_JrULNEXSTghdhm03v62hdf1OVObYbRzOAbCa260BNpMyYExe_Hg4cS4AJ-Ej2Sc0YyP-3AsRmTrQuRdEL5d8yfwu_F-hZRDh2ODn-x-jJeUAe6-dv5H3BrrB79sTP1torY)
</Frame>

**7.Once successful, your voice will be marked as “successfully verified”. Your PVC will be then queued for Fine-Tuning:**

![](https://lh7-us.googleusercontent.com/_vt2hVW8SubcO0PHkTYEfsMk1yJhiSOjD6vcs0HpnXw7f2M0IIowS3sgKAp6Ba6ZhSPcauMOarHdYYvk6THMKe7HD7dY-sGG0LIscyumuoLz4XKRKkrefUHHdpqk9QJa5uypr_g0nHFgKnWUW6QlRSg)

**8. After fine-tuning your PVC, you will find it in your VoiceLab. Click "use" so it can appear in the Speech Synthesis page, so that you can use it to generate the audio you need.**

**9. If you would like to share your PVC in our Voice Library and start earning passively with [Payouts](https://elevenlabs.io/payouts), follow [these steps](https://elevenlabs.io/docs/voices/voice-library/sharing).**

## Recording audio for your PVC

### Recording Key Considerations

Before you upload your audio samples for Professional Voice Cloning (PVC), there are key considerations to keep in mind to achieve the best results.

1.  **Recording Quality**
    Firstly, Professional Voice Cloning is highly accurate in cloning the samples used for its training. It will create a near-perfect clone of what it hears, including all the nuances and characteristics of that voice, but also including any artifacts and unwanted audio present in the samples. This means that if you upload low-quality samples with background noise, room reverb/echo, or any other type of unwanted sounds, the AI will try to replicate all of these elements in the clone as well. Making your model also have ample background noise, sibilance, or reverb. Please follow these guidelines for best results.

2.  **Clear audio with a single speaker and no background music or sound effects**
    Ensure there’s only a single speaking voice throughout the audio, as more than one speaker or excessive noise or anything of the above can confuse the AI. This confusion can result in the AI being unable to discern which voice to clone or misinterpreting what the voice actually sounds like because it is being masked by other sounds, leading to a less-than-optimal clone.

3.  **Use at least 30 mins to 3 hours of audio**
    The bare minimum we recommend is 30 minutes of audio, but for optimal results and the most accurate clone, we recommend closer to 3 hours of audio. The more quality data you can feed into the AI, the better the voice clone will be. This can be either one long file, or several different files. If you choose to upload multiple audio files, make sure they have the same audio quality and are recorded in the same space. However, if you plan to upload multiple hours of audio, it is better to split it into multiple \~30-minute samples. This makes it easier to upload.

4.  **Use a consistent delivery style**
    The speaking style in your samples will be replicated in the output. For consistent results, use one style per upload. For instance, if you're creating a voice model intended for audiobooks, submit recordings of yourself reading books in a consistent style, avoiding different character voices or else this will create errors in your voice model. This does not mean monotone or emotionless, feel free to vary your tone and emotion according to the context of the text.

5.  **Use audio samples in the same language as your PVC model**
    For best results, use samples in the language you primarily intend the PVC for. While the AI can speak any supported language, cloning a voice from a different language may result in accents or mispronunciations. For example, if you clone an English voice for Spanish, it may retain an English accent. We only support cloning samples recorded in one of our supported languages, and the application will reject your sample if it is recorded in an unsupported language.

6.  **Clone your own voice only**
    For now, we only allow you to clone your own voice. You will be asked to go through a verification process with our voice Captcha before submitting your fine-tuning request.

### Recording Quality Guidelines

Whether you’re new to voice recording or a seasoned professional. Here are some quality guidelines to consider. **Please note that if you're sharing your PVC in our Voice Library and it follows these guidelines and showcases consistent output**, your PVC **may** earn a High-Quality Badge in our Voice Library, enhancing your ranking and potential earnings!

**General recording guidelines:**

*   **Use professional recording equipment:** The AI will clone everything in your audio. High-quality input = high-quality output. Opt for a professional XLR mic going into a dedicated audio interface.
*   **Use a pop-filter**: This will minimize plosives when recording.
*   **Microphone distance**: Position yourself at the right distance from the microphone - approximately two fists away from the mic is recommended, but it also depends on what type of recording you want.
*   **Noise-free recording:** Ensure that the audio input doesn’t have any interference, like background music or noise. The AI cloning works best with clean, uncluttered audio.
*   **Room acoustics:** Always record in an acoustically-treated room. This reduces unwanted echoes and background noises, leading to clearer audio input for the AI.
*   **Audio pre-processing** (optional): You might find that adding light compression or other tools can improve your audio files before creating your PVC. Please note that excessive processing can have diminishing returns, so it’s best to be conservative with these effects.
*   **Volume control:** Maintain a consistent volume that’s loud enough to be clear but not so loud that it causes distortion. The goal is to achieve a balanced and steady audio level. The ideal would be between -23dB and -18dB RMS with a true peak of -3dB.
*   **Audio file format:** Mono, .wav, Minimum 44.1 kHz sample rate, and Minimum 16-bit depth

### Please avoid these technical recording issues:

*   Room echo or "boxiness.”
*   Background noise, including hiss, white noise, electrical hum, or external disturbances.
*   Apparent editing issues (i.e. clicks, pops, audible cuts).
*   Distortion, clipping, heavy compression, or excessive processing (i.e. noise gate, noise reduction plugin, normalization, EQ).
*   Sibilance, loud breath noises, plosives, and mouth clicks.
*   Repeats, mistakes, and long periods of silence (5 seconds or more).
*   Voice level/input gain imbalance anywhere in the recording.

### Performance guidelines:

*   Emphasis, intonations and emotions should align appropriately with the context of the text to create a realistic PVC.
*   In some cases (e.g. audiobooks), emotional range and variance is helpful in delivering an engaging performance and creating a great AI voice. Our models can capture this emotional range, but the voice itself should remain consistent.
*   ***Please vary your tone*** and pace naturally when reading. ✅
*   ***Please avoid changing voices*** for different characters in a single recording or else this will create errors in your voice model. ❌
*   Ensure correct and articulate pronunciation.
*   Avoid sounding nasal, muffled, or wet (excess saliva).

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Good%20example&small=true&preview=true&audioSrc=https%3A%2F%2Fstorage.googleapis.com%2Feleven-public-cdn%2Faudio%2Fdocs%2Fgood_example.wav`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Bad%20example&small=true&preview=true&audioSrc=https%3A%2F%2Fstorage.googleapis.com%2Feleven-public-cdn%2Faudio%2Fdocs%2Fbad_example.wav`} />

## Beginner's Guide to Audio Recording

New to audio recording? Follow our guideline below!

**1) Recording Location**

When recording audio, choose a suitable location and set up to minimize room echo/reverb.
So, we want to "deaden" the room as much as possible. This is precisely what a vocal booth that is acoustically treated made for, and if you do not have a vocal booth readily available, you can experiment with some ideas for a DIY vocal booth, “blanket fort”, or closet.

Here are a few YouTube examples of DIY acoustics ideas:

*   [I made a vocal booth for \$0.00!](https://www.youtube.com/watch?v=j4wJMDUuHSM)
*   [How to Record GOOD Vocals in a BAD Room](https://www.youtube.com/watch?v=TsxdHtu-OpU)
*   [The 5 BEST Vocal Home Recording TIPS!](https://www.youtube.com/watch?v=K96mw2QBz34)

**2) 2) Equipment: Microphone, pop-filter, and audio interface**

A good microphone is crucial. Microphones range from $100 to $10,000, but a professional XLR microphone costing $150-$300 is sufficient for most voiceover work.

For an affordable yet high-quality setup for voiceover work, consider a **Focusrite** interface paired with an **Audio-Technica AT2020** or **Rode NT1 microphone**. This setup, costing between $300 to $500, offers high-quality recording suitable for professional use, with minimal self-noise for clean results.

Also, please ensure that you have a proper **pop-filter** in front of the microphone when recording to avoid plosives as well as breaths and air hitting the diaphragm/microphone directly, as it will sound poor and will also cause issues with the cloning process.

**3) Digital Audio Workstation (DAW)**

There are many different recording solutions out there that all accomplish the same thing: recording audio. However, they are not all created equally. As long as they can record WAV files at 44.1kHz or 48kHz with a bitrate of at least 24 bits, they should be fine. You don't need any fancy post-processing, plugins, denoisers, or anything because we want to keep audio recording simple.

If you want a recommendation, we would suggest something like **REAPER**, which is a fantastic DAW with a tremendous amount of flexibility. It is the industry standard for a lot of audio work. For a personal license or a discounted license, it is only \$60. Another good free option is **Audacity**.

Maintain optimal recording levels (not too loud or too quiet) to avoid digital distortion and excessive noise. Aim for peaks of -6 dB to -3 dB and an average loudness of -18 dB for voiceover work, ensuring clarity while minimizing the noise floor. Monitor closely and adjust levels as needed for the best results based on the project and recording environment.

**4) Positioning**

One helpful guideline to follow is to maintain a distance of about two fists away from the microphone, which is approximately 20cm (7-8 in), with a pop filter placed between you and the microphone. Some people prefer to position the pop filter all the way back so that they can press it up right against it. This helps them maintain a consistent distance from the microphone more easily.

Another common technique to avoid directly breathing into the microphone or causing plosive sounds is to speak at an angle. Speaking at an angle ensures that exhaled air is less likely to hit the microphone directly and, instead, passes by it.

**5) Performance**

The performance you give is one of the most crucial aspects of this entire recording session. The AI will try to clone everything about your voice to the best of its ability, which is very high. This means that it will attempt to replicate your cadence, tonality, performance style, the length of your pauses, whether you stutter, take deep breaths, sound breathy, or use a lot of "uhms" and "ahs" – it can even replicate those. Therefore, what we want in the audio file is precisely the performance and voice that we want to clone, nothing less and nothing more. That is also why it's quite important to find a script that you can read that fits the tonality we are aiming for.

When recording for AI, it is very important to be consistent. if you are recording a voice either keep it very animated throughout or keep it very subdued throughout you can't mix and match or the AI can become unstable because it doesn't know what part of the voice to clone. same if you're doing an accent keep the same accent throughout the recording. Consistency is key to a proper clone!

## Scripts

Here’s a variety of English scripts to help you create PVCs optimized for some of the most popular use cases.

Please remember that what you read is not very important; how you read it is very important, however. The AI will try to mimic everything it hears in a voice: the tonal quality, the accent, the inflection, and many other intricate details. It will replicate how you pronounce certain words, vowels, and consonants, but not the actual words themselves. So, it is better to choose a text or script that conveys the emotion you want to capture, and read in a tone of voice you want to use, and optimized for the use case it’s intended to serve.

*   [Audiobook](/product/voices/voice-lab/scripts/the-great-gatsby)
*   [News Article](/product/voices/voice-lab/scripts/news-article)
*   [Social Media](/product/voices/voice-lab/scripts/social-media)
*   [Meditation](/product/voices/voice-lab/scripts/meditation)
*   [Elearning](/product/voices/voice-lab/scripts/elearning)


# Instant Voice Cloning

Guide for getting the most out of you cloned voices.

Instant Voice Cloning (IVC) allows you to create voice clones form shorter samples near instantaneously. Creating an instant voice clone does not train or create a custom AI model. Instead, it relies on prior knowledge from training data to make an educated guess rather than training on the exact voice. This works extremely well for a lot of voices.

However, the biggest limitation of IVC is if you are trying to clone a very unique voice with a very unique accent where the AI might not have heard a similar voices before during training. In such cases, creating a custom model with explicit training using Professional Voice Cloning (PVC) might be the best option.

## Voice Creation

When cloning a voice, it's important to consider what the AI has been trained on: which languages and what type of dataset. In this case, you can find the languages for each model [here](https://help.elevenlabs.io/hc/en-us/articles/17883183930129-What-models-do-you-offer-and-what-is-the-difference-between-them-), and the dataset is quite varied, especially for the `multilingual v2`. You can read more about each individual model [here](/product/speech-synthesis/models) and their strengths.

As mentioned earlier, if the voice you try to clone falls outside of these parameters or outside of what the AI has heard during training, it might have a hard time replicating the voice perfectly using instant voice cloning.

How the audio was recorded is more important than the total length (total runtime) of the samples. The number of samples you use doesn't matter; it is the total combined length (total runtime) that is the important part.

Approximately 1-2 minutes of clear audio without any reverb, artifacts, or background noise of any kind appears to be the sweet spot. When we speak of "audio or recording quality," we do not mean the codec, such as MP3 or WAV; we mean how the audio was captured. However, regarding audio codecs, using MP3 at 128 kbps and above seems to work just fine, and higher bitrates don't seem to markedly improve the quality of the clone.

The AI will attempt to mimic everything it hears in the audio; the speed of the person talking as well as the inflections, the accent and tonality, breathing pattern and strength, as well as noise and mouth clicks and everything else, including noise and artefacts which can confuse it.

Another important thing to keep in mind is that the AI will try to replicate the performance of the voice you provide. If you talk in a slow, monotone voice without much emotion, that is what the AI will mimic. On the other hand, if you talk quickly with much emotion, that is what the AI will try to replicate.

It is crucial that the voice remains consistent throughout all the samples, not only in tone but also in performance. If there is too much variance, it might confuse the AI, leading to more varied output between generations.

*   The most important aspect to get a proper clone is the voice itself, the language and accent, and the quality of the recording.
*   Audio length is less important than quality but still plays an important role up to a certain point. At a minimum, input audio should be 1 minute long. Avoid adding beyond 3 minutes; this will yield little improvement and can, in some cases, even be detrimental to the clone, making it more unstable.
*   Keep the audio consistent. Ensure that the voice maintains a consistent tone throughout, with a consistent performance. Also, make sure that the audio quality of the voice remains consistent across all the samples. Even if you only use a single sample, ensure that it remains consistent throughout the full sample. Feeding the AI audio that is very dynamic, meaning wide fluctuations in pitch and volume, will yield less predictable results.
*   Find a good balance for the volume so the audio is neither too quiet nor too loud. The ideal would be between -23 dB and -18 dB RMS with a true peak of -3 dB.

If you are unsure about what is permissible from a legal standpoint, please consult the [Terms of Service](https://elevenlabs.io/terms-of-use) and our [AI Safety information](https://elevenlabs.io/safety) for more information.


# Overview

Learn more about My Voices

My Voices is your personal voice HQ. Here you can:

*   Create new <a href="https://elevenlabs.io/docs/voices/voice-lab/instant-voice-cloning">Instant Voice Clones (IVCs)</a>, <a href="https://elevenlabs.io/docs/voices/voice-lab/professional-voice-cloning">Professional Voice Clones (PVCs)</a>, and generate new voices using [Voice Design.](https://elevenlabs.io/docs/voices/voice-lab/voice-design)
*   View all of your custom voices, including those added from the <a href="https://elevenlabs.io/docs/voices/voice-library/overview">Voice Library</a>

## Search and filter

My Voices includes a search box, so you can easily find voices by searching for the name, words from the description, or tags.
You can sort voices either alphabetically, or by most recently use, and you can filter by voice type. By default, all voice types are selected, but you can also filter for Professional Voice Clones, Instant Voice Clones or Generated Voices.

## Voice Categories

My Voices includes several tabs which allow you to filter your voices by type.

*   **All**: All the voices currently saved in My Voices, including [Default](https://elevenlabs.io/docs/voices/default-voices) voices.  Default voices cannot be deleted from My Voices, and do not take up any of your custom voice slots.
*   **Personal**: Voices that you have created - Professional Voice Clones, Instant Voice Clones and voices generated using Voice Design.
*   **Community**: Voices you have saved from the Voice Library.
*   **Default**: All Default voices.

## Tags and Labels

You can give voices in My Voices (including those added from the Voice Library) custom names, descriptions, and tags. This allows you to organize My Voices as you wish and store custom attributes. However, please note that these changes will not reflect on shared versions of your voices. To edit shared names, descriptions, and labels, please set these values when <a href="https://elevenlabs.io/docs/voices/voice-library/sharing">sharing your voice in the Voice Library</a>.

## Deleting voices

You can only delete voices that you have created or saved from the Voice Library.  Default and Legacy voices cannot be deleted, but they don't take up any of your custom voice slots.  Voices that you have created using Instant and Professional Voice Cloning and Voice Design, as well as voices you've saved from the Voice Library, use your custom voice slots.

You can free up voice slots by deleting these voices.  To delete a voice, first click "View" to open the detailed view for the voice.  Then click "Delete" in the bottom left corner.  You can use the "Personal" and "Community" tabs to easily identify voices that use your custom voice slots, and can be deleted.

## Sharing voices

Only Professional Voice Clones can be shared with other users.  Instant Voice Clones and voices created using Voice Design cannot be shared.

Professional Voice Clones can be shared privately, via a sharing link, or publicly via the Voice Library.  For full details on how to share your Professional Voice Clone, please see [Sharing Voices.](https://elevenlabs.io/docs/voices/voice-library/sharing)


# Professional Voice Cloning

Guide to getting the highest quality voice clone available.

<Info>
  The video is currently slightly outdated as we've released new features since
  it was made, and the training time is significantly quicker. However, a lot of
  the information in it is still relevant.
</Info>

<iframe width="100%" height="400" src="https://www.youtube.com/embed/bY9DO6wa_vs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />

Professional Voice Cloning (PVC), unlike Instant Voice Cloning (IVC) which lets you clone voices with very short samples nearly instantaneously, allows you to train a hyper-realistic model of a voice. This is achieved by training a dedicated model on a large set of voice data to produce a model that’s indistinguishable from the original voice.

Since the custom models require fine-tuning and training, it will take a bit longer to train these Professional Voice Clones compared to the Instant Voice Clones. Giving an estimate is challenging as it depends on the number of people in the queue before you and a few other factors.

Here are the current estimates for Professional Voice Cloning:

*   **English:** \~3 hours
*   **Multilingual:** \~6 hours

## Voice Creation

There are a few things to be mindful of before you start uploading your samples, and some steps that you need to take to ensure the best possible results.

Firstly, Professional Voice Cloning is highly accurate in cloning the samples used for its training. It will create a near-perfect clone of what it hears, including all the intricacies and characteristics of that voice, but also including any artifacts and unwanted audio present in the samples. This means that if you upload low-quality samples with background noise, room reverb/echo, or any other type of unwanted sounds like music on multiple people speaking, the AI will try to replicate all of these elements in the clone as well.

Secondly, make sure there's only a single speaking voice throughout the audio, as more than one speaker or excessive noise or anything of the above can confuse the AI. This confusion can result in the AI being unable to discern which voice to clone or misinterpreting what the voice actually sounds like because it is being masked by other sounds, leading to a less-than-optimal clone.

Thirdly, make sure you have enough material to clone the voice properly. The bare minimum we recommend is 30 minutes of audio, but for the optimal result and the most accurate clone, we recommend closer to 3 hours of audio. You might be able to get away with less, but at that point, we can’t vouch for the quality of the resulting clone.

Fourthly, the speaking style in the samples you provide will be replicated in the output, so depending on what delivery you are looking for, the training data should correspond to that style (e.g. if you are looking to voice an audiobook with a clone of your voice, the audio you submit for training should be a recording of you reading a book in the tone of voice you want to use). It is better to just include one style in the uploaded samples for consistencies sake.

Lastly, it’s best to use samples speaking where you are speaking the language that the PVC will mainly be used for. Of course, the AI can speak any language that we currently support. However, it is worth noting that if the voice itself is not native to the language you want the AI to speak - meaning you cloned a voice speaking a different language - it might have an accent from the original language and might mispronounce words and inflections. For instance, if you clone a voice speaking English and then want it to speak Spanish, it will very likely have an English accent when speaking Spanish. We only support cloning samples recorded in one of our supported languages, and the application will reject your sample if it is recorded in an unsupported language.

For now, we only allow you to clone your own voice. You will be asked to go through a verification process before submitting your fine-tuning request.

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Good%20example&small=true&preview=true&audioSrc=https%3A%2F%2Fstorage.googleapis.com%2Feleven-public-cdn%2Faudio%2Fdocs%2Fgood_example.wav`} />

<iframe width="100%" height={90} frameBorder="no" scrolling="no" src={`https://elevenlabs.io/player/index.html?title=Bad%20example&small=true&preview=true&audioSrc=https%3A%2F%2Fstorage.googleapis.com%2Feleven-public-cdn%2Faudio%2Fdocs%2Fbad_example.wav`} />

*   **Professional Recording Equipment:** Use high-quality recording equipment for optimal results as the AI will clone everything about the audio. High-quality input = high-quality output. Any microphone will work, but an XLR mic going into a dedicated audio interface would be our recommendation. A few general recommendations on low-end would be something like an Audio Technica AT2020 or a Rode NT1 going into a Focusrite interface or similar.
*   **Use a Pop-Filter:** Use a Pop-Filter when recording. This will minimize plosives when recording.
*   **Microphone Distance:** Position yourself at the right distance from the microphone - approximately two fists away from the mic is recommended, but it also depends on what type of recording you want.
*   **Noise-Free Recording:** Ensure that the audio input doesn't have any interference, like background music or noise. The AI cloning works best with clean, uncluttered audio.
*   **Room Acoustics:** Preferably, record in an acoustically-treated room. This reduces unwanted echoes and background noises, leading to clearer audio input for the AI. You can make something temporary using a thick duvet or quilt to dampen the recording space.
*   **Audio Pre-processing:** Consider editing your audio beforehand if you're aiming for a specific sound you want the AI to output. For instance, if you want a polished podcast-like output, pre-process your audio to match that quality, or if you have long pauses or many "uhm"s and "ahm"s between words as the AI will mimic those as well.
*   **Volume Control:** Maintain a consistent volume that's loud enough to be clear but not so loud that it causes distortion. The goal is to achieve a balanced and steady audio level. The ideal would be between -23dB and -18dB RMS with a true peak of -3dB.
*   **Sufficient Audio Length:** Provide at least 30 minutes of high-quality audio that follows the above guidelines for best results - preferably closer to 3 hours of audio. The more quality data you can feed into the AI, the better the voice clone will be. The number of samples is irrelevant; the total runtime is what matters. However, if you plan to upload multiple hours of audio, it is better to split it into multiple \~30-minute samples. This makes it easier to upload.
*   **Uploading:** After pressing upload, you will not be able to make any changes to the clone and it will be locked in. Ensure that you have uploaded the correct samples that you want to you.
*   **Verify Your Voice:** Once everything is recorded and uploaded, you will be asked to verify your voice. To ensure a smooth experience, please try to verify your voice using the same or similar equipment used to record the samples and in a tone and delivery that is similar to what was present in the samples. If you do not have access to the same equipment, try verifying the best you can. If it fails, you will have to reach out to support.

Keep in mind that all of this depends on the output you want. The AI will try to clone everything in the audio, but for the AI to work optimally and predictably, we suggest following the guidelines mentioned above.

Once you've uploaded your samples, there are four stages of the cloning process that you might see on your voice card.

*   **Verify:** This means that they have uploaded the voice samples, but you have not yet finished the verification step. You will need to finish this step before it can start training.
*   **Processing:** This means that the voice has been verified and is preprocessing, ready to be trained. When you've reached this step, the rest is automatic, and you will not need to do anything.
*   **Fine-tuning:** This is when the voice is actually training. Along with this label, you will also see a loading bar to show you the progress.
*   **Fine-tuned:** This means the voice has finished training and is ready to be used!

## Scripts

What you read is not very important; how you read it is very important, however. The AI will try to mimic everything it hears in a voice: the tonal quality, the accent, the inflection, and many other intricate details. It will replicate how you pronounce certain words, vowels, and consonants, but not the actual words themselves. So, it is better to choose a text or script that conveys the emotion you want to capture, and read in a tone of voice you want to use.

*   [Audiobook](/product/voices/voice-lab/scripts/the-great-gatsby)
*   [News Article](/product/voices/voice-lab/scripts/news-article)
*   [Social Media](/product/voices/voice-lab/scripts/social-media)
*   [Meditation](/product/voices/voice-lab/scripts/meditation)
*   [Elearning](/product/voices/voice-lab/scripts/elearning)


# Voice Design

Generate a unique voice from a text prompt.

Voice Design helps creators fill the gaps when the exact voice they are looking for isn’t available in the Voice Library. Now if you can’t find a suitable voice for your project, you can create one.  Note that Voice Design is highly experimental and Professional Voice Clones are still the highest quality voices on our platform. If there is a PVC available in our library that fits your needs, we recommend using it.

You can find Voice Design by heading to Voices -> My Voices -> Add a new voice -> Voice Design.

When you hit generate, we'll generate three voice options for you. The only charge for using voice design is the number of credits to generate your preview text, which you are only charged once even though we are generating three samples for you. You can see the number of characters that will be deducated in the "Text to preview" text box.

After generating, you'll have the option to select and save one of the generations, which will take up one of your voice slots.

## Voice Design Prompt Guide

### Voice Design Types

| Type                   | Description                                                                                                                     | Example Prompts                                                                                                                                                                                                                                                                                                                                                                      |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Realistic Voice Design | Create an original, realistic voice by specifying age, accent/nationality, gender, tone, pitch, intonation, speed, and emotion. | - "A young Indian female with a soft, high voice. Conversational, slow and calm."<br /> - "An old British male with a raspy, deep voice. Professional, relaxed and assertive."<br /> - "A middle-aged Australian female with a warm, low voice. Corporate, fast and happy."                                                                                                          |
| Character Voice Design | Generate unique voices for creative characters using simpler prompts.                                                           | - "A massive evil ogre, troll"<br />- "A sassy little squeaky mouse"<br />- "An angry old pirate, shouting" <br /><br /> Some other characters we've had success with include Goblin, Vampire, Elf, Troll, Werewolf, Ghost, Alien, Giant, Witch, Wizard, Zombie, Demon, Devil, Pirate, Genie, Ogre, Orc, Knight, Samurai, Banshee, Yeti, Druid, Robot, Elf, Monkey, Monster, Dracula |

### Voice Attributes

| Attribute          | Importance      | Options                                                             |
| :----------------- | :-------------- | :------------------------------------------------------------------ |
| Age                | High Importance | Young, Teenage, Adult, Middle-Aged, Old, etc...                     |
| Accent/Nationality | High Importance | British, Indian, Polish, American, etc...                           |
| Gender             | High Importance | Male, Female, Gender Neutral                                        |
| Tone               | Not Needed      | Gruff, Soft, Warm, Raspy, etc...                                    |
| Pitch              | Not Needed      | Deep, Low, High, Squeaky, etc...                                    |
| Intonation         | Not Needed      | Conversational, Professional, Corporate, Urban, Posh, etc...        |
| Speed              | Not Needed      | Fast, Quick, Slow, Relaxed, etc...                                  |
| Emotion/Delivery   | Not Needed      | Angry, Calm, Scared, Happy, Assertive, Whispering, Shouting, etc... |


# Overview

Discover AI voices from the ElevenLabs community

The [Voice Library](https://elevenlabs.io/voice-library) (VL) is a marketplace where our community can share voices and earn rewards when they're used. At the moment, only Professional Voice Clones (PVCs) can be shared in the library. Instant Voice Clones (IVCs) cannot be shared for safety reasons.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/library.png" />

## Using voices from the Voice Library

You can play a sample for any voice in the Voice Library by clicking it.

To use a voice from the Voice Library, you first need to add it to My Voices. To do this, click "Add". This will save it to My Voices using the default name for the voice. You can use it directly from the Voice Library by clicking "Use", which will open Speech Synthesis with the voice selected.

Once the voice has been added to My Voices, it will appear in the voice selection menu across all features.

## Details view

You can find out more information about a voice by clicking "View". This opens up a pane on the right which contains more information. Here you can see all the tags associated with the voice, including:

*   the language it was trained on
*   the age and gender of the voice
*   the category, for example, "Conversational"
*   how long the notice period is, if the voice has one
*   if the voice has been labelled as High Quality
*   what type of voice it is, for example, Professional Voice Clone

You can also see how many users have saved the voice to My Voices, and how many characters of audio have been generated with the voice.

Finally, you can also see suggestions of similar voices, and can play samples and add these to My Voices if you want.

### Category

Some labels tell you about the type of voice:

<Info>
  Voice Design voices are no longer shareable in the Voice Library; however, the
  legacy shared voices will remain accessible.
</Info>

<Card
  title="Voice Design"
  icon={
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 24 24"
     fill="gray"
     class="w-6 h-6"
     display="inline-block"
   >
     <path
       fill-rule="evenodd"
       d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z"
       clip-rule="evenodd"
     />
   </svg>
  }
>
  Generated voices made using **[Voice
  Design](/product/voices/voice-lab/voice-design)**
</Card>

<Card
  title="Professional Voice Clone"
  icon={
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 24 24"
     fill="#fbbf24"
     class="w-6 h-6"
   >
     <path
       fill-rule="evenodd"
       d="M8.603 3.799A4.49 4.49 0 0 1 12 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 0 1 3.498 1.307 4.491 4.491 0 0 1 1.307 3.497A4.49 4.49 0 0 1 21.75 12a4.49 4.49 0 0 1-1.549 3.397 4.491 4.491 0 0 1-1.307 3.497 4.491 4.491 0 0 1-3.497 1.307A4.49 4.49 0 0 1 12 21.75a4.49 4.49 0 0 1-3.397-1.549 4.49 4.49 0 0 1-3.498-1.306 4.491 4.491 0 0 1-1.307-3.498A4.49 4.49 0 0 1 2.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 0 1 1.307-3.497 4.49 4.49 0 0 1 3.497-1.307Zm7.007 6.387a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
       clip-rule="evenodd"
     />
   </svg>
  }
>
  Voices made using **[Professional Voice
  Cloning](/product/voices/voice-lab/professional-voice-cloning)**
</Card>

<Card title="HQ">
  The HQ label stands for High Quality, and indicates that this Professional
  Voice Clone has been trained on audio which follows our **[Professional
  Recording Guidelines](/product/voices/voice-lab/professional-voice-cloning)**
  and has passed a quality control check on input texts of various lengths.
</Card>

### Sharing Options

Other labels tell you about options the voice owner set when sharing the voice. Please see the **[Sharing](/product/voices/voice-library/sharing)** page for more details.

<Card
  title="Notice Period"
  icon={
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 24 24"
     fill="none"
     class="w-3.5 h-3.5"
   >
     <path
       stroke="currentColor"
       stroke-linecap="round"
       stroke-linejoin="round"
       d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
       stroke-width="1.5"
     ></path>
   </svg>
  }
>
  <p>
    A label with a clock icon indicates that the voice has a Notice Period in
    place. The Notice Period lets you now how long you'll continue to have
    access to the voice if the voice owner decides to remove it from the Voice
    Library.
  </p>
</Card>

<Card title="Credit Multiplier">
  Some voices have a credit multiplier in place. This is shown by a label
  displaying, for example, x2 multiplier or x3 multiplier. This means that the
  voice owner has set a custom rate for use of their voice. Please pay close
  attention, as credit multipliers mean your account will be deducted >1x the
  number of credits when you generate using a voice that has a credit
  multiplier.
</Card>

<Card
  title="Live Moderation"
  icon={
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 24 24"
     fill="none"
     class="w-3.5 h-3.5"
   >
     <path
       d="M11.302 21.6149C11.5234 21.744 11.6341 21.8086 11.7903 21.8421C11.9116 21.8681 12.0884 21.8681 12.2097 21.8421C12.3659 21.8086 12.4766 21.744 12.698 21.6149C14.646 20.4784 20 16.9084 20 12V7.21759C20 6.41808 20 6.01833 19.8692 5.6747C19.7537 5.37113 19.566 5.10027 19.3223 4.88552C19.0465 4.64243 18.6722 4.50207 17.9236 4.22134L12.5618 2.21067C12.3539 2.13271 12.25 2.09373 12.143 2.07827C12.0482 2.06457 11.9518 2.06457 11.857 2.07827C11.75 2.09373 11.6461 2.13271 11.4382 2.21067L6.0764 4.22134C5.3278 4.50207 4.9535 4.64243 4.67766 4.88552C4.43398 5.10027 4.24627 5.37113 4.13076 5.6747C4 6.01833 4 6.41808 4 7.21759V12C4 16.9084 9.35396 20.4784 11.302 21.6149Z"
       stroke="currentColor"
       stroke-width="1.5"
       stroke-linecap="round"
       stroke-linejoin="round"
     ></path>
   </svg>
  }
>
  Some voices have "Live Moderation" enabled. This is indicated with a label
  with a shield icon. When you generate using a voice with Live Moderation
  enabled, we use tools to check whether the text being generated belongs to a
  number of prohibited categories. This may introduce extra latency when using
  the voice, and voices with Live Moderation enabled cannot be used in Projects.
</Card>

## Filters, Sorting, and Search

To help you find the perfect voice for you, the Voice Library is searchable and filterable.

### Search box

You can use the search box to search by name, keyword and voice ID. You can also search by dragging and dropping an audio file, or uploading a file by clicking the upload icon. This will return the voice used, if it can be found, along with similar voices.

### Sort by

You have a number of options for sorting voices in the Voice Library:

*   Trending: voices are ranked by our trending algorithm
*   Latest: newest voices are shown first
*   Most users
*   Most characters generated

### Language filter

The language filter allows you to return only voices that have been trained on audio in a specific language. While all voices are compatible with our multilingual models and can therefore be used with all 32 languages we support, voices labelled with a specific language should perform well for content in that language

### Accent filter

If you select a specific language, the Accent filter will also become available. This allows you to look for voices with specific accents.

### More filters

Click the "More filters" button to access additional filters.

#### Category

*   Voice Design
*   Professional
*   High-Quality

#### Gender

*   Male
*   Female
*   Neutral

#### Age

*   Young
*   Middle Aged
*   Old

#### Use case

You can click the use case of your choice to show only voices that have been labelled with this use case.


# Payouts

Earn rewards for sharing voices in the Voice Library

The [Payouts](https://elevenlabs.io/payouts) (VL) system allows you to earn rewards for sharing voices in the Voice Library. ElevenLabs uses <a href="https://stripe.com/connect">Stripe Connect</a> to process payments.

## Account setup

To set up your Payouts account:

*   Go to "Payouts" in the sidebar and click "Create Payout Account"
    <Frame>
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/payouts-connect.jpeg" />
    </Frame>
*   Follow the prompts from Stripe Connect to finish setting up your account

## Tracking usage and earnings

*   You can track the usage of your voices by going to your <a href="/product/voices/voice-lab/overview">My Voices</a>, clicking "View" to open the detailed view for your voice, then clicking the sharing icon at the bottom. Once you have the Sharing Options open, click "View Metrics".

*   The rewards you earn are based on the options you selected when <a href="/product/voices/voice-library/sharing">sharing your voice in the Voice Library</a>.

    <Frame>
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/rewards.png" />
    </Frame>

*   You can also see your all-time earnings and past payouts by going back to your Payouts page

    <Frame>
      <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/payouts.png" />
    </Frame>

## Reader App Rewards

*   If your voice is marked as **[High-Quality](/product/voices/voice-library/overview#category)** and you have activated the "Available in ElevenReader" toggle, your voice will made be available in the ElevenReader. Rewards for ElevenReader are reported separately – to view your Reader App rewards, check the "ElevenReader" box on your "View Metrics" screen.
    <Frame>
      <img width="200" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/reader-availability.png" />
    </Frame>

## Things to know

*   Rewards accumulate frequently throughout the day, but payouts typically happen once a week as long as you have more than \$10 in accrued payouts. You can see your past payouts by going to your [Payouts](https://elevenlabs.io/app/payouts) page in the sidebar.

## Supported Countries

*   Currently, Stripe Connect is not supported in all countries. We are constantly working to expand our reach for Payouts and plan to add availability in more countries when possible.

<Accordion title="Currently supported countries">
  *   Argentina - Australia - Austria - Belgium - Bulgaria - Canada - Chile -
      Colombia - Croatia - Cyprus - Czech Republic - Denmark - Estonia - Finland -
      France - Germany - Greece - Hong Kong SAR China - Hungary - Iceland - India -
      Indonesia - Ireland - Israel - Italy - Japan - Latvia - Liechtenstein -
      Lithuania - Luxembourg - Malaysia - Malta - Mexico - Monaco - Netherlands -
      New Zealand - Nigeria - Norway - Peru - Philippines - Poland - Portugal -
      Qatar - Romania - Saudi Arabia - Singapore - Slovakia - Slovenia - South
      Africa - South Korea - Spain - Sweden - Switzerland - Thailand - Taiwan -
      Turkey - United Arab Emirates - United Kingdom - United States - Uruguay -
      Vietnam
</Accordion>


# Sharing Voices

Learn how to share voices in the Voice Library.

## How to share a voice model in the Voice Library:

**1. Share Button:** To get started with sharing a voice model, find the voice model you want to share in <a href="product/voices/voice-lab/overview">My Voices</a> and click the share icon:

<Frame>
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/share_voice_start.png" />
</Frame>

**2. Sharing Toggle:** Next, activate sharing by enabling the "Sharing" toggle. Note that this doesn’t make your voice model automatically discoverable in the Voice Library.

<Frame>
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/share_voice_2.png" />
</Frame>

**3. Sharing Link/Email Whitelist:** Once the "Sharing" toggle is enabled, you have a few ways to share your Voice Model:

<Frame>
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/share_voice_3.png" />
</Frame>

*   **Sharing Link:** share this link with your audience, your friends, or anyone else that you want to be able to make a copy of your voice model in My Voices.
*   **Email Whitelist:** you can specify specific emails to restrict who can make copies of your voice model in My Voices using your Sharing Link. If you leave the whitelist blank, all emails will be enabled by default.
*   **Discovery in Voice Library:** this makes your voice model discoverable in the Voice Library and takes you to the sharing dialog detailed in Step 4 below.

**4. Library Sharing Options:** if you enable "Discovery in Voice Library", you’ll be brought to a dialog screen where you can configure a few options for sharing your voice model in the Voice Library:

<Frame>
  <img width="400" height="100%" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/voices/voice-library/images/share_voice_4.png" />
</Frame>

Please see the [Voice Library Addendum](https://elevenlabs.io/vla) to our Terms of Service for full descriptions of these options.

**5. Naming Guidelines:** Please ensure the name you give your voice model adheres to the guidelines shown in the sharing dialog:

*   The naming pattern should be a one-word name followed by a 2-4 word description, separated by a hyphen (-).

*   Your name should NOT include the following:

    *   Names of public individuals or entities (company names, band names, influencers or famous people, etc).
    *   Social handles (Twitter, Instagram, you name it, etc).
    *   ALL CAPS WORDS.
    *   Emojis and any other non-letter characters.
    *   Explicit or harmful words.
    *   The word “voice”.

*   Some examples of names following our guidelines:
    *   Anna - calm and kind
    *   Robert - friendly grandpa
    *   Steve - wise teacher
    *   Harmony - soothing serenader
    *   Jasper - jovial storyteller
    *   Maya - confident narrator

**6. Scroll and accept terms:** Before sharing your voice model in the Voice Library, you’ll be asked to scroll and accept the [Voice Library Addendum](https://elevenlabs.io/terms#VLA) to our [Terms of Service](https://elevenlabs.io/terms) and provide additional consents and confirmations. Please do this carefully and ensure you fully understand our service before sharing. If you have any questions at this stage, you can reach out to us at [legal@elevenlabs.io](mailto:legal@elevenlabs.io).

Before you share your voice to the Voice Library, we have a few guidelines that need to be followed. These guidelines are in place to ensure better discoverability and to maintain a clean and organized appearance for everyone using the platform. Please take the time to read through the guidelines below. They will help you understand how you should name, categorize, and tag your voice to enhance the overall experience for users.

### Review

Once you’ve created, named, and shared your voice, it will be set for pending review. This means that someone from the ElevenLabs team will go through your voice to ensure that it adheres to the guidelines outlined above. If there are significant issues, your request to share the voice model will be declined. If only small changes are required, the team might make these adjustments for you and approve the voice model for sharing.

As part of the review process, our team may add labels to your voice model to make it discoverable using the filters for the Voice Library:

*   Gender
*   Accent
*   Language (the language of the source audio used to create your PVC)
*   Age
*   Use case
*   Descriptive

Consistently uploading voices that do not adhere to the guidelines or are highly explicit in nature might result in being barred from uploading and sharing voices altogether. Therefore, please adhere to the guidelines.

Currently, we do not have an estimate of how long the review process will take, as it is highly dependent on the length of the queue.


# Overview

An overview on how teams can collaborate in a shared workspace.

<Info>
  {" "}

  Workspaces are currently only available for Enterprise customers. To upgrade, [get
  in touch with our sales team](https://elevenlabs.io/enterprise).
</Info>

For teams that want to collaborate in ElevenLabs, we offer shared workspaces. Workspaces offer 4 benefits:

*   Shared billing: Rather than having each of your team members individually create & manage subscriptions, all of your team’s character usage and billing is centralized under one workspace.
*   Shared resources: Within a workspace, your team can share custom voices and soon will be able to share Projects and Dubbing Studio instances.
*   Access management: Your workspace admin can easily add and remove team members.
*   API Key management: You can issue and revoke unlimited API keys for your team.

## Creating a Workspace

Workspaces are automatically enabled for all Enterprise clients. When setting up your account, you’ll be asked to nominate a workspace admin who will have the power to add more team members as well as nominate others to be an admin.

## Adding team members

<Info> Only admins can add and remove team members. </Info>

To access your workspace settings, select your profile in the bottom left of the dashboard and choose Workspace Settings.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/home_page.png" />

You’ll be greeted with a model (shown below) where you can add team members via email and specify whether they should be a Member or Admin. We describe the different roles below.

<img height="200" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/add_team.png" />

## Roles

There are two roles, Admins and Members. Members have full access to your workspace and can generate an unlimited number of characters (within your current overall plan’s limit).

Admins have all of the access of Members, with the added ability to add / remove teammates and permissions to manage your subscription.

## Managing Billing

<Info> Only admins can manage billing. </Info>

To manage your billing, select your profile in the bottom left of the dashboard and choose Subscription. From there, you’ll be able to update your payment information and access past invoices.

## Managing API Keys

To manage your API keys, select your profile in the bottom left of the dashboard and choose Workspace Settings. From there you’ll be able to issue & revoke API keys.


# SSO Setup

An overview on how to setup SSO (Single Sign-On) for your team.

<Info> Only workspace admins can use this feature. </Info>

Single Sign-On (SSO) allows your team to log in to ElevenLabs by using your existing identity provider. This means that your team can use the same credentials which they use for other services to log in to ElevenLabs.

## Choosing identity providers

To access your SSO settings, click on your profile icon located at the bottom left of the dashboard, select Workspace Settings, and then navigate to the SECURITY & SSO tab.

You can choose from a variety of identity providers, including Google, Okta, GitHub, etc. The organization SSO provider will only appear in this list after it has been configured shown in the `Configure SSO` section.

<img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/identity_providers.png" />

If you disable any of the identity providers, your team members will log out if they're using the disabled providers. They will be able to log back into the same account with any of the allowed providers if they are using the same email.

## Verifying your email domain

Next, you need to verify your email domain for authentication. This step confirms to ElevenLabs that you own the domain you are configuring for SSO. This is a security measure to prevent unauthorized access to your workspace.

*   Click on the `Verify domain` button.

<img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/verify_domain_button.png" />

*   Enter the domain name you want to verify.

<img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/domain_verification.png" />

*   You'll be prompted to add a DNS TXT record to the DNS settings of your domain. An example text is as below. You can contact your domain administrator or IT team for help with this step. Once the DNS record is added, click on the `Verify` button again.

<img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/dns_records.png" />

*   Once the domain is successfully verified, the status of your domain will change to `Passed`.

## Configure SSO

ElevenLabs support both OIDC (OpenID Connect) and SAML (Security Assertion Markup Language) for SSO. You can set up SSO for your domain by following the steps outlined below.

### Create an OIDC configuration

ElevenLabs OIDC integration only supports the [Authorization Code Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow).

To configure SSO with OIDC, you'd need:

*   Client Id for your application
*   Client Secret for your application
*   Issuer URL (The url of the authentication server)

and you'd need to use the information below from ElevenLabs:

*   Redirect URL: use the greyed out link at the bottom of the SECURITY & SSO tab in Workspace Settings.

Steps:

*   Register an OIDC application with your identity provider.
*   Add the information of required fields (Client Id, Issuer URL, etc.) to ElevenLabs SSO provider form.
    <img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/sso_oidc.png" />
*   Click on `Add Domain` Button and choose the domain you want to enable SSO for from the list of verified domains.
    <img height="50" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/add_domains.png" />
*   Click on the `Update SSO` button.

### Create a SAML configuration

<Info> Only SP-initiated SSO is supported for SAML.</Info>

Concepts:

*   **Service Provider (SP)**: the entity providing the service. This is ElevenLabs in this case.
*   **Identy Provider (IdP)**: the entity that authenticates the user and provides the user's identity to the SP. This is your authentication server.
*   **SAML request**: a request from the SP to the IdP to authenticate the user.
*   **SAML response**: a response from the IdP to the SP containing the user's identity.
*   **Redirect URL**: the endpoint where the SAML response is posted.

To configure SSO with SAML, you'd need to provide ElevenLabs the following details:

*   Identity Provider Entity Id
*   Identity Provider Sign-In URL (The endpoint where SAML requests are posted)
*   Certificate (Digital signature)

and you'd need to use the information below from ElevenLabs:

*   Service Provider Entity Id: use the value (e.g. `https://elevenlabs.io`) provided in the SSO provider form in the SECURITY & SSO tab in Workspace Settings.
*   Redirect URL: this is the endpoint where the IdP sends the SAML response; Use the greyed out link at the bottom of the SECURITY & SSO tab in Workspace Settings.

Steps:

*   Register a SAML application with your identity provider; fill in required fields (SP entity id, redirect URL).
*   Add the information of required fields (IdP Entity Id, IdP Sign-In URL, etc.) to the ElevenLabs SSO form.
    <img height="150" src="https://mintlify.s3-us-west-1.amazonaws.com/elevenlabs-docs/product/workspace/images/sso_saml.png" />
*   Click on `Add Domain` Button and choose the domain you want to enable SSO for from the list of verified domains.
*   Click on the `Update SSO` button.

### FAQ

**Microsoft Entra Identifier (or Azure AD) - SAML**

What shall I fill for Identifier (Entity ID)?

*   Use Service Provider Entity Id

What shall I fill for Reply URL (Assertion Consumer Service) URL in SAML?

*   Use Redirect URL

What is ACS URL?

*   Same as Assertion Consumer Service URL

Which fields should I use to provide ElevenLabs?

*   Use *Microsoft Entra Identifier* for IdP Entity ID
*   Use *Login URL* for IdP Sign-In URL

**Login Error via SAML**

What shall I do if I get the error "Unable to login with saml.workspace..."?

*   One known error: make sure you have `<saml:NameID>` having email address as the value inside `<saml:Subject>` in the SAML response. We use Google Cloud as our identity platform and it expects the `<saml:Subject>` and `<saml:NameID>` elements in responses from the identity provider. If you don't define values for these elements when configuring your provider, the SAML assertion fails.