Bell v2

Bell gets your agent’s reply ready sooner.

Bell lets your reply model start writing while the caller is still talking, so the agent answers the way a person does. It runs beside the reply model you already use.

Measured

365 ms

saved a turn on the reply.

Version2
ReleaseNov 1, 2026

The agent answers the way a person does.

People form a reply while they listen. With Bell, so does your agent.

  • The reply is written early

    Bell starts writing the reply before the caller’s last word, so the agent’s first word comes sooner.

  • Your reply model, your answers

    Bell works with the reply model you already run, and the agent’s answers stay its own.

  • Pay as you go

    $0.005 a minute, billed by the second while a conversation is open. Every account starts with 60 free minutes.

Hear it

Hear the difference.

Three conversations, each twice: as a voice agent answers today, and with Bell. Listen for the pause after the caller stops.

Without Bell

1.5 s

With Bell

500 ms

Caller Wait Agent
The same conversation, before Bell and after. With Bell, the median wait falls from 1.5 s to 500 ms.

Bell cuts the wait on every call.

The wait runs from the caller’s last word to the agent’s first. For the assistant it runs until the agent has the answer, tool call included.

The median wait

Conversation

Assistant

Drive-through

The median wait in each of the three conversations above.

Measured

365 ms

saved a turn on the reply.

Version2
ReleaseNov 1, 2026

Choose your effort level.

More effort saves more latency on your agent’s replies, and less effort keeps your bill light.

The effort level

More effort
More of your agent’s replies start before the caller finishes.
Less effort
A lighter bill, with fewer replies started early.

Rabel APIBeta

Add Bell to the voice agent you already run.

Bell takes the words from your speech-to-text. Sign up with your email for an API key and 60 free minutes.

const bell = new WebSocket("wss://api.rabellabs.com/v1/conversation");
bell.onopen = () =>
  bell.send(JSON.stringify({ key: process.env.RABEL_API_KEY }));

// your speech-to-text's words so far, each time it has new ones
stt.on("words", (text) =>
  bell.send(JSON.stringify({ type: "heard", text })));
// its final words, when it ends the turn
stt.on("endOfTurn", (text) =>
  bell.send(JSON.stringify({ type: "end_of_turn", text })));

bell.onmessage = (e) => {
  const m = JSON.parse(e.data);
  if (m.type === "ready") stt.start();
  // start your reply on Bell's guess
  if (m.type === "guess") reply.start(m.text);
  // the guess that matched, or null
  if (m.type === "end_of_turn") reply.keep(m.guess_id);
};
URL = "wss://api.rabellabs.com/v1/conversation"

async with websockets.connect(URL) as bell:
    await bell.send(json.dumps({"key": os.environ["RABEL_API_KEY"]}))

    # your speech-to-text's words so far, each time it has new ones
    async def on_words(text):
        await bell.send(json.dumps({"type": "heard", "text": text}))

    # its final words, when it ends the turn
    async def on_end_of_turn(text):
        await bell.send(json.dumps({"type": "end_of_turn", "text": text}))

    async for msg in bell:
        m = json.loads(msg)
        if m["type"] == "ready":
            stt.start(on_words, on_end_of_turn)
        elif m["type"] == "guess":
            reply.start(m["text"])  # start your reply on Bell's guess
        elif m["type"] == "end_of_turn":
            reply.keep(m["guess_id"])  # the guess that matched, or None

Free to start

60 min

free with every account, then $0.005 a minute.

Sign upWith your email
BilledBy the second

Works with the stack you already run.

Rabel APIBeta

Bell, at $0.005 a minute, billed by the second while a conversation is open. Every account starts with 60 free minutes.

Contact us

Leave your email and we’ll set you up.