A Voice Agent Isn’t Operational Until the Call Is Accounted For
A voice agent that talks in a browser is a demo. A voice agent whose completed calls reach a verified ingest endpoint, attach to the intended tenant, and bill usage exactly once is a managed product. Here is how our operational call-accounting architecture works.
An AI voice agent that speaks, listens, and handles natural interruptions in a web browser is an impressive demonstration. But taking that voice model and wiring it into a business’s phone line introduces an entirely different category of engineering problems. An agent that can talk is a demo. An agent whose completed calls are verified, attributed to the correct account, and accurately metered is a managed product.
When teams evaluate voice AI, they almost always focus on the conversational surface: the voice model, the latency, the accent, and whether it can handle an interruption. Those elements matter, but they are only half of the system. Once an agent starts receiving real inbound calls on a commercial phone number, the operational foundation becomes paramount.
If a phone call ends and the system cannot prove who owned the call, whether the notification was authentic, or how many minutes were used, the system is not production-ready. Here is how we structured the operational call-accounting architecture in Ghost AI Systems to bridge the gap between voice runtime and customer portal.
The Boundary Between Voice Runtime and Customer Portal
In our architecture, the voice runtime lives on telephony infrastructure outside the web application. Telephony workers interact with SIP trunks, audio streams, and carrier networks to conduct conversations in real time.
The customer portal, billing meter, and call logs live on our web application and database. These two environments must communicate reliably across the public internet. When a call concludes, the telephony layer must report the call event back to the portal so that the customer’s dashboard reflects the interaction and the usage meter advances.
Because this event passes over an open HTTP endpoint, treating it like a standard webhook would expose the system to tampering, phantom usage spikes, and reconciliation errors. The endpoint must enforce four strict guarantees:
- Cryptographic authentication: Reject any request that does not originate from our authenticated workers or verified telephony carriers.
- Deterministic tenant routing: Accurately associate the call with the specific subscribed customer using destination numbers.
- Atomic idempotency: Ensure network retries and duplicate webhooks never charge a customer twice for the same call.
- Telecom-standard billing: Apply predictable, round-up minute math across normalized call outcomes.
1. Fail-Closed Ingest Authentication
Our call-record ingest endpoint at /api/voice-agent/calls fails closed by default. If the server lacks configured ingest credentials, it immediately rejects incoming requests with an HTTP 503 rather than accepting unverified payloads.
Incoming requests are validated through one of two authorized authentication paths:
- Operator Ingest Key: For background workers reporting call summaries, requests must supply an ingest key that is validated using constant-time string comparison (
timingSafeEqual) to prevent timing attacks. - Cryptographic Telephony Signature: For direct status callbacks from telephony providers, the endpoint validates the provider’s cryptographic signature (such as the
X-Twilio-Signatureheader). The signature is verified by computing an HMAC-SHA1 digest over the canonical request URL and sorted form parameters using the account’s auth token.
Any request that fails both checks receives an immediate HTTP 401 Unauthorized. Unauthenticated data never touches our database or triggers business logic.
2. Tenant Attribution via Destination Number
In a multi-tenant voice platform, assigning calls to the correct business must be foolproof. While internal worker payloads can supply an explicit customer identifier, direct telephony callbacks identify the destination using the dialed telephone number in standard E.164 format.
Our ingest pipeline queries the customer database for an active account whose assigned number matches the incoming destination. Under our provisioning safeguards, numbers are assigned to a customer only after an active subscription is confirmed and number ownership is verified.
If a call arrives for a phone number that is unassigned or unrecognized, the endpoint logs a warning and returns an HTTP 404. It refuses to invent default tenant records or silently attach the call to an arbitrary customer.
3. Atomic Idempotency and Exactly-Once Metering
Telephony webhooks operate in distributed networks where retries are inevitable. A carrier might send an initial callback when a call begins, an update during transfer, and a final status callback when the call ends. If a network blip occurs during delivery, the carrier will re-deliver the final callback multiple times.
If an ingest system simply runs increment(duration) on every incoming callback, network retries will artificially inflate a client’s bill.
To prevent this, our pipeline wraps call recording and usage accounting inside a single database transaction:
- The incoming call is keyed by its unique telephony identifier (
CallSid). - The system checks whether an existing record for this
CallSidwas already marked as completed with a recorded duration. - The call record is upserted with normalized status, caller phone, duration, outcome, and metadata. Crucially, existing durations and outcomes are protected against regressions.
- The customer’s usage meter (
minutesUsed) is incremented if and only if the call was not already billed, its status is completed, and it has a positive duration.
If the same completed callback is delivered five times across ten seconds, the call record is safely updated, but the customer’s minute allowance is billed exactly once.
4. Telecom-Standard Usage Accounting
How call duration converts to billable minutes is governed by telecom billing standards. In telecom accounting, partial minutes round up to the next whole minute.
Our usage helper (lib/voice-usage.ts) enforces this logic deterministically:
- A call lasting 45 seconds bills for 1 minute.
- A call lasting 61 seconds bills for 2 minutes.
- Unanswered, busy, or 0-second failed attempts bill for 0 minutes.
Raw statuses from carrier callbacks (such as completed, in-progress, answered, busy, no-answer, canceled, or failed) are normalized into a predictable status taxonomy (initiated, in-progress, completed, or failed). This ensures that analytics dashboards, client portals, and billing summaries report consistent, understandable state across every call.
Building Managed Systems, Not Prototype Demos
Anyone with an API key can connect a speech-to-text engine to an LLM and play synthesized audio over a speaker. The barrier to building an impressive voice prototype has never been lower.
The barrier to building a dependable, enterprise-grade business phone system remains high. A production voice agent requires cryptographic authentication on every webhook, foolproof tenant boundaries, resilient idempotency against duplicate delivery, and transparent usage metering that matches telecom standards.
That is the engineering standard we bring to every system we build at Ghost AI.
If you want to experience our conversational voice interface firsthand, you can try our live interactive voice demo directly on the homepage. And when you are ready to put a dedicated, managed AI voice agent on your business phone line, explore our AI Voice Agent plans.