Palabra × Vapi
A bridge between Vapi and Palabra Realtime STT/TTS, implementing Vapi's Custom Transcriber and Custom Voice server protocols.
/transcriber(WebSocket) — Vapi streams the call as interleaved stereo linear16 (channel 0 = customer, channel 1 = assistant). The bridge splits the channels, feeds each to its own Palabra STT session at the call's sample rate (no resampling) and answers withtranscriber-responsemessages (transcriptType: "final", optionally"partial")./tts(HTTP POST) — Vapi sends avoice-request; the bridge streams back raw pcm_s16le mono at the requestedsampleRate(8000 / 16000 / 22050 / 24000), chunked, no WAV header./healthz(GET).
Run
pip install palabra-ai-vapi-bridge
export PALABRA_API_KEY=plbr_...
export VAPI_SECRET=... # recommended: enforced as the x-vapi-secret header
palabra-vapi-bridge --port 8080
docker run -e PALABRA_API_KEY=plbr_... -e VAPI_SECRET=... -p 8080:8080 palabra-vapi-bridge
The server must be reachable from Vapi (public https:// / wss://, e.g. ngrok http 8080).
| Variable | Default | Meaning |
|---|---|---|
PALABRA_API_KEY |
— | Palabra API Key (both STT channels and TTS) |
VAPI_SECRET |
— | if set, requests without a matching x-vapi-secret are rejected |
PALABRA_STT_LANGUAGE |
auto-detect | STT source language (en, de-DE, ...) |
VAPI_SEND_PARTIALS |
false |
also forward interim transcripts as transcriptType: "partial" |
PALABRA_TTS_LANGUAGE |
en |
TTS language |
PALABRA_VOICE_ID |
default_low |
TTS voice (catalog) |
PALABRA_FINALIZE_TIMEOUT |
10 |
seconds to wait for the final transcript when the call ends |
LOG_LEVEL |
INFO |
Vapi assistant configuration
{
"transcriber": {
"provider": "custom-transcriber",
"server": { "url": "wss://<your-host>/transcriber", "secret": "<VAPI_SECRET>" }
},
"voice": {
"provider": "custom-voice",
"server": { "url": "https://<your-host>/tts", "secret": "<VAPI_SECRET>", "timeoutSeconds": 45 }
}
}
server.secret arrives as the x-vapi-secret header. Vapi's newer credentialId (Bearer / OAuth2 / HMAC
custom credentials) is not verified by the bridge; put it behind a gateway that does, or extend
handle_transcriber / handle_voice_request.
Protocol details
Transcriber. Vapi sends {"type": "start", "encoding": "linear16", "container": "raw", "sampleRate": 16000, "channels": 2}
and then binary frames. Only linear16 is supported (anything else closes the socket with 1003). The
bridge replies with
{ "type": "transcriber-response", "transcription": "...", "channel": "customer", "transcriptType": "final" }
When the socket closes the bridge flushes both recognizers (finalize) so the last words of the call are
still delivered where possible, then closes the Palabra sessions.
Voice. POST /tts with {"message": {"type": "voice-request", "text": "...", "sampleRate": 24000}} →
200, Content-Type: application/octet-stream, chunked raw PCM. Validation problems and Palabra errors
that happen before the first audio chunk are reported as JSON {"error": "..."} with 400 / 401 / 502.
Concurrency
Every call opens one Palabra STT session per channel (customer and assistant), all with the same
PALABRA_API_KEY. A key is not limited to one live session, so a single bridge instance serves concurrent
calls; the only cap is the concurrent-session quota of your Palabra account.
Tests
pip install -e ".[dev]"
pytest -m "not live" # offline (fake Palabra client, real FastAPI app)
PALABRA_API_KEY=plbr_... pytest -m live -s # /tts -> /transcriber round trip against the API
Status
Protocol checked against the current Vapi documentation and exercised end-to-end against the Palabra API with a test client playing Vapi's part. Not yet run against a live Vapi call.
Metadata
Release files for palabra-ai-vapi-bridge 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| palabra_ai_vapi_bridge-0.1.0.tar.gz | 15.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| palabra_ai_vapi_bridge-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.3 kB
Release files / palabra_ai_vapi_bridge-0.1.0.tar.gz
| Download URL | palabra_ai_vapi_bridge-0.1.0.tar.gz |
|---|---|
| Size | 15.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c3b98daa64c21746eca7aa1662be7bfc2b14e8474e11d521af130586c0ac6f04
|
|
BLAKE2b-256 checksum How to use checksums |
39d39ed12092f63031c48984582caa174bb44645d64afa19579819b42cc2bb4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / palabra_ai_vapi_bridge-0.1.0-py3-none-any.whl
| Download URL | palabra_ai_vapi_bridge-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0fbf665ea0ff52f8746ef6d19f7463804c9c5c427803ef08691cc7b35bb614b6
|
|
BLAKE2b-256 checksum How to use checksums |
24e3de762f34873572ccef693ba3f040baa86ed0c11e00a9a594df109e766b56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|