Synapse

Synapse for developers.The parts we left off the homepage.

How a turn is put together, what every call is scored on, and the code you write to configure an agent. If you are evaluating Synapse technically, start here.

How one turn works

Four steps between the caller finishing and the agent answering. Every one of them is measured — and the part we control adds up to well under 300 ms.

01

Hear

Audio in over the phone or the browser, transcribed while the person is still speaking.

streaming
02

Know it is your turn

A turn model, not a silence timer — so it does not cut people off mid-thought.

~90 ms
03

Think

The model streams a reply while the flow decides where the call goes next.

~140 ms to first token
04

Speak

The first clause goes to speech at once, and stops the moment the caller interrupts.

~50 ms to audio
Then there is the phone network. Your carrier adds 150 to 400 ms on top, which is why a real call lands between 400 and 700 ms rather than 280. That leg is the one part of the path we do not own — so we publish the range instead of quoting the number that flatters us.
When something breaks, one call restarts. A supervisor owns each session, so a stuck model call or a dropped line takes down that call and nothing else. No pager, no full restart, no blackout for everyone else on the platform.

The core, with code

The realtime path a conversation runs on, and what configuring each part actually looks like.

Voice

Pick up the phone and hold a real conversation. Fast replies, barge-in that stops mid-sentence, and a noisy line handled without falling apart.

Barge-inTurn detectionMultilingual
# answer, listen, reply — inside a second
def handle_info({:speech_final, text}, call) do
  {:ok, reply} = Synapse.LLM.stream(call.llm, text)
  Synapse.TTS.speak(call, reply, barge_in: true)
  {:noreply, call}
end

Telephony

Real numbers, in and out, at campaign volume. Inbound queues, outbound lists, and a warm transfer to a person when the agent has done its part.

Twilio & TelnyxSIPWarm transfer
Synapse.Campaign.run("hr-screen-july",
  rows: csv,
  concurrency: 400,
  on_qualified: &Synapse.Handoff.to_human/1
)

Observability & evals

Every call is a trace: latency per hop, tokens, cost per minute, full transcript, and a score for how the agent actually behaved.

TracesCost per minuteScorers
%Eval{
  scorer: :interruption_gap,
  target_ms: 300,
  over: Synapse.Calls.today()
}
|> Synapse.Evals.run()

Voice evals, in full

Four concepts, each backed by named metrics and a pass mark that lives in code. This is the report you get after every call.

Response speed

How long does the caller wait before the agent starts talking?

A caller reads a long pause as the agent not having understood them, and starts repeating themselves. That is where calls fall apart.

p95 ≤ 3.0sPass

Dead air and freezing

Does the agent ever go quiet long enough to look dead?

This is the failure that loses calls. Background noise keeps the end-of-turn detector hearing words, so it never concludes the caller stopped, so it never answers. The caller says “hello?” and hangs up.

zero stallsPass

Interruption handling

When the caller talks over the agent, does it stop and listen?

An agent that keeps talking over someone feels like it is not listening, and callers escalate fast once they think that.

≥ 90% stoppedPass

Conversation rhythm

Does the back and forth feel natural?

Long handovers and constant talking over each other both make a call tiring, even when every answer is correct.

max gap ≤ 3.0sPass

Who was speaking, and when

One call, scored. A long red block would be the agent going quiet after the caller finished — the thing a caller reads as a dropped line. This call has none.

Agent speakingCaller speakingLine dead over 5sCaller cut inAgent stopped0m 27s of call
Agent
Caller
Events
caller cut in → agent stopped, 190 ms
The line never went dead. At 0:20 the caller cut in, and the agent stopped 190 ms later.
Response speed p95 1.9sPassStalls 0PassInterruptions 1 of 1 stoppedPassLongest gap 0.8sPass

The thresholds live in code, not in a settings page — so nobody can quietly widen one to make a bad week look green.

Coming soon

An open core is on the way

We are preparing to open the runtime underneath Synapse — the media path, the turn detection and the supervision tree that keeps one bad call from touching any other.

What we plan to open

The realtime core: media in and out, turn detection, the supervision tree, and the transport adapters. Enough to run an agent end to end on your own machines.

What stays managed

The agent builder, the eval reports, campaign orchestration and the dashboards. That is the product, and it is how we keep the lights on.

Why it is not out yet

Because a repository nobody can run is not open source. We would rather ship it once the setup path is honest than publish a snapshot and leave it.

Want the numbers from your own calls?

We will run one of your real workflows and send you the report.