Skip to main content
Version: v5.3.0

TTS Providers

A provider is a text-to-speech service that OpenReader sends text to. Admins add providers in Settings → Admin → Providers, and everyone on the instance can use the enabled ones. Users pick a provider, model and voice in Settings → Model & Voice, and can choose a different voice for each book from the player (see Reading and Listening).

API keys stay on the server, encrypted (see How saved keys are protected). Users never see them. Speech is generated by the compute worker, so the worker is the one that connects to each provider.

Provider types​

TypeWhat it isNeeds
KokoroKokoro-82M running inside the compute worker. English only, with 28 American and British voices that can be blended.Nothing; voice data (about 336 MB) downloads the first time it speaks.
Custom OpenAI-likeAny server with an OpenAI-compatible speech endpoint, such as Kokoro-FastAPI, KittenTTS-FastAPI, Orpheus-FastAPI or Supertonic.Base URL; API key if the server requires one.
OpenAIOpenAI's speech API (tts-1, tts-1-hd, gpt-4o-mini-tts).API key.
ReplicateHosted models on Replicate, from a built-in list or any model ID.API key.
DeepinfraHosted models on DeepInfra, including Kokoro-82M.API key.
Speech SDKElevenLabs, Cartesia, Deepgram, Google, Hume, Inworld and others through one provider.The API key of the model's own service.

Setup guides for specific services are listed under TTS Providers in the sidebar.

Add a provider​

In Settings → Admin → Providers, add a provider and fill in:

FieldNotes
SlugA short identifier such as kokoro-prod: lowercase letters, numbers and hyphens.
Display nameWhat users see in their provider list.
Provider typeOne of the types above.
Default modelThe model users start with. Choose from the type's list, or enter a custom model ID.
TTS instructionsOnly for models that accept speaking instructions, such as gpt-4o-mini-tts.
Base URLFor types that take one, typically ending in /v1. Leave blank to use the type's default.
API keyWhen editing, leave it blank to keep the saved key.
EnabledTurn off to hide the provider from users without deleting it.

Choose Check before saving. It checks the settings, connects to the service, lists its voices and, for a saved provider, speaks a short sample through the worker. Each result reads OK, Check or Fix, with what to change.

The default provider for new users is set in Instance Settings.

Kokoro voice data​

For a Kokoro provider, the card at the top of Providers shows whether its voice data is downloaded. From there you can download it ahead of time, cancel a download, or remove the data. With several worker replicas, the card manages only the replica that answers.

Pronunciation uses a built-in port of Misaki without espeak, so a few abbreviations (for example St.) are skipped rather than read.

Self-hosted provider addresses​

The compute worker, not the browser, connects to the provider, and the app server connects when it lists voices. A self-hosted base URL must be reachable from both:

SetupBase URL
Native pnpm dev / pnpm start, provider on the same machinehttp://127.0.0.1:<port>/v1
Single Docker container, provider on the Docker hosthttp://host.docker.internal:<port>/v1 (on Linux, add Docker's host-gateway mapping)
Docker ComposeThe provider's service name, such as http://kokoro-tts:8880/v1
Remote worker (Railway or another host)A public, private-network or VPN address reachable from both the app and the worker

localhost always means the current container or process. A remote worker cannot reach a provider on your laptop through it.

Custom server requirements​

A custom server needs only POST /v1/audio/speech. It may return MP3, WAV, OGG or FLAC; OpenReader converts other formats to MP3, so the server does not need to support response_format. An API key is optional.

Voice listing is optional. OpenReader tries /v1/audio/voices, /v1/voices and /v1/styles. If none answer, it offers the Kokoro voices for Kokoro models and the standard OpenAI voices (alloy, echo, fable, onyx, nova, shimmer) otherwise.

Seed a provider from the environment​

On first start, if there are no providers yet and API_BASE or API_KEY is set, OpenReader creates a Custom OpenAI-like provider with the slug default-openai, using API_BASE, API_KEY and API_MODEL_NAME (default kokoro). After that the variables are no longer read; edit or delete the provider in the admin panel like any other. A providers list in RUNTIME_SEED_JSON replaces this behavior (see Environment Variables).

The Docker Compose examples seed a Kokoro-FastAPI provider, and the desktop app seeds the built-in Kokoro.