Skip to content
DocsStart free

Data Model

All configuration lives in the edge SQL database (the edge platform’s SQLite). This page maps the schema so you know what objects exist and how they relate. It is the source of truth for the API resource reference.

The schema follows a few consistent rules:

  • Booleans are INTEGER 0/1 (CHECK-constrained).
  • Enums are TEXT with CHECK(... IN (...)).
  • JSON (TEXT with json_valid()) is used only for genuinely opaque/variable data: the flow graph, small per-hop transforms, and custom SIP headers. Everything queryable is a real table with real columns.
  • Time is INTEGER epoch-seconds; money is INTEGER micro-units (no float drift).
  • Every tenant row carries an explicit, indexed account_id, with no implicit-join scoping.
  • Secrets are never stored plaintext. Columns ending in _secret_ref hold a key-value store key into the encrypted SECRETS store. SIP auth uses digest ha1, never a plaintext password.
  • IDs are prefixed, time-ordered opaque strings: a per-type prefix plus a ULID, e.g. a queue is q_01jay3k9q7m2n5p8r0xv4zb7dc. The prefix names the type (acc_ account, us_ sip_user, dev_ sip_device, did_ DID, ext_ extension, q_ queue, rg_ ring_group, tr_ sip_trunk, vm_ voicemail, flow_ call_flow, sch_ time_schedule, fwd_ forward, route_ outbound_route, media_ media_file, …). IDs sort lexicographically by creation time and are unguessable, so treat them as opaque.

The single most important idea in the schema is the route target: the consistent trio used everywhere a call can go next:

ColumnMeaning
dest_kindTyped enum: flow, user, extension, ring_group, queue, voicemail, conference, forward, trunk, hangup.
dest_idThe id within the table implied by dest_kind.
dest_xformSmall JSON {var: val} applied on this hop.

Because SQLite can’t enforce a polymorphic foreign key, dest_id integrity is validated in the edge runtime on save and on route. Simple direct routes stay simple; branching logic folds into a call flow (dest_kind: "flow") rather than a pile of conditional-routing tables.

TablePurpose
accountThe tenant. Hierarchical (parent_id) for reseller/white-label. Holds CAC ceilings (max_in/max_out/max_dialer), defaults (language, timezone, voice gender), and wholesale linkage.
sip_domainA realm an account answers on (own + white-label vanity domains).
sip_userThe logical identity/extension (person or agent). Caller-ID presentation, concurrency ceiling, agent flag.
sip_deviceA registering endpoint holding the SIP digest credential (ha1/ha1b). One user → many devices.
nodeThe edge SBC/the media engine boxes the brain pushes ops to (tunnel URL + agent-token ref).
TablePurpose
didInbound number (E.164). Route target + per-DID channel cap + attachable business hours.
extensionInternal short code / feature code. Route target + attachable business hours.
call_flowThe versioned node-graph (graph JSON). Published flows are interpreted by CallSessionDO.
TablePurpose
ring_group + ring_group_memberFork-to-members with a strategy and an exit route target. Members are users or devices, as rows.
queue + agent_queue_assignmentACD config + agent membership (modes, skill tier_level). Loaded by PresenceDO.
in_queue_optionPer-queue DTMF-on-hold options: digitroute/webhook/deflect/hangup.
campaign + campaign_contactOutbound dialer: campaign config (pacing mode, governor, retries, caller-ID) + the per-contact lifecycle.
dispositionPer-account disposition catalog: codeoutcome (closed/retry/callback/dnc) that drives retries.
cid_poolLocal-presence caller-ID numbers keyed by called-number prefix (longest match wins).
pause_reasonNamed agent pause reasons, with whether inbound/outbound still flow while paused.
voicemailMailbox config (greeting, quota, notify email; PIN by secret ref).
conferenceConference room (PINs by secret ref, max members, MOH, record).
forwardExternal call forward (number, trigger, caller-ID mode, press-1 confirm, overflow target).
TablePurpose
time_scheduleA reusable, timezone-aware schedule (= “hours of operation”).
time_schedule_ruleRules as rows: weekly / date / date_range, with dow, times, dates, and is_closed holiday overrides.
TablePurpose
sip_trunkA first-class SIP trunk, with role (carrier/pbx), direction, outbound auth/registration, and inbound auth (ip/register/digest). Generalizes the former customer_trunk. See Trunks, Outbound & PSTN.
sip_trunk_aclAllow-listed source IPs/CIDRs per trunk; drives inbound identification by source IP.
outbound_routeMatch dialed number → sip_trunk or wholesale carrier, by prefix/country and priority.
number_transformRegex number/caller-ID transforms as rows, scoped to account/trunk/did/route.
trunk_headerCustom SIP headers per trunk.

All policy tables share a (scope_kind, scope_id) shape so one rule covers account/user/device/did/queue:

TablePurpose
call_limitCAC sliding-window rate rules ([period_sec, max_count]).
acl_ruleIP/geo allow/deny.
caller_id_ruleCaller-ID presentation by destination country.
recording_ruleRecording policy by direction.
phone_list + phone_list_entryDNC / DNR / allow lists.
geo_policy + geo_policy_countryAnti-fraud destination-country allow/deny.
TablePurpose
media_fileAn object-storage-backed prompt/MOH/greeting/announcement (key + metadata).
media_playlist + media_playlist_itemOrdered playlists.
  • CDR / call_events → the Apache Iceberg data lake (volume). See Observability.
  • Registrations / contacts → the registrar's location store.
  • Live agent / channel / reservation state → PresenceDO.
  • Wholesale rates / termination / balance → the wholesale carrier; retail wallet → BalanceDO.

For a per-resource field reference, see the API Resource Reference.