Self-Hosting
Run the entire VoiceLayer stack on your own infrastructure. The SDK and server are MIT licensed — no vendor lock-in.
Why self-host?
- Use your own Deepgram API key — audio data never touches VoiceLayer servers
- Full control over data retention and privacy policies
- No per-minute costs to VoiceLayer (you pay Deepgram directly)
- Deploy on-prem for air-gapped or compliance-sensitive environments
Self-hosting removes managed features: API key auth, usage dashboard, and rate limiting. You'll manage these yourself.
Requirements
- Node.js 18+
- A Deepgram API key (Nova-3 streaming)
- A server that can hold WebSocket connections open (Railway, Render, Fly.io, VPS)
Setup
# Clone the repo
git clone https://github.com/klhenry/voicelayer-sdk
cd voice-layer/packages/server
# Install dependencies
npm install
# Set your Deepgram key
export DEEPGRAM_API_KEY=your_deepgram_key
# Start the server
npm start
# Server running at ws://localhost:3001
Point the SDK at your server
<script
src="https://voicelayer.co/sdk.js"
data-key="any_string"
data-ws-url="wss://your-server.com/ws"
data-show-branding="false">
</script>
Or with npm:
VoiceLayer.init({
apiKey: 'any_string', // not validated when self-hosting
wsUrl: 'wss://your-server.com/ws',
showBranding: false,
});
Environment variables
| Variable | Required | Description |
|---|---|---|
| DEEPGRAM_API_KEY | Yes | Your Deepgram API key for Nova-3 streaming STT |
| PORT | No (default: 3001) | HTTP/WebSocket server port |
| CLERK_SECRET_KEY | No | Enables API key authentication via Clerk (hosted feature) |
Deploy to Railway
cd packages/server
# Install Railway CLI
npm i -g @railway/cli
# Deploy
railway login
railway init
railway up
# Set env vars
railway variables --set "DEEPGRAM_API_KEY=your_key"
Docker
Docker support is coming soon. Track progress on GitHub Issues.
WebSocket endpoint
The server exposes a single WebSocket endpoint at /ws. Connect with an Authorization: Bearer <key> header or ?key=<key> query parameter.
The server proxies audio to Deepgram and forwards transcript events back to the client in the same format Deepgram uses — the SDK handles everything automatically.