The platform is four cooperating services. Three of them live in their own git repositories under the pelocal-techservice Bitbucket workspace; the fourth, the Dialler, is deployed and operated for Pelocal but its source is managed with the platform rather than as a separate Pelocal repo. This page maps every service to its repo (where it has one), shows which plane it sits on, and spells out the handful of contracts that let the four pieces work as one system.
In prose we call the services Console, Backend / Backend API, Voice fleet, and Dialler. Those friendly names are what you use day to day. Three of the services have their own canonical Bitbucket repo names — vb-dashboard, vb-core, vb-agents — and those are what you clone, branch, and deploy. The Dialler is deployed and operated for Pelocal (it runs on the SIP/LiveKit host), but its source is managed with the platform rather than as a separate Pelocal Bitbucket repo, so it has no clone of its own. The table below is the one place the namings meet; everywhere else, the friendly names win.

The repositories

The three repos live at bitbucket-pelocal:pelocal-techservice/<repo>.git.
RepositoryServicePlaneLanguage / runtimePackage managerWhat it owns
vb-coreBackend APIControlPython 3.12 · FastAPIuvAuth, bots, campaigns, system settings, per-call runtime config, durable call records, CRM push, API keys, recordings access, fleet selection
vb-dashboardConsoleOperator surfaceReact 19 · Vite 8 (SPA)npmThe operator dashboard: bot builder, campaign builder, call logs, reports, settings, knowledge bases
vb-agentsVoice fleetRuntime / mediaPython 3.12 · FastAPI · Pipecat 1.3.0uvLive call workers, transport adapters, the speech pipeline, recording upload, post-call packaging, result delivery
(no separate Pelocal repo)DiallerRuntime / executionPython 3.12 · asyncio workeruvCampaign leases, predictive pacing, retry scheduling, outbound SIP dialing, answering-machine screening, attaching answered calls to the fleet
The Dialler is deployed and run for Pelocal — it lives on the SIP/LiveKit host as the voxdialler service — but its source is not a separate Pelocal Bitbucket repo; it is managed with the platform. There is therefore no Dialler clone URL. Everything operational about it (the systemd unit, its run command, the one-instance-per-database rule, its health port) is documented on the relevant DevOps pages.
Internal development directories do not match the repo names — you may see a checkout sitting in a folder called something else locally. That mismatch is cosmetic and historical. For anything an operator or DevOps engineer touches — cloning, CI configuration, deploy jobs, runbooks — always refer to the repositories by their Bitbucket names (vb-core, vb-dashboard, vb-agents). Never script against a local directory name.

Repo → service → plane

Control plane vs runtime plane

The defining rule of the platform is a clean split between the control plane, which owns durable business state, and the runtime plane, which runs the actual calls and holds no long-lived state.

Control plane — the source of truth

vb-core (Backend API) plus its data layer — MongoDB, Redis, the vector database, and object storage — hold everything durable: bots, campaigns, system settings, and every call record. vb-dashboard (Console) is the operator’s window onto that truth. If a piece of state must survive a restart, it lives here.

Runtime plane — disposable muscle

vb-agents (Voice fleet) and the Dialler do the heavy real-time work but keep no durable state. They re-fetch everything they need from the control plane at the start of each call, which is why you can scale them out, restart them, or replace a host freely — and why a crashed fleet worker costs you exactly one call.
This boundary is not just architectural tidiness; it drives the operational model. You scale the runtime plane horizontally (add fleet hosts, add workers) without touching the control plane, and you back up and protect the control plane carefully because it is the only thing that cannot be regenerated.

The contracts between services

Four narrow contracts connect the services. Everything else is internal. If you understand these four, you understand how a call gets configured, run, recorded, and recorded back.
1

Backend serves per-call runtime config — the fleet fetches it

At the start of every call, the Voice fleet calls the Backend’s config endpoint and gets back the complete picture for that bot: prompts, voice settings, tools, and any CRM data for this contact. The fleet stores nothing between calls — this fetch is how a stateless worker becomes “the right bot” for the next 90 seconds.The endpoint is GET /api/v1/config on the Backend. The fleet (vb-agents) knows where to find it via VOXBRIDGE_CONFIG_URL in its environment (for example http://localhost:8080/api/v1/config when the Backend is co-located).
# vb-agents .env
VOXBRIDGE_CONFIG_URL=http://localhost:8080/api/v1/config
2

The fleet posts results back to the Backend

When the call ends, the fleet hands the Backend a complete record — transcript, post-call analysis, quality-control findings, a disposition, and the recording reference. The Backend stores it as the durable call record and can push it onward to a CRM. The fleet’s job is finished the moment the result is delivered.
3

The Dialler shares the SAME MongoDB database as the Backend

The Dialler and the Backend point at the same MongoDB database (MONGODB_DB=voxbridge in both). The Dialler reads running campaigns and leases call records directly from that shared database — there is no separate dialler API. The campaign records the Console writes through the Backend are the same records the Dialler paces and dials.
# both the Backend (vb-core) and the Dialler .env
MONGODB_DB=voxbridge
Exactly one Dialler instance may run against a given database. Two diallers on one MongoDB over-dial, because each one paces as if it is the only dialler in the system. Run the single Dialler instance on the SIP/LiveKit host.
4

The Dialler attaches answered calls to the fleet via POST /attach

The Dialler places outbound SIP calls through LiveKit and, on answer, hands the live call to a free fleet worker with POST /attach. From that point the worker drives the conversation exactly as it would an inbound call — same pipeline, same config fetch, same post-call path. The Dialler authenticates the attach with a shared secret (VOXCORE_SECRET) and finds workers from its configured fleet list (FLEET_URLS).
The Console (vb-dashboard) has only one upstream: the Backend. It talks to nothing else — not the fleet, not the dialler, not the database. The Backend’s base URL is baked into the build at build time via VITE_API_URL. Every operator action, every list, every save goes through that one address.
# vb-dashboard brand .env
VITE_API_URL=https://api.pelocal.net

Contract summary

ContractFrom → ToMechanismNotes
Runtime configVoice fleet → BackendGET /api/v1/config (fleet fetches per call)Located via VOXBRIDGE_CONFIG_URL
Call resultsVoice fleet → BackendFleet posts the finished record backBackend stores it and may push to a CRM
Shared campaign stateDialler ↔ BackendSame MongoDB database (MONGODB_DB=voxbridge)No dialler API; one dialler per database
Attach answered callDialler → Voice fleetPOST /attach (authenticated with VOXCORE_SECRET)Fleet workers found via FLEET_URLS
Operator actionsConsole → BackendHTTPS to VITE_API_URLConsole’s only upstream

Where each repo runs

The repository boundaries line up with the deployment topology. A small deployment co-locates roles; a larger one spreads them across hosts.
vb-core (Backend, uvicorn on :8080) and the built static output of vb-dashboard (Console, served by nginx). Small deployments also co-locate MongoDB and Redis here.

Package managers at a glance

The three Python repos all use uv — never pip. The Console uses npm.
uv sync                 # install dependencies
uv run uvicorn voxbridge.app:app --host 0.0.0.0 --port 8080 --app-dir src
The module paths above (voxbridge.app, voxcore.app, voxdialler.main) are the importable Python package names inside each service. They are the run targets, not the repo names — clone vb-core, but launch voxbridge.app.

Where to go next

System architecture

The end-to-end picture: the four services, the data layer, the telephony plane, and the life of a single call.

Run it locally

Prerequisites, cloning the repos, and running the whole stack on your own machine.

Deploy it

The Bitbucket → Jenkins pipeline, host deployment, configuration, and the operations runbook.