Create a voice and generate speech
Generate speech in the Playground within minutes using a built-in voice, then clone or import your own voice and call the API. Every step names the exact button you will see.
Start here
Choose a voice path
The shortest path depends on whether the voice already exists. You do not need to clone anything to make your first request.
Use a built-in voice
Every workspace starts with dozens of ready voices across all three providers — rows marked Built-in in the Voices list. Open the Playground, pick one, and generate immediately.
Clone an authorized speaker
Upload clean recordings or record the speaker in the Dashboard, save exact transcripts, confirm permission, then create provider routes.
Import an existing voice
Bring a voice from your ElevenLabs or Fish Audio account, or search the provider’s public library, without uploading a new recording.
Navigation
Find the Voices page
Voices and the Playground live in the Text to Speech product area.
- 1
Sign in to the Dashboard
Open the login page and sign in. If you were invited by a teammate, use the account attached to that invitation. - 2
Switch to the right product
In the top-left corner of the Dashboard, select the Narya.ai product switcher and choose Text to Speech. The sidebar changes to that product’s pages. - 3
Open Voices
Select Voices in the sidebar, or go directly to /operator/voices.
The list shows every usable voice with its status, provider routes, recording and transcript counts, and the voice id once one exists. Built-in voices show Built-in in the Updated column and are ready without any setup.
Voice model
One voice can have multiple routes
Animated Waffle separates the identity of a voice from the provider copies that produce audio.
| Object | What it contains | Why it matters |
|---|---|---|
| Voice | The canonical workspace identity and voice_id used by TTS requests. | Your application refers to one stable voice while operators manage its routes. |
| Source samples | Authorized recordings, language, and exact transcript for each recording. | These are the source of truth when cloning or refreshing provider copies. |
| Voice route | One provider and model combination, provider voice reference, state, and capabilities. | The same voice can be available through ElevenLabs, Fish Audio, or waffle 1.0 beta routes. |
| Default route | The ready route preferred when no more specific route is selected. | Changing the default does not change the canonical voice_id used by callers. |
Ready. Imported and built-in voices already have a usable route.Dashboard workflow
Clone a voice to one or more providers
This is the complete path from an authorized recording to a voice you can select in the Playground, in Agents, and in API requests.
- 1
Open the Create voice dialog
The Create voice button is at the top right of the Voices page. The dialog offers three tabs: Upload, Record, and Import existing. - 2
Upload or record the speaker
Upload accepts clean audio or video of one speaker — no music, no background voices. Record shows a ~10-second script in 中文, 日本語, or English, and saves that script as the transcript automatically. - 3
Name the voice and verify the sample
Enter a Name that identifies the speaker and purpose. For uploads, the Verify the sample block appears: listen once, select the spoken language, and type the exact words into the transcript field (placeholder “Exact words spoken”). - 4
Confirm speaker permission
Tick “I have the speaker's permission to use and clone this voice”. The Create button stays disabled until you do. - 5
Select Create voice
With a complete transcript, the app opens the new voice and immediately shows the Add voice route dialog. If any transcript is still missing, finish it on the voice’s Samples tab first. - 6
Choose providers
Tick the providers that should host this voice: ElevenLabs, Fish Audio, or waffle 1.0 beta. Each uses its recommended model automatically, and the sparkle icon shows whether that route supports emotion tags. Select Add routes. - 7
Watch route progress
The Provider route progress card updates as each provider finishes independently. The canonical voice id appears as soon as the first clone is submitted; wait for at least one route to showReadybefore using it. - 8
Test before relying on it
Select Test in playground in the voice header, generate representative text, and listen before assigning the voice to an Agent or an API integration.
Input quality
Recordings and transcripts
A clone can only reproduce what the recordings make clear. Clean, representative input matters more than volume.
Good source audio
- One speaker, recorded clearly and at a consistent distance.
- No music, overlapping speech, strong room echo, or background noise.
- The language, accent, tone, and delivery you want the generated voice to keep.
- Several clean clips beat many inconsistent ones.
Complete transcripts
- Choose the language actually spoken in each sample.
- Enter every spoken word exactly, including repetitions.
- Replay the sample before saving the transcript.
- Every recording needs a transcript before cloning is allowed.
When you upload several files at once, the dialog warns: “This transcript is saved to the first recording. Add the remaining transcripts on the voice page before cloning.” Open the voice’s Samples tab — the counter (for example 3/4 transcripts) shows what is missing, and each recording row has an Edit button for its language and transcript.
You can select Add recordings on the voice page at any time. New samples reach the providers on the next clone, so existing routes show Update available until you re-clone them (see below).
Provider delivery
Manage routes, defaults, and failures
Routes let one workspace voice use different synthesis providers or models without changing the voice_id your application sends.
No new recordings
Import a voice from a provider
Importing creates a managed voice from a route that already exists in a provider account — useful when the voice was built elsewhere.
- 1
Open Create voice → Import existing
The third tab of the Create voice dialog. - 2
Choose the provider account and catalog
Pick ElevenLabs or Fish Audio, then My voices (voices in the connected account) or Public voice library. - 3
Search and preview
Type a name and select Search. Each result offers an inline audio preview; selecting one fills the Name field. - 4
Choose the Route model and import
Pick the provider model for the route, confirm the permission checkbox, and select Import voice. The voice is usable right away — no samples, no cloning.
Dashboard acceptance
Test the voice with real content
Use the Playground before code so audio-quality problems are separated from integration problems.
- 1
Open the voice → Test in playground
The button in the voice header carries the voice into the Playground. You can also open the Playground directly and pick any ready voice in Settings → Voice. - 2
Use representative text
Test names, numbers, abbreviations, domain vocabulary, mixed-language phrases, punctuation, questions, and the emotional range your product needs. - 3
Add emotion tags where supported
On tag-capable routes, type[to search tags inline, or use Auto Tag to let the editor suggest them. Unsupported routes show a warning and skip the tags. - 4
Tune output settings
Under Settings, choose the Output format (PCM, MP3, AAC, Opus, or μ-law) and an optional Speed override, then select Generate speech. - 5
Review History
Successful generations are saved to the voice’s History → Generations tab with provider, model, tags, format, and playable audio.
API quickstart
Generate your first audio file
A one-shot HTTP request is the shortest path from complete text to a playable audio file.
- 1
Open Integrations in the Dashboard
Sign in at /login, then select Integrations in the sidebar (under the Config group), or go directly to /operator/keys. The page is titled API keys. Only workspace Owners and Admins see it — other roles get “API key management requires an organization Owner or Admin.” - 2
Name and create the key
Enter a descriptive Label such ascheckout-voice-prodand select Create key. - 3
Copy the key immediately
A banner shows the full key exactly once: “Key created. Copy it now, it won’t be shown again.” The key starts withawp_. Only a hash is stored, so a lost key must be replaced, not recovered. - 4
Store it server-side
Put the key in your backend’s secret manager. Never ship it in browser or mobile code — browsers use short-lived tokens instead. The Issued keys table shows each key’s prefix, status, and last-used time, and a Revoke button that disables it immediately.
- 1
Get a voice id
Copy it from the voice’s page in the Dashboard, or callGET /v1/voiceswith your key and pick anidfrom the response. Use a voice from the same environment as the key. - 2
Send complete text
POST/v1/ttswithtext,voice_id, and anoutput_formatthe voice supports. The response body is the audio bytes.
curl --request POST https://animated-waffle.narya.ai/v1/tts \
--header 'Authorization: Bearer awp_your_key_here' \
--header 'Content-Type: application/json' \
--data '{
"text": "Hello from Narya.",
"voice_id": "<id from GET /v1/voices>",
"output_format": "mp3_44100_128"
}' \
--output speech.mp3Realtime output
Stream text and play audio incrementally
Use WebSocket streaming when text arrives incrementally or playback must start before the full text is known. Complete prompts are simpler over HTTP.
- 1
Connect
Openwss://…/v1/tts/streamwith your workspace key as a bearer token. To keep the permanent key away from short-lived processes, your backend can instead callPOST /v1/tts/stream-tokensand pass the returned 2-minute token. - 2
Start a generation
Send the start event with the voice, format, and request options documented in the event reference. - 3
Append text in order
Send text chunks as they become available. Signal with stop when no more text will arrive. - 4
Play audio in order
Decode each audio chunk using the delivered format. Do not reorder chunks, and handle terminal and error events explicitly.
Common failures
Troubleshooting
| Symptom | Why it happens | What to do |
|---|---|---|
| The Create voice button is missing | Voice management is restricted to workspace Owners and Admins. | Ask an Owner or Admin to create or import the voice, or to update your role. |
| Add route or Clone to providers is disabled | The permission checkbox is unconfirmed, a recording is missing its transcript, or there are no recordings. | Open the voice’s Samples tab: complete every transcript (the counter must read n/n) and confirm permission in Settings. |
| The row says “Voice id assigned on first clone” | No provider clone has been submitted for this sample set yet. | Select Add route, submit at least one provider, and wait for a Ready route. |
| A route shows Failed | The provider rejected or could not complete the clone attempt. | Open History → Route attempts, read the failure summary and technical details, fix the cause, then select Try again. |
| A route shows Update available | Recordings changed since that route was cloned. | In the Voices list, tick the voice and select Clone to providers to resubmit the provider with the current samples. |
| Emotion tags have no effect | The route’s model does not support tags — only Fish Audio S2 and ElevenLabs Eleven v3 do. | Switch to a route marked Emotion tags, or remove the tags from the request. |
| The API cannot find the voice | The voice id belongs to another workspace or environment, or the voice has no ready enabled route. | Copy the id again from the voice page or GET /v1/voices with the same key you use for synthesis. |
Before launch