Skip to content
DocsStart free

The Control Plane

The control plane is the brain: an edge runtime that fields decisions from the edge, backed by stateful edge objects, the edge SQL database, the key-value store, and object storage. This page covers what each component owns.

A single edge runtime is the front door for every decision. Its endpoints (see the Control-Plane API) fall into groups:

  • SIP-facing: /auth (REGISTER/INVITE digest auth), /route (returns routing JSON for the SIP signaling layer), /flow (the call-flow command loop), /presence/event (SIP dialog/register/agent events).
  • ACD & agents: /agent (login/logout/pause/available + queue membership), /agent/confirm/* and /agent/claim/* (answer-time hooks).
  • Concurrency: /cac (channel-usage view), /cac/reset (ops).
  • Security: /security/report, /security/bans, /security/allow (ban reporting + allowlist).
  • Media: /media/* (serve prompts/MOH to the edge; receive voicemail uploads).
  • Admin & future: /admin/tts/generate (prompt synthesis), /debug (dev monitor), and the roadmap /v1 public API and /hooks.

The edge runtime is stateless between requests: all durable state lives in the bindings below.

BindingTypeHolds
CONTROLthe edge SQL databaseAll configuration: accounts, devices, numbers, queues, schedules, trunks, policies.
PRESENCEstateful edge objectPer-account presence, ACD, CAC, dashboard deltas.
CALL_SESSIONstateful edge objectPer-call flow interpreter state.
BALANCEstateful edge objectPer-account retail wallet.
STEERINGthe key-value storeRouting keys (e.g. cac:<callId> → account) for stateless BYE handling.
SECRETSthe key-value storeEncrypted trunk passwords, tokens, PINs (referenced by *_secret_ref).
MEDIAobject storageSystem prompts, MOH, voicemail, TTS cache.

stateful edge objects are the heart of the design. Each is single-threaded (it processes one request at a time), which is exactly what concurrency-sensitive telephony state needs.

The per-account PresenceDO does four jobs in one single-threaded object, so that reservation, admission, and distribution are all atomic with no cross-object locking:

  1. Presence: agent status (offline / available / on_break) and state (waiting / offering / in_call / wrap_up / idle), plus reachability fed by the SIP signaling layer register/qualify feed.
  2. Queue ACD: picking agents by strategy, and the reserve → confirm → release fence that guarantees no double-dispatch (see Queues & ACD).
  3. CAC (admission control): account/user concurrency ceilings and sliding-window rate rules, decided in one atomic admit() (see Concurrency Control).
  4. Dashboard deltas: every mutation emits a delta to a decoupled outbox that fans out to live wallboards over WebSocket.

Each live call walking a flow has its own CallSessionDO. It is the flow interpreter: it holds the current node, the call’s variables, and drives the poll-based command loop. Pure-logic nodes (condition, timeCondition, httpRequest, setVar) resolve inside the session object without an extra edge round-trip. It also buffers the call’s event trace and flushes it in one batch at a terminal step (see Observability).

The per-account retail wallet, kept separate from PresenceDO on purpose. Money math uses integer micro-units to avoid float drift. Wholesale balance (carrier termination) is fed externally; the retail wallet gates retail spend.

The edge SQL database: the configuration source of truth

Section titled “The edge SQL database: the configuration source of truth”

All queryable, enforceable configuration lives in the edge SQL database (the edge platform’s SQLite). Every tenant row carries an explicit, indexed account_id; enums are CHECK-constrained; JSON is used only for genuinely opaque/variable data (the flow graph, small per-hop transforms, custom SIP headers). See the Data Model.

What is deliberately not in the edge SQL database:

  • CDR / call-event trace → the Apache Iceberg data lake (3M+ calls/month would blow the edge SQL database’s size cap).
  • SIP registrations / contacts → the registrar's location store.
  • Real-time state (online, agent status, live channels, reservations) → PresenceDO.
INVITE ─▶ the SIP signaling layer ─▶ edge runtime /route
│ reads the edge SQL database (did → flow), runs CAC via PresenceDO.admit()
flow directive ─▶ the media engine ─▶ edge runtime /flow (loop)
│ CallSessionDO.start()/resume()
enqueue ─▶ PresenceDO (reserve→confirm)
│ agent frees → dispatch push
node-agent ─▶ bridge agent

Each arrow is a small, well-typed request. The edge runtime is the orchestrator; the stateful edge objects hold the truth; the edge moves the packets.

Next: The Media Edge.