Developed with Qwen3.7-Max — This project was built by the AI model Qwen3.7-Max.
OpenAI-compatible audio gateway for speech, transcription, sound effects, audio isolation, voice design, and voice cloning.
voxout gives one stable API and one web console for multiple audio providers. Applications can call OpenAI-style endpoints while operators switch providers, manage keys, route models, test voices, and persist provider-specific settings without changing client code.
- OpenAI-compatible surface: use familiar
/v1/audio/*endpoints for speech, transcription, and voice cloning, with Voxout extensions for audio effects, isolation, and voice design. - Multi-provider routing: route by explicit
provideror by model id, so one client can use OpenAI, ElevenLabs, Cartesia, Camb.ai, MiMo, Gradium, StepFun, and the built-in default provider. - More than TTS: speech synthesis, streaming speech, ASR, text-to-sound, vocal/background separation, generated voice previews, and custom voice cloning share the same gateway.
- Provider-neutral voices: store one Voxout voice record and link it to provider-specific voice ids or accounts.
- Operational console: configure providers, API keys, models, voices, and test requests from the built-in React UI.
- Self-hostable: run as a Node service, a Docker image, or split the static frontend behind any reverse proxy.
| Provider | Capabilities |
|---|---|
default |
Microsoft Edge online TTS and Bilibili/Bcut file-upload ASR |
openai |
TTS, ASR, custom voice cloning |
elevenlabs |
TTS, streaming TTS, ASR, sound effects, isolation, voice design, voice cloning |
cartesia |
TTS, streaming TTS, ASR, voice listing, voice cloning |
cambai |
TTS, streaming TTS, ASR, text-to-sound, audio separation, voice design, voice cloning |
mimo |
Xiaomi MiMo TTS, preset voices, voice design, ASR |
gradium |
TTS, streaming TTS, ASR, voice listing, voice cloning |
stepfun |
TTS, streaming TTS, ASR streaming, system/cloned voices, voice cloning |
boson |
TTS, streaming TTS, preset/custom voices, voice cloning, avatar video generation |
Provider availability depends on your configured API keys and the upstream
account plan. The built-in default provider is useful for getting started, but
production deployments should configure the providers that match your quality,
latency, language, and cost requirements.
OpenAI-compatible endpoints:
GET /v1/modelsPOST /v1/audio/speechPOST /v1/audio/transcriptionsPOST /v1/audio/voices
Voxout extension endpoints:
POST /v1/audio/effectPOST /v1/audio/isolationPOST /v1/audio/voices/designPOST /v1/audio/voices/create
Management endpoints:
GET /healthGET /api/providersGET /api/providers/:provider_id/voicesGET /api/voices?provider=:provider_idGET /api/providers/:provider_id/api-keysPOST /api/providers/:provider_id/api-keysPUT /api/providers/:provider_id/config
For detailed field mapping, provider-specific behavior, and compatibility notes, see API.md.
Requirements:
- Node.js 20+
- npm
- Optional MySQL database for persisted provider settings and API keys
npm install
cp .env.example .env
npm run build
npm startOpen the console at:
http://127.0.0.1:4177/
Without DATABASE_URL, provider settings fall back to in-memory behavior where
supported. Set DATABASE_URL when you want configuration, API keys, and voice
records to survive restarts.
Build and run the image:
docker build -t voxout:latest .
docker run --rm -p 4177:4177 \
-e PORT=4177 \
-e TTS_AUDIO_DIR=/app/audio \
-v "$PWD/audio:/app/audio" \
voxout:latestWith MySQL persistence:
docker run --rm -p 4177:4177 \
-e PORT=4177 \
-e DATABASE_URL='mysql://user:password@mysql-host:3306/voxout' \
-e TTS_AUDIO_DIR=/app/audio \
-v "$PWD/audio:/app/audio" \
voxout:latestOn startup, the Docker image runs Prisma database synchronization when
DATABASE_URL is present, then starts node dist/server.js.
Core environment variables:
| Variable | Purpose |
|---|---|
PORT |
HTTP port, default 4177 |
DATABASE_URL |
Optional MySQL connection string for persisted settings |
TTS_AUDIO_DIR |
Directory for generated/static audio files |
TTS_SYNTHESIS_TIMEOUT_MS |
Optional upstream request timeout override |
FREESOUND_API_KEY |
Optional token for /api/search Freesound proxy |
Provider credentials are managed through the web console or the
/api/providers/:provider_id/api-keys API. API keys are stored separately from
provider config, can be weighted, and are selected at runtime for upstream
requests.
Enable and configure a provider through the API:
curl -X PUT http://127.0.0.1:4177/api/providers/cambai/config \
-H 'content-type: application/json' \
--data '{"enabled":true,"config":{"default_language":"en-us"}}'Add a provider API key:
curl -X POST http://127.0.0.1:4177/api/providers/cambai/api-keys \
-H 'content-type: application/json' \
--data '{"name":"main","api_key":"YOUR_PROVIDER_KEY","weight":1,"enabled":true}'curl -X POST http://127.0.0.1:4177/v1/audio/speech \
-H 'content-type: application/json' \
--output speech.mp3 \
--data '{
"provider": "default",
"input": "Hello from voxout.",
"voice": "en-US-JennyNeural",
"response_format": "mp3"
}'curl -N -X POST http://127.0.0.1:4177/v1/audio/speech \
-H 'content-type: application/json' \
--output speech.pcm \
--data '{
"provider": "mimo",
"input": "Streaming audio from voxout.",
"voice": "Chloe",
"response_format": "pcm",
"stream_format": "audio"
}'curl -X POST http://127.0.0.1:4177/v1/audio/transcriptions \
-F provider=openai \
-F model=gpt-4o-transcribe \
-F response_format=json \
-F language=auto \
-F file=@sample.wavcurl -X POST http://127.0.0.1:4177/v1/audio/effect \
-H 'content-type: application/json' \
--output effect.mp3 \
--data '{
"provider": "elevenlabs",
"instructions": "a short cinematic whoosh",
"duration_seconds": 1.5,
"prompt_influence": 0.3,
"response_format": "mp3"
}'curl -X POST http://127.0.0.1:4177/v1/audio/isolation \
--output isolated.wav \
-F provider=cambai \
-F file=@mix.wav \
-F 'extra_params={"stem":"foreground"}'For Camb.ai, use {"stem":"background"} to return the background track.
curl -X POST http://127.0.0.1:4177/v1/audio/voices/design \
-H 'content-type: application/json' \
--data '{
"provider": "elevenlabs",
"instructions": "A calm narrator voice with a clean tone.",
"input": "This is a preview sentence.",
"name": "Calm Narrator"
}'Then create a stored voice from a selected preview:
curl -X POST http://127.0.0.1:4177/v1/audio/voices/create \
-H 'content-type: application/json' \
--data '{
"provider": "elevenlabs",
"generated_voice_id": "preview_voice_id",
"name": "Calm Narrator",
"instructions": "A calm narrator voice with a clean tone."
}'curl -X POST http://127.0.0.1:4177/v1/audio/voices \
-F provider=openai \
-F name='Narrator Clone' \
-F consent=cons_1234 \
-F audio_sample=@sample.wavvoxout can serve the compiled frontend itself from public/. This is the
simplest deployment: put a reverse proxy in front of the Node service and route
all paths to the same backend.
If you prefer a split deployment, build the frontend and publish public/ to
any static host:
npm run build:web
rsync -a --delete public/ /path/to/static/site/Configure frontend/public/voxout.config.json before building:
{
"api_base_url": ""
}Use an empty api_base_url when the frontend and API share the same origin.
When the frontend is served from a different origin, set it to the public Voxout
API origin, for example:
{
"api_base_url": "https://api.example.com"
}Typical reverse proxy rules:
- Same-origin deployment: proxy
/,/assets/*,/api/*,/v1/*,/audio/*, and/healthto the Voxout service. - Split frontend deployment: serve
/and/assets/*from static hosting, and proxy/api/*,/v1/*,/audio/*, and/healthto the Voxout service.
Run the full build and test suite:
npm testServer-only build:
npm run build:serverFrontend-only build:
npm run build:webFrontend development server:
npm run devProject layout:
src/: server, provider adapters, API routing, persistence helpersfrontend/: React console sourcepublic/: compiled frontend assetsprisma/: Prisma schema and migration helperstests/: provider and API behavior tests
- voxout intentionally normalizes common audio operations while preserving
provider-specific controls through
extra_params. - Some providers expose asynchronous task APIs. Voxout hides the polling flow and returns final audio or normalized JSON where possible.
- Upstream pricing, quotas, supported voices, and model availability are owned by each provider and can change independently of voxout.