You are building a platform. Your customers sign up, configure their own voice agents, plug in their own numbers and provider keys, and pay you for what they use. All of it runs on top of ClutchCall Voice. This page shows how a tenant is isolated end to end, what each tenant gets at provisioning, and where the billing meters sit. The whole model hangs off one stable identifier: the org id. Every tenant resource (DNS label, SIP realm, data rows, sealed credentials, usage account) is keyed on the org id, never on a human-facing slug. Thus a customer can rename their workspace without a move of any infrastructure.
Org onboarding (the console) triggers provisioning. Your platform backend can also trigger it through the control-plane API. Each step below is idempotent and best-effort. Onboarding completes even if one subsystem is briefly unavailable. A re-run of the bootstrap backfills whatever was missed.

What a tenant gets

Per-tenant SIP + WebRTC endpoints

<org-id>.sip.clutchcall.dev and <org-id>.webrtc.clutchcall.dev resolve to the engine. The engine routes inbound SIP INVITEs by their leftmost DNS label.

Isolated analytics

A read-only analytics role scoped by a row policy on tenant_id. Thus a customer’s reports and CDRs can never read across the tenant boundary.

A usage account

A metering account keyed Tenant=<org-id> and bound to your rating plan. Thus every rated call debits the correct balance from the first minute.

Managed recording storage

A per-tenant object-storage prefix (<org-id>/) + access keys. If you leave a customer’s recording target empty, recordings land in managed storage.
Onboarding also mints an entitlement in the entitlements control plane (tier starter | growth | scale | enterprise, with your configured tier as the default). It also mints a per-tenant realtime channel key. Thus CTI events and screen-pop have a channel from day one.

Provision a tenant

1

Create the org and bootstrap resources

Onboarding creates the org record. It then runs the provisioning steps in parallel: DNS labels, the isolated analytics role + row policy, the usage account, storage keys, the entitlement, and the realtime channel. All are keyed on the new org id.
2

Point trunks and numbers at the tenant realm

Register the customer’s SIP trunk against their realm. Map DIDs to it. The engine extracts <org-id> from the leftmost DNS label of each inbound INVITE as the tenant_id. Thus no slug-to-id translation is ever needed. See SIP trunking and number provisioning.
3

Publish the tenant's agent config

When a customer saves an agent, the platform hydrates its pipeline config to the engine, keyed per agent. Provider credentials resolve per tenant (below). See runtime configuration.
4

Issue scoped API keys

Mint a key per customer (or per customer-app). Then their backend can drive calls and stream audio, and it never sees another tenant’s traffic.

Scoped API keys

Programmatic access uses opaque bearer tokens carried as Authorization: Bearer <key>. The server stores keys hashed (it shows the raw value once, at creation). Each key carries a scope set. You can give a key an expiry, and you can revoke it at any time. The token resolves to exactly one org id. That org id becomes the tenant boundary for every request the key makes.
string[]
What the key may do, as product:action strings — for example voice:read, voice:write, or a wildcard voice:* / *. The server refuses a request (403) if the key lacks the scope that the endpoint requires.
timestamp | null
Optional hard expiry. Expired keys authenticate as invalid.
timestamp | null
Set this to revoke immediately. The audit trail is not deleted.
A tenant’s backend instantiates the SDK with its own key. Nothing about other tenants is reachable through it:
If you build a customer-facing dashboard, mint a short-lived token per browser session. Do not embed a long-lived key. Supervisor attach and browser media legs already work this way.

Isolation model

Every layer enforces tenancy, not only the application:
  • Naming. Each tenant is a distinct SIP realm/AOR host (multidomain registrar). Thus two customers can both have extension 1001 with no collision.
  • Routing. The engine derives tenant_id from the inbound INVITE’s DNS label. Thus a misdirected trunk cannot land a call in the wrong tenant.
  • Data. Reports and CDRs are read through a per-tenant analytics role. Its row policy pins tenant_id = <org-id>. There is no query path across tenants.
  • Credentials. Every tenant secret (provider keys, trunk/registrar passwords) is sealed at rest with a key-encryption key. Provider keys are sealed under the org that owns them. Thus only the engine that handles that org can open them. See voice isolation for the media-plane story.
  • Keyspace. Per-tenant runtime state (sessions, registrations, sealed credentials, agent config) lives under org-scoped keys that the engine reads directly.

Per-tenant agent config

Each customer configures their own agents: prompt, ASR/LLM/TTS providers, voice, turn-detection, tools. On save, the platform hydrates the agent’s config into a single per-agent blob. The engine reads that blob at session start. The blob survives many concurrent sessions for the same agent. Timeouts and tunables hot-reload, and in-flight calls do not drop. Provider credentials resolve per tenant. Thus customers can bring their own keys or inherit the platform’s. The resolution order at call time is:
  1. Per-agent override — a key set on a specific agent.
  2. Per-tenant default — the org’s key for that provider.
  3. Platform fallback — your environment default (if you offer one).
per provider
Each tenant can supply its own openai / anthropic / gemini / elevenlabs / deepgram (and peers) credentials. The secret field is sealed at rest. Only the non-secret routing fields (endpoint, region) stay plaintext. See BYO ASR/LLM/TTS and BYO speech-to-speech.
You set turn detection per agent in the same way: type: "silero" (local VAD, the cascaded default) or type: "server_vad" (the realtime provider owns turns). See turn detection.

Billing & usage metering

Two independent meters feed platform billing. Both attribute usage per tenant:
  • Rated call usage. On each call teardown, the engine sends a CDR (Q.850 cause + duration, keyed by call_sid). The system rates CDRs against your tenant’s usage account and rating plan. Thus per-minute call spend accrues automatically. The system captures media quality (MOS, jitter, loss) per call at the same time.
  • Traffic & bandwidth. The engine counts bytes per tenant, per modality as they flow. It drains the counts into a per-minute rollup. That rollup powers the Traffic & Bandwidth dashboard. Voice media bytes are attributed per tenant, per call.
Entitlement tiers gate features and quotas in the control plane. The usage account meters spend. They are separate controls. A tier promotion does not change a tenant’s rated usage. A balance top-up does not change their tier.
See dashboards and call traces for how tenants see their own usage. See deployment models for how to run this managed or on a customer’s own infrastructure.

Build a contact-center platform

Add ACD, skills, VDN/IVR, and supervisor tools on top of tenancy.

Build a voice agent

The single-agent build that each tenant configures.

Platform backend recipe

A runnable backend that provisions and drives tenants.

Runtime configuration

The per-agent pipeline config that each tenant edits.