Configure webhook rules
A Webhook Rule matches a webhook's destination URL and names the Webhook Setting that Twilio applies to it. Any webhook configuration needs a Rule. Without one, Twilio sends the webhook with no Setting applied.
Every Rule has a matchType that determines how it matches URLs and which other fields it needs.
| Property | Type | Necessity | Description |
|---|---|---|---|
id | string | read-only | The Rule's identifier, in the form webhooks_rule_ plus 26 characters. |
friendlyName | string | optional | A name to identify the Rule. Up to 255 characters. Defaults to blank. |
description | string | optional | What the Rule is for. Up to 1024 characters. |
matchType | enum | required | EXACT_MATCH, PREFIX_MATCH, or DEFAULT. |
value | string | required for EXACT_MATCH | The exact URL to match. Up to 2048 characters. |
prefix | string | required for PREFIX_MATCH | The URL prefix to match. Up to 2048 characters. |
settings | array | required | One or two Settings with the percentage of traffic each receives. |
createdAt | string | read-only | When the Rule was created, as an ISO 8601 timestamp. |
updatedAt | string | read-only | When the Rule last changed, as an ISO 8601 timestamp. |
matchType | Matches | Required field |
|---|---|---|
EXACT_MATCH | One specific URL without a trailing slash. | value |
PREFIX_MATCH | Every URL that begins with the given prefix. The prefix must end with /. | prefix |
DEFAULT | Every webhook no other Rule matches. | none |
The default Rule applies to every webhook in your account
A default Rule catches every webhook that no other Rule matches. Start with an exact match or a narrow prefix, and add a default Rule only after you've proven the Setting.
Scope Rules to endpoints you own
A Rule decides which destinations receive the credentials in its Setting. Match only URLs you control. Twilio recommends that you set an exact match or a narrow prefix over a broad one.
Each value and each prefix must be unique across your account once Twilio has adjusted them. A duplicate returns 409 Conflict. Only one DEFAULT Rule is allowed per account.
Write value and prefix as full URLs starting with http:// or https://, and without query parameters or fragments. A pattern containing either fails validation.
Twilio might store your pattern differently from the way you wrote it. It adjusts each incoming webhook URL in the same way before comparing, so a GET returns exactly what Twilio compares against.
| Part | What Twilio does |
|---|---|
| Scheme and host | Lowercases them |
| Default port for the scheme | Removes it |
| Query and fragment | Removes them |
| Path | Keeps your capitalization, percent-encoded with uppercase hex |
Submit https://A.com:443/Hook and Twilio stores and matches https://a.com/Hook. Because the path keeps its case, a Rule for /hook doesn't match a webhook sent to /Hook.
An http:// pattern and an https:// pattern are different. Write the scheme your webhook URL uses.
A pattern containing a . or .. path segment fails validation, including percent-encoded forms such as %2e%2e. Twilio doesn't resolve those segments in an incoming URL either, so a webhook URL containing one matches no exact or prefix Rule and falls through to the default Rule.
Wildcards aren't valid
matchType carries the matching behavior, so patterns don't take a * character. A * in value or prefix is treated as a literal character, not a wildcard, so it won't match what you expect. To match everything, use matchType: DEFAULT.
1{2"matchType": "EXACT_MATCH",3"value": "https://api.example.com/webhooks/voice/incoming",4"settings": [ { "settingId": "{SETTING_ID}", "percentage": 100 } ]5}
1{2"matchType": "PREFIX_MATCH",3"prefix": "https://api.example.com/webhooks/",4"settings": [ { "settingId": "{SETTING_ID}", "percentage": 100 } ]5}
Twilio evaluates your Rules in a fixed order and applies the first one that matches. You don't set or influence the order.
- Exact-match Rules, longest match first.
- Prefix-match Rules, longest prefix first.
- The default Rule.
If no Rule matches, Twilio sends the webhook with no Setting applied: Twilio doesn't authenticate itself to your endpoint, it signs the request with your account authentication token using HMAC_SHA1, and it uses default connection behavior.
GET /v1/Webhooks/Rules returns your Rules already sorted in this evaluation order.
Worked example
Given a prefix Rule for https://api.example.com/, a prefix Rule for https://api.example.com/webhooks/, and a default Rule:
- A webhook to
https://api.example.com/webhooks/smsuses the…/webhooks/Rule, because it's the longer matching prefix. - A webhook to
https://api.example.com/statususes thehttps://api.example.com/Rule. - A webhook to
https://other.example.net/hookuses the default Rule.
settings is an array of one or two entries. Each entry names a Setting and the share of matching traffic it receives.
| Property | Type | Necessity | Description |
|---|---|---|---|
settingId | string | required | The Setting to apply. |
percentage | integer | required | The share of matching webhooks, from 0 to 100. |
The percentages across the array must sum to exactly 100. Anything else returns a 400 validation error.
{ "settings": [ { "settingId": "{SETTING_ID}", "percentage": 100 } ] }
Because Settings are immutable, you roll out a configuration change by splitting a Rule's traffic across the old and new Setting, then moving the split.
-
Create the new Setting and test it.
-
PATCHthe Rule to send a small share to the new Setting.1curl -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": "{OLD_SETTING_ID}", "percentage": 90 },7{ "settingId": "{NEW_SETTING_ID}", "percentage": 10 }8]9}' -
Wait for the Operation to reach
COMPLETED, then confirm your endpoint is handling the new configuration. -
Repeat with a larger share, for example
50/50, then0/100. -
Once the new Setting takes all traffic,
PATCHthe Rule to a single-entry array and delete the old Setting.
To roll back, PATCH the percentages the other way. Because the array holds at most two Settings, stage one change at a time.
POST, PATCH, and DELETE return 202 Accepted with an Operation-Id header, a Location header pointing at the Operation, and a Retry-After header. The write is saved immediately, then takes 30 to 90 seconds to propagate to the plane that delivers your webhooks. See Operations.
1curl -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"friendlyName": "Production webhooks",6"matchType": "PREFIX_MATCH",7"prefix": "https://api.example.com/webhooks/",8"settings": [ { "settingId": "{SETTING_ID}", "percentage": 100 } ]9}'
A Rule changes live traffic
Once its Operation completes, a Rule applies to real webhooks, and undoing it also takes 30 to 90 seconds. Test the Setting first, and use the migration guide gradually to bring a URL over to your new Rule.
Returns Rules in evaluation order. Filter by Setting with settingId.
1curl -X GET 'https://webhooks.twilio.com/v1/Webhooks/Rules?settingId={SETTING_ID}' \2-u {API_KEY_SID}:{API_KEY_SECRET}
1curl -X GET https://webhooks.twilio.com/v1/Webhooks/Rules/{RULE_ID} \2-u {API_KEY_SID}:{API_KEY_SECRET}
Omit matchType to change only friendlyName, description, or settings. Include matchType to change how the Rule matches, and send the companion field for that type in the same request.
Settings are immutable, but Rules aren't. Editing a Rule changes which Setting live webhooks use.
1curl -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": [ { "settingId": "{NEW_SETTING_ID}", "percentage": 100 } ]6}'
1curl -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"matchType": "PREFIX_MATCH",6"prefix": "https://api.example.com/v2/webhooks/"7}'
1curl -X DELETE https://webhooks.twilio.com/v1/Webhooks/Rules/{RULE_ID} \2-u {API_KEY_SID}:{API_KEY_SECRET}
Returns 202 Accepted.
When you delete a Rule, traffic is then routed to the next most specific Rule
Webhooks the Rule matched go to the next most specific Rule that matches them, then to the default Rule, and otherwise to legacy delivery. Check that the Setting they land on authenticates and signs in a way your endpoint accepts.
- Up to 50 Rules per account. See error 59200.
- One
DEFAULTRule per account. - Each
valueand eachprefixunique across the account. - One or two Settings per Rule, with percentages summing to 100.
- Basic authentication isn't allowed on the default Rule. See error 59202.
Basic authentication on the default rule
Because a default Rule matches every otherwise-unmatched webhook URL, a Setting using Basic authentication on it would send your credentials to any destination Twilio calls. Twilio rejects that configuration with error 59202. Scope Basic authentication to an exact-match or prefix-match Rule, or use OAuth 2.0 or Digest on the default Rule.
- Track webhook rule changes, to confirm your change propagated
- Configuration API FAQs