Platform overview
CX Bridge is split into five working services. The important architectural boundary is that CXB Core runs calls, while CXB API owns durable business state.| Service | Plane | Owns |
|---|---|---|
| CXB Core | Runtime/media plane | Live call workers, transport adapters, media pipeline, recording upload, post-call packaging, result delivery, Agent Desk handoff hooks |
| CXB API | Control plane | Auth, bots, campaigns, system settings, runtime config, call records, CRM integrations, API keys, recordings, fleet selection |
| CXB Console | Operator surface | Bot builder, campaign builder, call logs, analytics, settings, Agent Desk, knowledge bases |
| CXB Dialler | Campaign execution plane | Campaign leases, pacing, retry scheduling, LiveKit SIP dialing, AMD screening, answered-call attach |
| web call widget | Embeddable web surface | Browser call widget (React + LiveKit client) that joins a LiveKit room handled by CXB Core via /livekit/widget |
CXB Core runtime architecture
CXB Core is a FastAPI app running multiple single-process uvicorn workers behind nginx. Each production worker is one call slot. Production settings:| Setting | Current production intent |
|---|---|
MAX_CONCURRENT_CALLS | 1 per worker |
CXBCORE_WORKERS | Actual worker count reported in health, commonly 16 on 8 GB / 4 CPU hosts |
nginx max_conns=1 | Prevents a busy worker socket from receiving another call |
uvicorn --workers | Always 1; systemd instance count is the worker count |
Call entry points
| Entry point | Route | Used by | Notes |
|---|---|---|---|
| Telephony WebSocket | wss://fleet.example.com/ws/{bot_id} | WebSocket dialler | 8 kHz LINEAR16 |
| Exotel Voicebot | wss://fleet.example.com/exotel/{bot_id} | Exotel App Bazaar | 8 kHz LINEAR16, built-in serializer |
| LiveKit SIP inbound | POST /livekit/dispatch | LiveKit SIP webhook | DID -> LiveKit room -> bot |
| LiveKit SIP outbound | POST /livekit/dialout | CXB API direct dialout | CXB Core creates room and dials SIP participant |
| Campaign attach | POST /attach | CXB Dialler | Dialler creates/screens SIP call, then CXB Core joins answered room |
| Widget call | POST /livekit/widget | CXB Console/web widget | Uses LiveKit room path |
Pipeline
Current provider families:| Layer | Providers |
|---|---|
| STT | Streaming STT, turn-detecting STT, multilingual STT |
| LLM | A language model via the LLM provider, or a managed LLM platform |
| TTS | Multiple interchangeable text-to-speech (TTS) engines |
| VAD / turns | Voice activity detection (VAD), the turn-detection model, or STT-native external turn detection |
end_call, transfer_call, detected_voicemail, and search_knowledge. The search_knowledge tool queries the bot’s Knowledge Base, which CXB API backs with vector-database search over uploaded, chunked, and embedded documents. Custom HTTP tools run through the tool runtime and emit telemetry events.
When live prompt caching is active, CXB Core serves the static policy/system prompt from a cached-content entry on the LLM provider (or via the LLM provider’s prompt-cache-key hints). In that mode the pipeline builder passes tools=NOT_GIVEN and folds tools and the system instruction into the cached content, because the LLM provider rejects per-request tools combined with cached content.
Outbound and campaign flows
Direct outbound calls and campaign calls are intentionally different: CXB API currently distributes direct outbound calls by polling configured fleet URLs and choosing the server with the most available capacity. CXB Dialler performs campaign pacing and attach orchestration separately.State boundaries
CXB Core should be treated as mostly stateless call execution:- It does not store bots, users, campaigns, analytics, or CRM config.
- It fetches runtime config at call start.
- It uploads recordings to configured S3-compatible storage.
- It sends final results to CXB API through a durable result outbox.
- It persists Agent Desk handoff enqueue attempts through a separate outbox.
Failure model
| Failure | Expected behavior |
|---|---|
| One CXB Core worker crashes | Active call on that worker is lost; other workers continue. |
| CXB API temporarily unavailable during result delivery | Result remains in CXB Core outbox and is retried. |
| Agent Desk enqueue temporarily fails | Handoff remains in Agent Desk outbox and is retried. |
| Fleet host full | nginx/app capacity returns busy; CXB API/CXB Dialler should pick another host or retry later. |
| Per-host MinIO used for recordings | Playback depends on finding the originating host; shared object storage is preferred. |
Scaling direction
The current production architecture is good for controlled fleet growth, but 1K-channel scale needs more than “more workers”:- worker/container registration with TTL
- atomic capacity reservation
- partitioned CXB Dialler workers or campaign leases
- shared object storage everywhere
- stronger metrics, tracing, and per-provider cost visibility
- scripted or orchestrated host/container provisioning