Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM
Accelerate development with AI

On this page
Looking for more inspiration?Visit the

Migrate to the Webhooks configuration API


Webhook authentication and delivery behavior have long lived in the webhook URL itself: credentials in a user:password@ prefix, delivery options in a #ct=… fragment. The Webhooks configuration API moves authentication and delivery behavior into Settings you manage through the API.

This guide is for endpoints already receiving webhooks. It migrates one endpoint at a time, each step is reversible, and traffic keeps flowing throughout. If you're building an integration from scratch, start with the quickstart.


Before you start

before-you-start page anchor

Rules apply to a single Twilio account. If you keep test and production environments in separate accounts, migrate the test account first.

Settings you create always use Server Name Indication (SNI)(link takes you to an external page). You can't turn SNI off using the configuration API: SNI lets your endpoint present the certificate matching its hostname, which is what makes certificate validation meaningful on shared infrastructure.

If your webhook URLs set sni=n, make your endpoint work with SNI before you complete Step 4: Shift traffic to your setting. Until you shift traffic to your Setting, your traffic uses the system Setting which honors sni=n as a connection override.

If your Setting also changes how Twilio signs webhooks, your endpoint has to accept that signature before any traffic uses it. To learn more, see Sign webhooks with shared keys.


Step 1: Inventory your webhook URLs

step-1-inventory-your-webhook-urls page anchor

Create a list of the domains and paths Twilio calls. Rules match URL patterns, so a single prefix can cover many webhooks at once.

Webhook URLs are set in several places:

  • Phone numbers and TwiML apps
  • Messaging Services
  • Studio flows
  • action and statusCallback attributes on TwiML verbs
  • StatusCallback parameters on API requests

For each URL, note whether it carries credentials in a user:password@ prefix, and which connection override keys its fragment sets. You'll reproduce these in a Setting.


Step 2: Bring one URL under a rule

step-2-bring-one-url-under-a-rule page anchor

Create a Rule for the URL that points at the system Setting. The system Setting reproduces legacy delivery, so nothing about the request changes. This step proves the Rule matches your URL before any behavior depends on it.

Fetch the system Setting's id:

1
curl -X GET 'https://webhooks.twilio.com/v1/Webhooks/Settings?type=SYSTEM' \
2
-u {API_KEY_SID}:{API_KEY_SECRET}

Then create the Rule:

1
curl -X POST https://webhooks.twilio.com/v1/Webhooks/Rules \
2
-H 'Content-Type: application/json' \
3
-u {API_KEY_SID}:{API_KEY_SECRET} \
4
-d '{
5
"matchType": "EXACT_MATCH",
6
"value": "https://api.example.com/webhooks/messaging",
7
"settings": [ { "settingId": "{SYSTEM_SETTING_ID}", "percentage": 100 } ]
8
}'

Poll the Operation for this rule until its status is COMPLETED, then confirm your webhooks still arrive as they did before. Each one now carries an X-Twilio-Webhooks-Settings header naming your Rule. If the header is absent, the Rule isn't matching the URL you expected. Check it against how Twilio matches a rule pattern.


Step 3: Build your setting

step-3-build-your-setting page anchor

Create a Setting that reproduces what the URL does. These are the equivalents:

Override or credentialSetting fieldNotes
user:password@ credentialsauthInline, or an AuthProfile when several Settings share one set of credentials.
ctconnection.connectTimeoutMsRequired in a Setting, even when you never set ct.
rtconnection.readTimeoutMsRequired in a Setting, even when you never set rt.
ttconnection.totalTimeoutMsOptional.
rcconnection.retryPolicy.retryCountSee the warning below.
rpconnection.retryPolicy.retryOn4xx, 5xx, ct, rt, and all become HTTP_4XX, HTTP_5XX, CONNECTION_TIMEOUT, READ_TIMEOUT, and ALL.
sniNoneSettings always use SNI.
eedgeZones.zonesA zone groups edge locations, so delivery survives one of them failing.
(warning)

Retries don't carry over

A URL with no rc retries once on connect timeout. A Setting that omits retryPolicy doesn't retry at all. To keep retrying, set retryPolicy explicitly.

Edge zones are a superset of edge locations. Where e=dublin pins delivery to one location, the zone containing Dublin can deliver from another location in that zone when Dublin is unavailable. To learn more, see Choose webhook edge zones.

Test the Setting against your endpoint before any traffic reaches it.


Step 4: Shift traffic to your setting

step-4-shift-traffic-to-your-setting page anchor

PATCH the Rule so it splits traffic between the system Setting and yours. Start with a small subset of traffic.

1
curl -X PATCH https://webhooks.twilio.com/v1/Webhooks/Rules/{RULE_ID} \
2
-H 'Content-Type: application/json' \
3
-u {API_KEY_SID}:{API_KEY_SECRET} \
4
-d '{
5
"settings": [
6
{ "settingId": "{SYSTEM_SETTING_ID}", "percentage": 90 },
7
{ "settingId": "{YOUR_SETTING_ID}", "percentage": 10 }
8
]
9
}'

Wait for the Operation to reach the COMPLETED status. The setting= value in the X-Twilio-Webhooks-Settings header shows which Setting handled each request, so you can watch the split. Once your endpoint is handling your Setting correctly, raise the share of traffic you're routing to your Setting. Once your Setting takes all the traffic, PATCH the Rule to a single-entry array. For the full pattern, see Shift traffic between settings.


Step 5: Remove credentials and overrides from the URL

step-5-remove-credentials-and-overrides-from-the-url page anchor

Once your Setting covers the URL, remove the credentials and the fragment it carries, as Twilio no longer requires them.

https://user:password@api.example.com/webhooks/messaging#ct=2000

becomes:

https://api.example.com/webhooks/messaging

Until you do this, the credentials stay in your configuration, your logs, and your source control.

Repeat from step 1 with your next URL.


At any point before step 5, PATCH the Rule back to the system Setting at 100%. Legacy delivery resumes once the Operation completes.

1
curl -X PATCH https://webhooks.twilio.com/v1/Webhooks/Rules/{RULE_ID} \
2
-H 'Content-Type: application/json' \
3
-u {API_KEY_SID}:{API_KEY_SECRET} \
4
-d '{ "settings": [ { "settingId": "{SYSTEM_SETTING_ID}", "percentage": 100 } ] }'

Deleting the Rule works too. Its webhooks go to the next Rule that matches them, or to legacy delivery if no Rule does.