📞 Beginner ~10 min Volatile · 14d

Connect Your Agent to a Real Phone Number

Import a Twilio number in four fields, or route your own SIP trunk into xAI, with the codecs, transfer types and monthly costs the docs specify.

The AI Dude · Published July 31, 2026 · Verified July 31, 2026

Assumes you've done: What a Voice Agent Actually Needs, How to Use Grok Voice Agent Builder: No-Code Tutorial. Advisory, not a gate — this page stands on its own.

A US local number on Twilio costs $1.15 a month and takes four fields to import into a managed voice platform. Routing your own SIP trunk into a raw API takes an origination URI, a signed webhook you have to verify, and a codec decision you cannot skip. Both end with a phone that rings. They differ in what you can change afterwards, which is the part worth reading before you pick one.

The managed import is four fields and a capability check

The ElevenLabs native Twilio integration is the shortest path on the page. Two credentials come out of the Twilio admin console at https://www.twilio.com/console: the Twilio Account SID and the Twilio Auth Token.

In the ElevenLabs dashboard, open the Phone Numbers tab and fill in four fields:

  • Label, a descriptive name, with "Customer Support Line" as the documented example.
  • Phone Number, your Twilio number.
  • Twilio SID.
  • Twilio Token.

What happens next is automatic and easy to misread. The platform detects the number's capabilities: purchased Twilio numbers support both inbound and outbound, while verified caller IDs support outbound only. If your agent is meant to answer calls and the inbound assignment dropdown never appears, the cause is the number's own type rather than the import.

For an inbound number you assign an agent to handle incoming calls from that dropdown. For outbound, use the Outbound call button next to the imported number, pick the agent, enter the recipient, and click Send Test Call. The docs attach a warning to that flow that people learn the hard way: "your agent will be the initiator of the conversation, so ensure your agent has appropriate initial messages configured." An outbound agent with no opening line dials someone and says nothing.

Pointing an Elastic SIP trunk at the Grok endpoint

The API route through Grok's speech-to-speech service starts with a registration step and one flat limitation. You create a Direct SIP phone number with origin: "byo_trunk" for a number you already own, and the SIP documentation states: "Provisioning xAI phone numbers via API is not supported." You bring the number. xAI routes it.

The registration response contains a webhook signing secret, and the docs are explicit about handling: "Store it securely; xAI returns it only once." Same for digest credentials, since "xAI never returns the password after creation." You get one chance at both.

Carrier-side, the destination is the same URI in every provider. The documented Twilio path:

  1. In the Twilio Console, go to Voice then Elastic SIP Trunking and create a trunk.
  2. Open the trunk's Origination settings and add the origination URI sip:{number}@sip.voice.x.ai;transport=tls.
  3. Assign a Twilio phone number to the trunk, or purchase a new number and attach it.
  4. If your application transfers calls mid-session, enable call transfer on the trunk.

Telnyx and Plivo get their own numbered steps on the same page. For Telnyx: Voice Suite then SIP Trunking, create an FQDN SIP Connection, add sip.voice.x.ai as the primary FQDN on port 5060 with record type A, set the inbound destination number format to E.164, and enable at least one of G.711 mu-law, G.711 A-law or G.722. For Plivo: SIP Trunking, create a trunk, choose Inbound, and create a new URI with FQDN sip.voice.x.ai.

Step four in the Twilio list is where the documentation runs thin. It tells you to enable call transfer on the trunk without naming the Twilio setting, so you are matching a description against the console yourself.

Once a call lands, three things happen in order. xAI sends a signed realtime.call.incoming webhook. You verify the webhook-id, webhook-timestamp and webhook-signature headers against your stored signing secret, then read data.call_id from the payload. Then you open wss://api.x.ai/v1/realtime?call_id={call_id} with your API key, send session.update to configure the agent for this call, and send response.create when the agent should start speaking. After that the socket behaves like any other session, with the caller's audio bridged in and assistant audio played back.

Transport, authentication and encryption are choices you make once

If you are bringing a trunk to ElevenLabs instead, its SIP trunking page spells out the same decisions with different names. The setup form asks for a Label, an E.164 Phone Number, a Transport Type, a Media Encryption setting and an Outbound Address, which must be a hostname or IP with no path.

The SIP URI format is sip:identifier@domain:port, with sip:+19991234567@sip.rtc.elevenlabs.io:5060 as the worked example. The identifier is mandatory, and it does not have to be a phone number; strings like 1000 or john are listed as valid.

Three settings deserve a decision rather than a default:

  • Authentication. Digest uses username and password credentials; ACL uses IP allowlisting. The docs pick a side: "Digest Authentication is strongly recommended as it provides better security without relying on IP allowlisting."
  • Transport. TCP, TLS ("Encrypted TLS transport for enhanced security"), or UDP, which the page labels "Connectionless transport (experimental; use TCP or TLS for production)."
  • Media encryption. Disabled, Allowed, or Required, the last of which "Enforces encrypted media streams."

And the codec floor, stated as a condition rather than a preference: "Your system must support either G711 or G722 audio codecs or be capable of resampling audio on your end." If you go the xAI route the equivalent session parameters are audio/pcmu for G.711 mu-law at 8000 Hz, audio/pcma for A-law, and audio/opus at 24000 Hz.

Keypad digits and transfers only exist on the phone leg

Two capabilities appear the moment a call arrives over SIP and are absent in a browser test, which is why they get skipped in testing and discovered in production.

DTMF. On a SIP session, keypresses are buffered and flushed to the model as text input. Three documented flush triggers: the user presses #, 2.5 seconds of idle time pass after the last keypress, or the user begins speaking, which preempts the digit buffer. Each press also emits an audit event to the client socket, input_audio_buffer.dtmf_event_received, carrying the digit and a received_at timestamp. The docs note that DTMF is only available on SIP sessions and is not emitted on direct WebSocket connections.

Transfers. On the xAI side these are two REST calls against the live call. POST /v1/realtime/calls/$CALL_ID/refer with a body of {"target_uri": "sip:agent@example.com"} hands the caller to another PSTN or SIP destination, and POST /v1/realtime/calls/$CALL_ID/hangup ends the call from your application.

On the ElevenLabs side, the same job is a system tool named transfer_to_number with three documented types, conference as the default behaviour, blind, and sip_refer, plus fields for transfer_destination, condition, transfer_type, post_dial_digits, custom_sip_headers and uui.

Read the limitations before you choose an import route, because they bind the two decisions together. The tool "is only available for phone calls and is not available in the chat widget." Blind transfers, warm transfer messages and post-dial digits are all listed as "only available when the agent's phone number is imported via the native Twilio integration." And "SIP REFER transfers do not support post-dial digits." So a number brought in over your own trunk gives up blind transfer and post-dial digits, and a number brought in through the Twilio import gives up whatever your carrier contract was for. That choice is made at import time.

What the number costs before anyone calls it

The carrier line is the small one. Twilio's US voice pricing lists a local number at $1.15 / mo with inbound at $0.0085 / min and outbound at $0.0140 / min. Toll-free is $2.15 / mo, outbound $0.0140 / min, inbound $0.0220 / min. Against a voice model billed at $0.05 to $0.08 per minute, telephony is under a fifth of the per-minute cost on an inbound local call.

Neither vendor's documentation covers porting an existing business number, and xAI's page rules out provisioning numbers through its API entirely. That work stays with your carrier, on your carrier's timeline, which for a main business line is measured in weeks. Point a spare number at the agent first and keep the switchboard where it is.

SIP trunkingTwiliovoice agent telephonyphone number setupDTMF
Changelog (1)
  • July 31, 2026 — First published.