Skip to main content

Overview

A phone line of kind byo connects an agent to your own carrier or PBX over SIP. Your carrier bills the minutes; 60db bills the AI part (speech, LLM, memory) from your AI credits as for any call.
  • Inbound. Your carrier or PBX sends the call to hellokit-sip.60db.ai. The agent attached to the called number answers.
  • Outbound. Place a call with a byo line. 60db dials your carrier’s domain and the agent talks.
Phone lines appear in the dashboard as Phone lines with the subtitle SIP trunk. If you are coming from LiveKit or Pipecat, read Move from LiveKit or Pipecat first. To use 60db as the speech engine inside LiveKit instead, see the LiveKit integration.
Tested carriers. Only the 60db carrier has been tested end to end against a live server. Every other carrier and PBX recipe on this page uses standard SIP and is expected to work, but is untested. Settings screens change, so check each against your provider’s own documentation. The Kamailio and 3CX recipes are additionally marked not yet verified end to end.

What 60db needs from a call

Answers 60db gives to an inbound call:

Set it up

1

Create an agent

Create an agent with its script, voice and, if you need them, tools and a knowledge base. Copy its id
2

Create the phone line

POST /agents/phone-lines with kind: "byo", the number your carrier dials as inbound_number, the agent, and your carrier’s source addresses as allowed_addresses
3

Read the setup guide

GET /agents/phone-lines/{id}/setup returns what to enter at the carrier and what is still missing
4

Dry-run it

POST /agents/phone-lines/{id}/check says how an incoming call would be answered, before the carrier sends one
5

Point the carrier at 60db

Set the carrier’s destination to sip:+<number>@hellokit-sip.60db.ai:5060;transport=udp, then call the number

Create the line

No username or password is needed for a carrier that trusts your server’s IP and gives no login. Send both or neither. The rules are read once when a call arrives. Nothing is added to the audio or reply path.
Open lines. A byo line with an inbound number and an empty allowed_addresses is accepted, but then any source can send calls that are billed to your workspace. The response and the setup guide carry warnings: [{ "code": "open_trunk" }] and the dashboard shows it prominently. Set allowed_addresses.

The setup guide

GET /agents/phone-lines/{id}/setup is read-only. It is read from the stored line and is not on any call’s path.
warnings is a list of { code, message }: Nothing is enforced by the guide: an open line keeps working. It only tells you.

The dry-run check

POST /agents/phone-lines/{id}/check runs the same decision a real call would, without placing or receiving one.
inbound_enabled is false when inbound calls are not available on the environment at all. The check cannot prove your carrier can reach 60db. Only a real call does.

One number, one stack

A number can answer in exactly one place. Creating or updating a line is refused when the number is already used by any of:
  • another Agents phone line (inbound_number or an entry in numbers)
  • a Dialer number
  • a LiveKit realtime number
To move a number from one stack to another, remove it from the old one first.

Firewall and ports

The INVITE carries no password, so anyone who can reach the SIP port can start a call that is billed to your workspace. Restrict by address with allowed_addresses, and restrict on your own firewall too.
TODO (needs 60db operations, not published yet): the public source IP addresses of the hosted service. To allow outbound calls from 60db on your firewall or carrier’s IP allow-list you need them, and they are not listed here. Until they are published, ask 60db support. Do not guess or copy addresses from another provider.
  • Ask your carrier for all the addresses its SIP servers send from. They often have several. Calls from an address that is not listed are refused with 403.
  • Close everything else. SSH only from your own address.

NAT

  • 60db side. The hosted service advertises its public address in the SDP, so audio reaches it without any setting on your side.
  • Your side. A PBX behind NAT must put its public address in the SDP it sends, and forward its RTP range to the PBX. In Asterisk this is external_media_address, external_signaling_address and local_net; in FreeSWITCH ext-rtp-ip and ext-sip-ip. Without it you get ringing and then one-way or no audio.
  • Keep SIP ALG (a router feature that rewrites SIP) off. It commonly breaks both signalling and audio.

Number format

Most inbound problems are the number. 60db matches the user part of the request URI.
  • It must be E.164 with a leading +: +917965318709.
  • If your carrier writes 07965318709, 00917965318709 or 917965318709, either change the carrier’s number format or dial-pattern setting, or turn on normalize_numbers (and set default_country_code for the national form).
  • Caller numbers in allowed_numbers and caller_id are E.164 too.

Codecs

PCMU (G.711 µ-law) and PCMA (G.711 A-law), 8 kHz. Nothing else is negotiated. Put them in your trunk’s codec list and remove G.729, Opus and the rest, or the call may be refused with 488.

Recipes

For every recipe: give the call to sip:+<number>@hellokit-sip.60db.ai:5060;transport=udp, keep the number in +E.164 form, allow only PCMU and PCMA, switch off SRTP and TLS, and add the carrier’s or PBX’s public SIP address to the line’s allowed_addresses.

60db carrier (tested)

The 60db Dialer is the only carrier tested end to end: an inbound call arrives with INVITE sip:+917965318709@…, offers PCMA, PCMU and telephone-event, and is answered with PCMU. For a 60db Dialer number you do not create a byo line: add the number as a sixtydb line. See Create phone line.

Twilio, Telnyx, Plivo and other cloud carriers (untested)

Use their SIP trunking product (Twilio Elastic SIP Trunking, Telnyx SIP Connection, Plivo Zentrunk):
  1. Add an origination URI of sip:hellokit-sip.60db.ai:5060;transport=udp and assign your number to the trunk.
  2. Make sure the provider sends the number as E.164 with + in the request URI. If it sends the national form or drops the +, 60db answers 404. Most providers have a number-format or dial-pattern setting for this.
  3. Add the provider’s published SIP signalling addresses to the line’s allowed_addresses. If you use the wrong list you will see 403.
  4. Do not enable SRTP or TLS media.
  5. For outbound calls, create the line with the provider’s termination domain, plus username and password for credential auth, or leave both out and allow 60db’s source addresses at the provider (IP authentication). The caller_id must be a number the provider lets you present.

Indian carriers and dialers (untested)

Exotel, Knowlarity, Ozonetel and similar cloud-telephony dialers usually call this “SIP trunk”, “forward to SIP” or “SIP endpoint”. Enter the address above, and ask the provider for (a) the source addresses to allow and (b) to send the number as +91.... Many send numbers without the +, or with a leading 0. Fix that on their side, or use normalize_numbers with default_country_code: "91".

Asterisk (untested)

pjsip.conf and extensions.conf, to send the call for number +917965318709 to the agent:
<60db source IP address> is the hosted source address that is not yet published (see the TODO above). To receive outbound calls from the agent, add a from-60db context in extensions.conf that routes the dialled number to your trunk.

FreeSWITCH (untested)

In the dialplan, bridge the call out with the number in +E.164 form and PCMU allowed:

Kamailio (not yet verified end to end)

Written from standard Kamailio configuration, not run against 60db. Kamailio stays in the signalling path only, so audio flows directly between your carrier and 60db: the SDP your carrier sends must carry a reachable address (rtpengine is only needed if media must be anchored).
The address Kamailio sends from is the one to put in allowed_addresses. Use udp as the only listener transport toward 60db.

3CX (not yet verified end to end)

Written from 3CX’s generic SIP trunk model, not run against 60db. Menu names differ between 3CX versions, so check your version’s documentation.
  1. Add a Generic SIP Trunk (IP based) (no registration, no login).
  2. Registrar or proxy: hellokit-sip.60db.ai, port 5060, transport UDP.
  3. Codecs: PCMU and PCMA only. Turn SRTP and TLS off.
  4. Add an outbound rule that sends the numbers (or the extension that represents the agent) to this trunk, with the number in +E.164 form.
  5. Put the 3CX server’s public address in the line’s allowed_addresses.

Transfers

When the agent hands a caller to a person with transfer_targets:
  • Inbound calls, default. 60db sends a SIP REFER on the call’s own line, asking your side to call sip:<number>@<your domain>. Your carrier or PBX must support REFER on that trunk, and the trunk must be allowed to call the destination number (a trunk limited to one country cannot transfer outside it). A carrier that ignores REFER leaves the caller in silence. Test one real transfer before relying on it.
  • Inbound calls with bridge_transfers: true. 60db dials the person itself, using the line’s own login and caller ID, and joins the two. This works with a carrier that ignores REFER, but the carrier must let the line place calls (an inbound-only trunk refuses the INVITE), and the line carries both legs for as long as they talk, so you pay minutes for both.
  • Outbound calls. Always bridged.
See Call transfer. Warm transfer (the agent briefs the person first) is rolling out and needs a bridge.

Keypad tones (DTMF)

The agent can press keys on the other party’s phone (RFC 4733 tones) and collect digits the caller types. The other side must offer telephone-event in its SDP, or pressing keys is reported as not supported. The tool names send_dtmf and collect_digits are reserved. Digits go to the model as the tool’s result, so do not collect a secret the model should not see.

Limits

  • UDP only, plain RTP: no TLS and no SRTP. If your carrier requires TLS or SRTP toward its SIP target, the line does not work yet. Terminate TLS and SRTP at your own session border controller (SBC) or PBX and speak plain UDP and RTP to 60db over a path you control, or use a stream call, which runs over HTTPS and needs no SIP.
  • PCMU and PCMA only.
  • A call past a capacity limit hears busy (486).
  • Several calls at once are allowed on a line, up to your workspace’s limits. See Agents limits.

Troubleshooting

Use POST /agents/phone-lines/{id}/check first. It answers most “why 404 or 403” questions without a call.