Inspiration

The first call I placed through CALL-E rang out. Nobody answered. It came back with a filled-in result anyway.

A few calls later one went to a voicemail box. The agent asked its question into the tone, and the call came back task_completed: true with a high confidence score.

None of that is a lie, exactly. There's just no field in the payload that says a person was on the line, and the field everybody branches on is task_completed. If money moves on a call outcome, that gap is where somebody gets double-booked, or never called back.

What it does

It reads a finished call as three answers instead of one: how it ended, whether the job got done, and whether the answer came from anybody speaking.

Every reading says where it came from. Quoted from a field, worked out from other fields, or absent because nothing in the payload carries it. That last one matters most. A tool that can't say "nothing here tells you" will make something up.

On top of that sits a reconciler. It reads the call, its attempts and its event stream together and flags four things: a call nobody is watching, a call that may have gone out twice, a clock that contradicts itself, and a retry that isn't safe. Then it writes one plain sentence per call and puts the ones that cost you something first.

When it can't tell who picked up, it names the one field to add to your request so next time it can.

How we built it

TypeScript all the way through, and no model anywhere. Every sentence traces back to a field, so it says the same thing every time and you can test it.

There are three pieces:

  • asheard on npm. The engine that maps all three CALL-E surfaces (Calls API, Goal Runs, MCP), plus the reconciler and an intent ledger. Published from CI with provenance.
  • A Next.js app on top. Paste a payload, read a call with your key, point a webhook at it, see a batch as a morning briefing, or place a live call and watch the two sides disagree.
  • A skill, call-state-reconciler, now merged into awesome-phone-call-agents next to the app.

The coverage table isn't written by hand. It runs the mappers, so it can't claim coverage the code doesn't have.

Every finding came from real calls to lines with no person on them: a published time service, and numbers in the 555-01xx range that are held back for fiction.

Challenges we ran into

Most of the hard part was finding the places where the docs and the API disagreed, then proving it well enough to file.

  1. The authentication guide's own key check returned 405 for a good key and a bad one alike, so it couldn't tell them apart. calle-docs#39, fixed the next day.
  2. task_completed is named for one question and defined as another: "reached a clear end state". A voicemail box does that. calle-docs#44, fixed.
  3. A terminal status can arrive before structured_result is attached. The same wrong assumption turned up in the TypeScript SDK, the Python SDK and the n8n node, where calls waits on status but goals waits on the result. Three codebases, one sentence in the docs. calle-docs#40, server-sdk-typescript#17, server-sdk-python#30, n8n-nodes-calle#3.
  4. Attempt timestamps get rewritten about a minute after a call ends. The offset goes, the value shifts, the fraction of a second goes. That turned out to be the mechanism behind a p1 other people had open (#196), and it's now tracked as #374 and #377.
  5. The agent skills didn't know about call recover, so a lost response could turn into a second real call (call-e-integrations#108, fixed). Two packages installed the same calle binary, so an agent could hand a confirm token to the wrong program (#109, fixed and shipped in @call-e/cli 0.5.1).

14 issues across 6 CALL-E repos. 6 fixed and closed so far.

The other challenge was ours. The PR went through three rounds of security review, and the reviewer was right every time: a read route anyone could hit, a browser-made key treated as permission, real call data sitting in the history. Each one got fixed properly instead of argued.

Accomplishments that we're proud of

  1. PR #337 merged, the skill and the app, after three review rounds.
  2. Six upstream fixes shipped from issues we filed, one of them a P1.
  3. The timestamp finding explained a bug other people had open and couldn't account for.

What we learned

  1. A field name is a claim. task_completed sounds like it answers the question you care about. It answers a different one.
  2. Read twice before you trust a timestamp.
  3. Asking who picked up isn't a guarantee either. On one run CALL-E called the speaking clock a human. The field doesn't make the guess right. It just puts the guess somewhere you can point at it.
  4. The strongest bug report isn't "this is broken". It's "three separate codebases made the same mistake, so it's the sentence in your docs doing it".
  5. And when a reviewer asks for the same fix twice, the fix wasn't done properly the first time.

What's next for AsHeard

Other providers. Vapi, Retell, Bland and Twilio all describe how a call ended in their own words, and CALL-E is adapter one.

Then a hosted version: a durable ledger, alerts for stuck calls, and the briefing in your inbox every morning. It's for teams where money moves on a call outcome and nobody on staff reads payloads.

Built With

Share this project:

Updates

Submission history