Skip to main content

Overview

You do not need LiveKit or Pipecat to run a 60db agent. A 60db agent already does the listening, the model, the voice, the tools and the call itself, and you reach it with the HTTP API. This page maps what you built on those platforms to what you set here, and how to move one number at a time without risk. If you want to keep LiveKit in the path and only use 60db speech models inside it, that is a different topic: see the LiveKit integration.

Rolling out features

Rolling out. These parts of the migration use names that are defined but are still being released: MCP servers (mcp_servers, POST /agents/{id}/mcp/refresh), agent handoff (handoff_targets), warm transfer (transfer_targets[].warm) and agent tests (POST /agents/{id}/tests). Until they reach your workspace, the matching rows below do not apply. The rest of the page does not depend on them.

What replaces what

HelloKit and 60db names for the same things are in Names: HelloKit and 60db.

The same thing, step by step

1

Save the agent

Create an agent once. Copy your prompt into script, pick a voice_id, list the languages, and re-declare each function as a tool. Keep the webhook_secret it returns, shown only once
2

Phone, in

Create a phone line with the number your carrier dials and the carrier’s source addresses. No room, worker or dispatch rule is involved
3

Phone, out

Place a call with the agent, to and phone_line_id
4

Browser

Start a browser call with the agent and the offer. The dashboard’s Test call is the reference client
5

Your own audio source

Start a stream call, connect, send 8 kHz frames, play what comes back
6

Tools, transfer, knowledge

Set tool_webhook_url and tools, transfer_targets, and knowledge_collection_id or knowledge_webhook_url

Phone, in

Point the carrier at hellokit-sip.60db.ai (UDP 5060, G.711). No username or password is needed if the carrier trusts your IP.

Worked example: LiveKit SIP trunks to a 60db phone line

Field names below are LiveKit’s SIP trunk fields at the time of writing. Check your LiveKit version before copying.

Inbound trunk and dispatch rule

LiveKit inbound trunk:
LiveKit dispatch rule that sends calls to a room with an agent:
The 60db phone line that replaces both:
A trunk that relied on a login must switch to addresses. If your LiveKit trunk was protected only by auth_username and auth_password, set allowed_addresses to the carrier’s source IPs on the 60db line. A line with an inbound number and no allowed_addresses is accepted but is an open line: anyone can send calls that are billed to you (warnings: [{ "code": "open_trunk" }]).

Outbound trunk and “create SIP participant”

LiveKit outbound trunk:
The same 60db phone line (add these to the line above, or create a separate outbound-only line with inbound_number: null):
The carrier must accept calls from 60db’s source addresses. See Firewall and ports.

Move without risk

  • One number first. Keep your current setup and give 60db a single number, or a test number. Nothing else changes.
  • Compare like with like. Place the same ten calls on both and compare the answer delay (typical p50 and slow p95), failed calls, and what callers say. Get call returns the measurements; the dashboard shows them under call measurements. 60db’s numbers depend on where it runs: measure from your own network, not a laptop. A workspace runs a limited number of calls at once, so size the test to it.
  • Widen in steps. Move numbers one at a time. Use numbers to put several numbers on one phone line, each with its own agent.
  • Roll back by pointing the carrier back. Your old trunk and worker stay untouched while you test, so undoing a step is changing where the carrier sends the number. Nothing in 60db has to be undone first. Prove it once before you rely on it.
  • Check the number is free first. A number can answer in only one place. Moving it to 60db fails with 409 NUMBER_IN_USE while it is still bound elsewhere in Agents, Dialer or a LiveKit realtime route. See One number, one stack.

What does not move over

  • Shared rooms. A 60db call is one caller and one agent. If you rely on rooms with several participants, keep LiveKit for that part. To put 60db speech models inside it, see the LiveKit integration.
  • Your own pipeline code. Custom turn-taking, custom STT or TTS vendors and frame processors are not exposed: the engine owns them. The knobs that are exposed are the agent’s settings.
  • TLS or SRTP on SIP. 60db speaks SIP over UDP with plain RTP today. If your platform requires TLS or SRTP toward the target, terminate them at your own SBC or PBX, or use a stream call.
  • Stream calls and MCP or handoff. Stream calls do not support MCP tools or agent handoff. SIP-only features (REFER, trunk source rules, recording through the carrier) also do not apply to them. Recording works as for any stream call.
  • Anything measured elsewhere. Latency, concurrency and cost figures from your old setup do not carry over. Re-measure.

Pipecat as the audio source (stream-call route)

Pipecat’s Twilio serializer produces compatible media events, but it does not perform 60db’s startup handshake. An adapter must send this JSON message when the stream-call socket opens, before forwarding Pipecat audio:
Then forward the serializer’s base64 µ-law media events at 8 kHz. The agent’s replies come back as media events in the same style. Route them, and clear events (the caller cut in: drop audio you have not played), back through the pipeline. Without the startup message, sending audio first closes the socket with 1008. 60db does the speech, model and voice itself, so Pipecat only carries the transport.
Not qualified. This adapter arrangement has not been qualified against a real Pipecat pipeline. The example below runs on its own against a real 60db stream call, using generated µ-law silence as the audio source. Wiring it to a Pipecat transport is shown in the comments and is untested.
Notes for a real pipeline:
  • Send frames in real time, one every 20 ms, and keep sending silence while the caller is quiet. A gap reads as a dead line.
  • Keep every message under 4 KB. Up to 3 stream calls run at once per workspace.
  • An agent transfer message means “put the caller through on your side”: answer with {"event":"transfer_result","outcome":"joined"} (or busy, declined, no_answer, failed) within 10 seconds. See the stream call wire contract and Agent Stream WebSocket.

Checklist

  • Agent saved, tools declared, test call passes (and test script, once agent tests reach you).
  • Phone line created with the carrier’s allowed_addresses and the number; the dry-run check answers 200; a real test call is answered by the agent.
  • Transfers tried (turn on bridge_transfers if the carrier ignores REFER); a warm one if you use it.
  • Ten calls compared with the old setup on typical and slow answer delay and failed calls.
  • Webhooks, recordings and transcripts land where your systems expect them.
  • Carrier pointed back at the old setup once, to prove the rollback.