Configure webhook rules
Public Beta
The Webhooks configuration API, including the Webhook Settings and Webhook Rules resources, has been released as a Public Beta product. Before Twilio declares this product as Generally Available, the information contained in this document might change. Twilio might implement additional features or change others. No Twilio SLA covers Public Beta products.
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. | value |
PREFIX_MATCH | Every URL that begins with the given prefix. | prefix |
DEFAULT | Every webhook no other Rule matches. | none |
Each value and each prefix must be unique across your account. A duplicate returns 409 Conflict. Only one DEFAULT Rule is allowed per account.
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 60 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}'
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.
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. Webhooks that the Rule used to match fall through to the next matching Rule, or to no Setting at all.
- 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