From a call to a customer relationship
When a call ends, voice.end_call turns it into things that outlive it: a summary, a lead, a memory and a follow-up. Each has a rule that refuses it. A call that was never a conversation produces no lead, a call with almost no caller speech is never summarised, and a form of address is never stored as somebody's name. What is left is a relationship, not a transcript.
From one call to a relationship#
- Trigger — a call ends, however it ended.
- External event — the provider's final status, or the worker's own end event.
- Authentication and workspace resolution — the ending runs inside the call's workspace, like every other stage.
- Ingest — turns, timings, events and the ending reason.
- Canonical record — the
callsrow closes: outcome from the engine, disposition kept separate for the human decision. - Reasoning — the summariser runs, unless the call is below the speech threshold that makes summarising honest.
- Knowledge, memory and rules — name guards, fact guards and memory writes, each able to refuse.
- Autonomy and approval — anything that would contact somebody again is subject to the channel's autonomy.
- Action through a provider — none, usually; this stage is bookkeeping, and that is the point.
- Result — a person, possibly a company, a timeline entry and a next action.
- Relationship, timeline and memory — the person's record now carries this call across every channel they use.
- Audit, usage and Needs You — cost booked, digest completed in the background, decisions queued.
The ending is deliberately split. finish(defer=True) closes the row, books the cost, marks the digest pending and answers immediately; a background task runs the summary and review afterwards. Waiting on two model calls inside one request produced "end not recorded" for endings the engine had recorded perfectly well.
The four refusals that keep the record honest#
| Stage | What you see | What changes | What can fail |
|---|---|---|---|
| Lead capture | No lead from a call that never connected | Nothing | no_answer and not_reached are both non-conversations; a lead from either is fiction |
| Summary | A very short call carries no summary | Nothing | Ten one-turn calls once produced an invented afternoon at a sales desk |
| Name capture | A title or a form of address is not stored as a name | The person keeps the name they had | Protected markers guard every door a name passes through, and every door it is read back through |
| Fact capture | A suffix, a pronoun or "the caller" is refused as a name-keyed fact | Nothing | A fact keyed to a non-name pollutes every later answer about that person |
The threshold for summarising is concrete: fewer than two caller lines and fewer than five caller words, and the call is never sent to the summariser. A model given almost nothing does not decline to answer — it produces something plausible, and plausible is the failure mode that matters here.
How the person is found#
A contact created by lead capture carries phone_key from the start. That sounds like a schema detail and is not: without it, a number is a string on a record rather than an identity, and the next call from the same person starts a second history. Where a number already resolves to two rows, identify_caller takes the oldest, favouring the relationship that has history over the row created most recently.
From there the call joins everything else that person has done — mail, messages, opportunities, cases — in one view, because identity resolves across channels rather than per channel.
What the call leaves behind#
- Summary
- What was discussed, written only when there was enough speech to write it from.
- Outcome and disposition
- The engine's word and the human's word, kept apart on purpose so a late provider webhook cannot overwrite what somebody decided.
- Memory
- What is durable about this business or person, under a small character budget, because every character is re-read on the next call.
- How to speak to them
preferred_language, once the caller has settled into one, andspeaking_style— which languages they mix, and how much — when they mix. Written only on a call that may use memory at all.- Follow-up
- A dated commitment with a reason and a channel — or nothing, when nothing was promised.
- Cost
- Metered by modality, since a live call is billed on audio tokens at several times the text rate.
Those last two facts merge differently from the rest. Most facts keep the first value they were given; preferred_language and speaking_style are latest-wins, so a later call replaces what an earlier one learned. That is the right way round for a fact about how somebody wants to be spoken to today, and it is why a caller who switches to English for one call is not fighting a record made a year ago on the next. On the following call the remembered language is what Connect replies in from its first reply, and only a whole sentence in another language moves it.
The gap audit that produced the current opening — instructions saying the greeting has already been said, one thought and one question, under 25 words — moved the median reply from 23–40 words to 19 and removed re-introductions entirely, with no latency cost. Shorter calls carry the same relationship value and less of the noise a summariser has to discard.
Questions#
Why is there no lead from a call that rang out?
Because nobody spoke. no_answer means it rang and was not picked up; not_reached means it never rang at all. Both are attempts, both are on the record, and neither is evidence of interest. Creating a lead from an attempt is how a pipeline fills with people who have never heard of you.
Who decides the call's disposition?
A person. The engine writes its own outcome, and the human disposition is a separate field precisely so a webhook arriving late cannot overwrite a judgement somebody made.
Does the summary come from a recording?
No — recording is a foundation capability and is not enabled on the live carrier. The summary is written from the transcript of the turns, which is also what the review and the follow-up evidence are drawn from.