Voice and API guide

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.

Who can do what
Creating, cloning, importing, and configuring voices requires a workspace Owner or Admin — other roles will not see the Create voice button. Builders and Reviewers can still browse voices and generate speech in the Playground. Only clone or import a voice when you have the speaker’s permission; the Dashboard requires this confirmation before creating anything.

Navigation

Find the Voices page

Voices and the Playground live in the Text to Speech product area.

  1. 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. 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. 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.

ObjectWhat it containsWhy it matters
VoiceThe canonical workspace identity and voice_id used by TTS requests.Your application refers to one stable voice while operators manage its routes.
Source samplesAuthorized recordings, language, and exact transcript for each recording.These are the source of truth when cloning or refreshing provider copies.
Voice routeOne 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 routeThe ready route preferred when no more specific route is selected.Changing the default does not change the canonical voice_id used by callers.
The voice id appears after the first clone
A newly uploaded sample set is not usable for synthesis yet — its row reads “Voice id assigned on first clone.” Submit at least one provider route and wait for it to reach 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. 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. 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. 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. 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. 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. 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. 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 show Ready before using it.
  8. 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.

Add routeOn the voice page, creates another provider copy from the same samples. Providers already attached are marked Already added and cannot be selected here.
Make defaultMarks a ready route as the one used when callers do not pick a specific route. The default route is always enabled.
EnabledA checkbox on every non-default route. Untick it to hide the route without deleting anything.
Emotion tagsEach route row states Emotion tags or No emotion tags. Only Fish Audio S2 models and ElevenLabs Eleven v3 support tags.
Route statesReady, Cloning, Failed, Blocked, or Update available (the samples changed since this route was created).
Refresh after new samplesIn the Voices list, tick the voice’s checkbox and select Clone to providers, then re-submit the same provider. ElevenLabs appends only the new recordings; other providers rebuild from the full sample set.
History → Route attemptsThe voice’s History tab lists every clone attempt with a plain-language failure summary and technical details. Select Try again on a failed group to resubmit it.

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. 1

    Open Create voice → Import existing

    The third tab of the Create voice dialog.
  2. 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. 3

    Search and preview

    Type a name and select Search. Each result offers an inline audio preview; selecting one fills the Name field.
  4. 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. 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. 2

    Use representative text

    Test names, numbers, abbreviations, domain vocabulary, mixed-language phrases, punctuation, questions, and the emotional range your product needs.
  3. 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. 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. 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. 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. 2

    Name and create the key

    Enter a descriptive Label such as checkout-voice-prod and select Create key.
  3. 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 with awp_. Only a hash is stored, so a lost key must be replaced, not recovered.
  4. 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. 1

    Get a voice id

    Copy it from the voice’s page in the Dashboard, or call GET /v1/voices with your key and pick an id from the response. Use a voice from the same environment as the key.
  2. 2

    Send complete text

    POST /v1/tts with text, voice_id, and an output_format the voice supports. The response body is the audio bytes.
Terminal
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.mp3
See request and response fields

Realtime 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. 1

    Connect

    Open wss://…/v1/tts/stream with your workspace key as a bearer token. To keep the permanent key away from short-lived processes, your backend can instead call POST /v1/tts/stream-tokens and pass the returned 2-minute token.
  2. 2

    Start a generation

    Send the start event with the voice, format, and request options documented in the event reference.
  3. 3

    Append text in order

    Send text chunks as they become available. Signal with stop when no more text will arrive.
  4. 4

    Play audio in order

    Decode each audio chunk using the delivered format. Do not reorder chunks, and handle terminal and error events explicitly.
Open the WebSocket event reference

Common failures

Troubleshooting

SymptomWhy it happensWhat to do
The Create voice button is missingVoice 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 disabledThe 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 FailedThe 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 availableRecordings 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 effectThe 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 voiceThe 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

Production checklist

Keep documented speaker permission and retain the authorized source recordings.
Verify every managed recording has the correct language and exact transcript.
Choose and test a ready default route with representative production text.
Keep workspace API keys on the backend.
Use a voice_id returned for the same workspace and environment.
Set explicit timeouts and handle provider or quota errors.
Respect the selected output format when decoding or storing audio.
Use streaming only when its latency benefit justifies the longer lifecycle.