Skip to main content

Twilio Connector

A Twilio connector streams live audio from a Twilio call into a VideoSDK room using Twilio Media Streams. You point your Twilio number's voice webhook at the connector, and Twilio opens a bidirectional WebSocket that carries the call audio into the room. No SIP trunk is required.

Setup takes three steps: create the connector, configure your Twilio number, and route the call to a room. If you are new to connectors, read the Connectors Overview first.

How It Works

  1. A caller dials your Twilio number.
  2. Twilio sends a voice webhook to your connector's webhook URL.
  3. VideoSDK resolves routing and responds with TwiML that tells Twilio where to stream the audio:
    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
    <Connect>
    <Stream url="wss://ingest.videosdk.live/twilio?ref=<callRef>" />
    </Connect>
    </Response>
  4. Twilio opens that WebSocket and streams audio. VideoSDK claims the call, joins the room, and bridges audio in both directions.

You do not implement the WebSocket protocol; Twilio handles it. Audio is G.711 μ-law (PCMU) at 8 kHz, in 20 ms frames of 160 bytes, and the call is identified by Twilio's CallSid.

Prerequisites

  • A VideoSDK account and API token. See Generate a VideoSDK Token.
  • An active Twilio phone number.
  • Your Twilio Account SID and Auth Token, from the Twilio Console.

Step 1: Create a Connector

Create the connector with a single API call. Setting defaultRoomId here is the fastest path to a working call, since every call then joins that room.

curl -X POST https://api.videosdk.live/v2/connectors \
-H "Authorization: Bearer $VIDEOSDK_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "twilio",
"name": "Main Twilio Connector",
"defaultRoomId": "abcd-efgh-ijkl",
"region": "us002"
}'
FieldTypeRequiredDescription
providerstringYesMust be twilio.
namestringNoA label to help you recognize the connector later.
defaultRoomIdstringNoRoom that calls join when no routing rule matches. Set this for the simplest setup.
defaultRuleIdstringNoFallback routing rule ID, for dynamic routing.
regionstringNoPins the media and ingest region (e.g., us002 or in002). When omitted, the region is derived from the caller.

The response contains the connector, including the webhookUrl you need for the next step:

{
"message": "Connector created successfully",
"data": {
"id": "cn_a7k2m9x5p3q8r1v0",
"provider": "twilio",
"name": "Main Twilio Connector",
"webhookUrl": "https://api.videosdk.live/v2/hooks/twilio/whk_7Ks9jD2mL4wQvB1xX3zP8C5hR6gN9fT0",
"defaultRoomId": "abcd-efgh-ijkl",
"defaultRuleId": null,
"region": "us002",
"createdAt": "2026-06-21T14:30:45.123Z"
}
}
FieldDescription
idConnector ID, prefixed with cn_. Use it to fetch, rotate, or delete the connector.
webhookUrlThe URL you configure in Twilio in the next step. It embeds the secret webhook key (whk_...).

Copy the webhookUrl from the response. You will paste it into Twilio in Step 2.

Keep the webhook URL private

Anyone who has the webhook URL can route calls into your room, because the key is part of the URL. If it leaks, rotate the key to invalidate the old URL.

Step 2: Configure Twilio

Give the webhookUrl from Step 1 to your Twilio number, so Twilio calls VideoSDK whenever the number rings.

  1. Open the Twilio Console and go to Phone Numbers > Manage > Active numbers.
  2. Select the number you want to use.
  3. Under Voice Configuration > A call comes in, choose Webhook.
  4. Paste the webhookUrl and set the method to HTTP POST.
  5. Save your changes.

That is the entire provider-side setup. From now on, when the number rings, Twilio posts to the webhook and VideoSDK replies with the <Connect><Stream> TwiML automatically.

tip

If your number is wired to a TwiML App instead of a number-level webhook, set the same webhookUrl as the app's Voice Request URL, with the method set to HTTP POST.

Step 3: Route the Call

Routing decides which room a call joins. You have three options, from simplest to most flexible:

  • Connector default. The defaultRoomId you set in Step 1 sends every call to one fixed room. Best for a single destination or for testing.
  • Per-call override. Append a roomId query parameter to the webhook URL in Twilio (...whk_xxx?roomId=<roomId>) to target a specific room for that number.
  • Routing rules. For different callers or numbers landing in different rooms, or to attach an AI agent, create a routing rule and reference it with defaultRuleId.

If you set defaultRoomId in Step 1, you can skip this step and move straight to testing.

Step 4: Test an Inbound Call

  1. Add a participant or AI agent to the target room, so there is audio to exchange.
  2. Call your Twilio number from any phone.
  3. Confirm that the caller hears the room and the room hears the caller.

If you registered lifecycle webhooks, you will see call-started, then call-answered, and finally call-hangup when the call ends. These are the quickest way to confirm the flow end to end.

Manage the Connector

List your connectors:

curl https://api.videosdk.live/v2/connectors \
-H "Authorization: Bearer $VIDEOSDK_TOKEN"

Fetch a single connector:

curl https://api.videosdk.live/v2/connectors/cn_a7k2m9x5p3q8r1v0 \
-H "Authorization: Bearer $VIDEOSDK_TOKEN"

Rotate the Webhook Key

Rotating the key invalidates the current webhook URL immediately and returns a new one. Update Twilio with the new URL right after, or calls will stop reaching VideoSDK.

curl -X POST https://api.videosdk.live/v2/connectors/cn_a7k2m9x5p3q8r1v0/rotate-key \
-H "Authorization: Bearer $VIDEOSDK_TOKEN"

Delete a connector:

curl -X DELETE https://api.videosdk.live/v2/connectors/cn_a7k2m9x5p3q8r1v0 \
-H "Authorization: Bearer $VIDEOSDK_TOKEN"

Lifecycle Webhooks

To track calls on your server, register a webhook URL and listen for events such as call-started, call-answered, and call-hangup. Each request carries a videosdk-signature header (a base64 RSA-SHA256 signature of the body) so you can verify it. Connectors use the same webhook system as SIP, so see SIP Webhooks for the full event list, payloads, and registration.

Troubleshooting

SymptomLikely cause and fix
Call connects but there is no audioNo one is in the target room, or defaultRoomId is wrong. Add a participant or agent and verify the room ID.
Twilio reports an application errorThe webhook URL is wrong or the method is not POST. Re-copy the URL from the connector and set the method to HTTP POST.
The stream never starts, or the call drops immediatelyThe claim expired (more than 90 seconds), or routing resolved no room. Confirm the number points at the current webhook URL and that a room is resolved.
Connector API calls return 401 or 403The Authorization token is missing or expired. See Generate a VideoSDK Token.
Audio works but quality is lowTelephony audio is 8 kHz narrowband μ-law by design. This is expected for PSTN calls.

API Reference

Connector APIs used in this guide:

Got a Question? Ask us on discord