2026-09-05 The first real calls have been placed: five ended normally, six failed. Here is what broke.

Voice AI platform · SIP PBX · contact centre

The agent talks on the phone. You see every millisecond.

A voice agent that answers calls, calls tools, searches your documents and hands the call to a person when it runs out of road. With everything it did, written down to the millisecond.

  • The Starter plan has no subscription
  • You can bring your own provider keys
  • It installs on your own server

A build in progress. The site says page by page what works and what does not. What is proven, and what is not.

One turn from a real call twilio · 2026-09-05
  1. 7.772 endpoint.detected the budget starts here
  2. 7.772 llm.started
  3. 8.272 transcript.final
  4. 9.857 llm.first_token target 600 ms
  5. 10.443 tts.started
  6. 10.862 tts.first_audio target 400 ms
  7. 10.863 assistant.speech.started 3,091 ms against a target of 1,200
llm.first_token 2 085 / 600 ms
tts.first_audio 419 / 400 ms
endpoint_to_audio 3 091 / 1 200 ms

The offsets are copied from the call events. The turn ran two and a half times over budget and the console flagged it. This call is here precisely because it did not go well.[2]

§01 How it is now

Six things that happen on a company phone line today

None of them is a software problem. They are what anyone who has spent a day next to a company phone already knows. The section below says what we do about each one, and where we have not got there yet.

People ring when you are closed

After six, on a Saturday, during the holidays. The phone rings out, the caller hangs up and rings the next name on their list. You never find out they called.

The same five questions, all day

What do I owe, where is my parcel, what time do you open, can I move my appointment. People paid to read out loud what the system already says.

Nobody knows what was said

The recordings exist somewhere on a server. Nobody listens to them. You find out what someone promised on the phone when the customer complains and asks you to play it back.

The cost of a call is a guess

You know the monthly total. You do not know what Tuesday at eleven cost you, or which campaign is eating the budget.

The robot sounds like a robot

Press-one menus, voices that break words in half, and Romanian treated as one language on a list rather than the language the caller is speaking.

Asking for a person loses everything

A transfer moves the call, not the context. A colleague picks up and asks again for the name, the contract number and what the caller wanted three minutes ago.

Below: what the product does about each one, with a link to the page that proves it

§02 What it does

One call, six things to do with it. All in the same product.

These are not modules sold separately. The number, the assistant, the tools, the operator queue, the recording and the cost breakdown are the same objects, in the same console, on the same invoice.

Answer the call

A number bought or imported through Twilio reaches an assistant and it answers. Twilio is the only path proven end to end today; what sits around it — our own switch, a SIP trunk — is written up separately, with what works and what does not.

How the call gets in

Understand and look things up

Transcription, model and voice are chosen per assistant, not per platform. The assistant searches your indexed documents and answers from what it found rather than from what the model remembers.

How an assistant is built

Call your own tools

Your own HTTP tools with a JSON schema, MCP servers, and 25 ready-made connectors — from Google Calendar and HubSpot to Shopify and WhatsApp Business.

The full list

Hand the call to a person

Queues, skills, a softphone in the browser, and a human taking the call over without the caller being rung again: their call is never hung up, the operator joins it. The contact centre is not another product; it is the same one.

Queues and operators

Write down everything that happened

Two-channel recording, transcription, 66 event types with millisecond offsets, and personal data — card, IBAN, Romanian CNP — masked in transcripts and in logs.

Recordings and storage

Show you what it cost

Every call carries a per-stage breakdown: what the transcription, the model, the speech and the telephony cost, plus the platform margin. A row with no published price stays at zero and is visibly empty.

How the price is made

  1. transport audio in and out
  2. stt speech to text
  3. endpoint the caller stopped
  4. llm the model answers
  5. tool tools and MCP
  6. tts text to speech
  7. playback audio to the caller
§03 The turn

A call is an ordered ledger of events, and you get all of it.

Every call writes an append-only stream of typed events with millisecond offsets, covering transport, transcription, endpointing, the model, tools, MCP, speech, DTMF, SIP signalling, transfers, queueing, recording and provider fallbacks. The whole vocabulary is printed on the next page.

That stream is what the console draws, what the API returns from the events endpoint, and what a webhook delivers. There is no second, prettier version of the truth — the debug timeline is a straight render of the same rows.

Transcript, with the interrupted turn struck out example

callerHello, I would like to move my appointment on Thursday.

assistantOf course. I can see an appointment on Thursday the fourteenth at ten —

callerSorry, make it the afternoon.

assistantThursday afternoon. I have half past two and half past four free.

A struck-out turn is one the caller never heard to the end. The console renders it that way, and so does the transcript the model is given.[1]

§04 The console

How you see a call, listen to it, and read what it cost

Every call leaves the same five surfaces behind: the list it appears in, the transcript with the tool calls in line, a two-channel recording you can scrub, a cost breakdown per stage, and a supervisor view while it is still running. These are screenshots of the running console, not mockups.

The transcript, with the tools in line

You see the assistant ask, the tool fire, and the answer come back — each with its own latency. That is how you find out where the silence a caller complained about actually came from, instead of guessing at it.

A call transcript as a conversation. Assistant turns are on the left, caller turns on the right, each stamped with a wall-clock time, an offset into the call and how long the turn took. Between two turns, a highlighted row shows an MCP tool named identify_customer completing successfully in 657 milliseconds.

The recording, on two channels

The assistant and the caller are separate waveforms on one timeline, so an interruption is something you can see before you play it. The transcript underneath scrolls with the audio, and the file downloads.

A recording player showing two stacked waveforms on one timeline: the assistant on the upper channel and the caller on the lower one, with a play button, a speed control and a download link. Under the player, the transcript runs as timestamped lines.

What the call cost, per stage

The quantity that was counted sits next to the published tariff it was multiplied by, with the vendor's own price page linked. A stage whose price nobody verified enters at zero and stays visibly empty rather than being estimated.

A cost breakdown for one call. A total, then a card per stage — transcription, model, voice, telephony — and a table listing for each stage the provider, the model, the quantity that was counted, the published tariff with its source URL, and the resulting cost.

The call list, with latency as a column

Time to first token and end-to-end latency are columns next to the price of the call that produced them — not a report you have to go and build. Filter, sort and open any row.

A table of calls. Each row shows the date and time, the assistant that answered, the calling and called numbers, an outcome badge, the duration, how the call ended, the model time to first token in milliseconds, the end-to-end latency, and the cost in dollars.

The supervisor console

Operator states, queue membership and the offered/taken/missed counters in one matrix. On a call that is running, listen, whisper and barge from the same row.

A supervisor console listing operators with their current state, how long they have been in it, the queues and skills they belong to, and counters for calls offered, taken and missed. A panel on the right waits for an operator to be selected.

The phone numbers and the customer name in these frames were replaced with neutral values before the screenshot was taken. Everything else — the timings, the costs, the tariffs, the waveform — is a real call this installation handled.

§05 Use cases

What people use it for

Take the calls that repeat

Balance, invoice, meter reading, order status. The assistant looks it up in your system through a tool and answers from real data rather than from the model weights. What it does not know, it hands over.

  • Assistant
  • Tools
  • Knowledge base
  • Queue
example

callerI have an invoice I do not understand.

assistantOf course. I can see the September invoice, 312.40 lei. The difference comes from the self-read meter value on the third.

toolcrm.get_invoice({"account":"…","period":"2026-09"}) → 312.40 RON

See the page for this case

Move, confirm, cancel

The simplest conversation to automate and the most irritating one to keep a person on. The assistant reads the calendar, offers slots and writes the change back.

  • Assistant
  • Tools
  • Structured outputs
  • Campaigns
example

callerI would like to move my Thursday appointment.

assistantThursday afternoon I have half past two and half past four free.

toolcalendar.find_slots({"day":"2026-09-10","after":"12:00"}) → 2

See the page for this case

Where is my order

The most repetitive question in an online shop, with the answer already written in the database. The assistant finds the order by phone number and reads its status back.

  • Shop connector
  • Lookup by phone
  • Ticket
  • Structured output
example

callerHello, I ordered last week and nothing has arrived.

assistantLet me check on the number you are calling from. Can you confirm the last four digits?

toolshop.get_order({"phone":"+407…"}) → shipped, AWB 4412…

See the page for this case

Call back in two minutes, not in two days

A form filled in on the site triggers a call. The assistant asks three qualifying questions and writes the answers as a structured output, ready to import into a CRM.

  • Campaigns
  • Structured outputs
  • Tools
  • Scorecards
example

callerI saw the ad. How much does it cost?

assistantIt depends on consumption. How many connection points does the company have, and at what voltage?

toolcrm.create_lead({"score":"warm","points":3}) → id 48213

See the page for this case

Polite reminders, inside permitted hours

The campaign respects calling windows, suppression lists and consent, and every contact it did not call carries one of nineteen named reasons.

  • Campaigns
  • Suppression lists
  • Tools
  • Recordings
example

callerI completely forgot about that invoice.

assistantIt can be paid now through a link sent by SMS, or spread over three months.

toolbilling.send_payment_link({"channel":"sms"}) → 202

See the page for this case

The Friday evening call

The office is shut, but the call is taken anyway: the full request, a ticket opened, and a summary sent through before morning.

  • Time conditions
  • Ticket
  • Notification
  • On-call transfer
example

callerI have a problem and I see you are closed. Shall I call tomorrow?

assistantI can take everything down now and a colleague will ring you first thing tomorrow.

toolhelpdesk.create_ticket({"priority":"normal"}) → id 9137

See the page for this case

One number, the right destination

Instead of a keypad menu, an open question. The caller says what they need and reaches the right team directly, with the context carried across.

  • Intent routing
  • Transfer with context
  • Queues
  • Extensions
example

callerI would like to speak to somebody in sales.

assistantI will put you through. So you do not have to repeat it, what is it about, briefly?

tooltransfer({"to":"sales","context":"summary"}) → ringing

See the page for this case

Ask an hour after the call, not a month later

Three short questions, the answers written as a structured output, and anybody who wants a person gets one straight away.

  • Campaigns
  • Structured outputs
  • Boards
  • Scorecards
example

callerYes, I have two minutes.

assistantFirst question: on a scale of one to ten, how easy was it to resolve?

toolsurvey.record_answer({"q":1,"value":8}) → 200

See the page for this case

Every trade and situation

§06 What this is

One control plane for the agent, the switch and the people.

Most voice AI stops at the agent. You still need numbers, trunks, an IVR, a queue, someone to escalate to when the agent runs out of road, and a recording you can hand to compliance. CallAgent is those things in one system: a voice agent platform, a SIP PBX and a contact centre that share one tenant, one billing ledger and one call record.

The agent side is provider-agnostic. You choose a transcriber, a model and a voice per assistant, from adapters the gateway registers at boot, and you see the latency and cost of each choice on the card you are choosing from rather than on a comparison page nobody opens.

The telephony side is a real switch, not a webhook. Numbers, SIP trunks, extensions, ring groups, time conditions, voicemail and conference rooms exist as first-class objects, so an assistant can be one destination in a dial plan instead of the whole product.

Build it and publish it

A five-step wizard, presets that pick the transcriber, model and voice together, and a publish step that refuses configurations which would drop the call.

See what happened

A millisecond timeline, the transcript, a dual-channel recording, per-stage cost and scorecards over real calls. The rows the console draws are the rows the API returns.

Wire it into everything else

221 documented paths, webhooks you can redeliver, MCP servers attached as tools, and CallAgent itself exposed as an MCP server.

§07 Providers

18 providers you can pick today.

A transcriber, a model and a voice are configuration on an assistant rather than one choice made once for the whole platform, and a fallback chain moves to the next provider when one fails mid-call.

The list below is what can be selected today, read from the same registry the console runs on. Roughly as many again are seeded in that registry and marked not implemented; we do not count those, because a name you cannot select is not an option.

Language models 5

  • OpenAI
  • Anthropic
  • Google Gemini
  • Groq
  • Custom OpenAI-compatible LLM

Transcription 12

  • Deepgram
  • AssemblyAI
  • OpenAI
  • OpenAI Realtime Transcription
  • Gladia
  • Speechmatics
  • Soniox
  • Cartesia
  • ElevenLabs Scribe
  • Sonix
  • Talkscriber
  • xAI

Speech synthesis 1

  • ElevenLabs

The count is counted from the application registry rather than typed by hand, and it changes on its own when the registry changes. Three have been used on a real call: Anthropic for the model, ElevenLabs for transcription and ElevenLabs for the voice.[3]

§08 Before you sign

What departments ask before a signature

The list below is what we have. The list of what we do not have — certifications, a penetration test, SAML — is on the security page and it is just as long.

See what we do not have

multi-tenant

An organization scope applied globally, plus policies, plus tenant resolution before model binding.

roles

Ten roles over 71 permissions, scoped to the organization rather than global.

audit

Who changed what, as records readable in the console rather than as log lines.

redaction

Luhn-checked card numbers, email, phone, IBAN and national ids, masked in transcripts and logs.

your storage

Recordings can go to your own bucket on S3, R2, Azure Blob or an S3-compatible store.

region

The installation region is configurable and starts in the European Union.

§09 Figures

The numbers we do have

We have no billions of calls and no uptime percentage. We have these, and every one can be checked in the repository.

2 239
tests run, of which 2,237 passed and 2 were skipped
18
provider ids registered by the gateway
70
event types a call can write
305
REST routes, of which 221 documented in OpenAPI

The test count comes from the build report. Providers and event types are counted when this page renders.

§10 Surface

Nine areas, one tenant.

The console groups everything into the nine sections below. Each name is a real object with its own screens, its own API routes and its own permissions.

The nine navigation groups of the console and the objects in each.
Build Assistants · Tools · MCP servers · Knowledge bases · Structured outputs · Squads
Telephony Phone numbers · SIP trunks · Extensions · IVRs · Ring groups · Queues · Voicemail boxes · Conference rooms · Time conditions
Contact Center Operators · Skills · Dispositions · Live calls · Wallboard
Engage Calls · Campaigns
Observe Analytics · Boards · Scorecards · Eval suites · Simulation suites · Monitors · Issues
Developers API keys · Webhook endpoints
Platform Provider credentials · Storage destinations · Connections · Integrations · Customers
Organization Members · Roles · Audit log
Billing Credits · Usage · Invoices · Prices · Products · Enterprise contracts
§11 Questions

What people ask first

What is CallAgent?

CallAgent is a voice AI platform with a SIP PBX and a contact centre in the same product: you build an assistant that answers the phone, give it a number, connect it to your systems through tools, and when it runs out of road it hands the call to a human operator from the same console.

Does it work in Romanian?

Yes, with one caveat we would rather state ourselves. The console, the guides and the billing are in Romanian, the personal-data masking recognises the Romanian CNP, and the language is set per assistant. On the first real calls the language was left on "multi", the transcriber labelled Romanian as Hindi and the answers came out wrong; setting Romanian explicitly on the assistant fixes it, but the default is still "multi", so it is a setting to make rather than a guarantee.

What does a minute of calling cost?

The platform charges €0.10 a minute, applied to the real billable seconds rather than to rounded-up minutes; on top of that you pay provider costs at their price, and if you bring your own provider keys you pay only the €0.10. The Starter plan has no subscription. There is no free trial yet.

Can we install it on our own servers?

Yes. Installing on your own server is documented, the whole stack runs in containers, and recordings and transcripts can be written straight into your own bucket on S3, R2, Azure Blob, Google Cloud Storage, Supabase or any S3-compatible service. What we do not offer is a managed EU region of our own: if you want the data in a particular place, you choose the server.

Is it production ready?

No, and we would rather you did not find that out later. On 5 September 2026 the first eleven real calls went out through Twilio: five ended normally, six failed, and the first turn took 3,091 ms against a 1,200 ms target. We have served no customers, taken no real payment, and no call has yet gone over a SIP trunk of our own.

§12 Honesty

The part most sites leave out.

This build has 2,237 passing tests and, since 5 September, eleven real calls through Twilio. Six of them failed, the transcriber mistook Romanian for Hindi, and the first turn came in two and a half times over the latency budget. This is on the front page because you would find out anyway.

The habit is written into the product, not only into this page: a cost derived from list prices is prefixed and says it is an estimate, an unmeasured latency says so, and a tool that would need a sandbox refuses to run rather than pretending.

Scoreboard 2026-09-05
Real calls ever placed
11
Ended normally
5
Failed
6
First turn, measured against target
3 091 / 1 200 ms
Customers served so far
0
Automated tests passing
2 239

Three of the six numbers are bad and are printed in red. They are on the front page because otherwise the sentence next to them would be worth nothing.

Notes

  1. 1 The exchange above is an example written for this page, not a real transcript. The strike-through marks the turn the caller never heard to the end.
  2. 2 The real call: 01M1RRDYJH6XAJY2M5XQX9Z6XD, table call_events. Twilio, ElevenLabs scribe_v2_realtime, Anthropic claude-sonnet-4-6, ElevenLabs eleven_flash_v2_5. Targets: config/callagent.php, key latency_targets_ms.
  3. 3 Provider ids: apps/voice-gateway/src/providers/real-adapters.ts, mirrored in config/marketing.php and returned by the gateway at GET /health.