tenant_id only when you need per-call attribution within one deployment: an agency splitting cost per end-user, or a SaaS product fanning usage out to the hosted cloud for per-tenant billing.
tenant_id and project are separate and composable: project groups calls by agent/team/customer at the config level (see Projects); tenant_id stamps an individual end-user on top of that, on the wire. Pass both to attach() when you need both levels. Per-tenant billing and margin rollups run on the hosted cloud.Prerequisites
- VoiceGateway installed (
voicegw --version). - A running gateway daemon (
voicegw serveorvoicegw onboard). voicegw.yamlwithstorage.pathpointing at your SQLite database.
How it works
attach() accepts a tenant_id keyword argument. Passing it sets a context variable for that call; every STT, LLM, and TTS record written during the session reads it back and stores it. The id is capped at 128 UTF-8 characters. attach() raises ValueError above that; it does not truncate.
Sessions where tenant_id is never set store NULL and appear as “unattributed” downstream.
Wire it into attach()
- LiveKit
- Pipecat
Sub-tenants
Some deployments nest a sub-tenant below the top-level tenant (an agency serving clients that each have end users). Stamp it intometadata.tenant_id on the record; the top-level tenant_id is unchanged.
Reading per-tenant costs
Per-tenant rollups (revenue, cost, margin) run on the hosted cloud, which resolves the tenant from the verifiedvk_ ingest key. In an OSS deployment tenant_id is stored but not exposed in a dashboard filter: read it back with SQL. The sessions, requests, and turns tables all carry tenant_id:
GET /v1/billing/usage. See Rating and the HTTP API reference.
Known limitations
Deliberate scope decisions, not bugs.
- No dashboard tenant selector. The OSS dashboard renders one deployment’s totals; per-tenant slicing lives on the hosted cloud.
- No re-tag. Once a session has a non-NULL
tenant_id, it can’t be changed after the fact. - Virtual keys carry no RBAC scopes. A verified virtual key grants the same access as a wildcard static key.
See also
attach()
Full signature and wiring reference for LiveKit and Pipecat.
Projects
Group cost by agent, team, or client at the config level.
Multi-project example
Code example using multiple projects and tenants side by side.