Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM

On this page
Looking for more inspiration?Visit the

Secure webhooks


Maintain secure communication between your app and Twilio using encryption and authentication for your webhooks.


Encrypt traffic with HTTPS and TLS

encrypt-traffic-with-https-and-tls page anchor

To secure your web app, serve your web app using the Secure HyperText Transport Protocol (HTTPS(link takes you to an external page)). Twilio won't connect to an HTTPS URL with a self-signed certificate. Use a certificate from a provider such as Let's Encrypt(link takes you to an external page).

The Twilio Console always validates SSL certificates.


Authenticate with signatures

authenticate-with-signatures page anchor

Twilio signs all HTTP requests to your app with an X-Twilio-Signature HTTP header. Before responding to a webhook request, your web app should check for this HTTP header.

To create this signature, Twilio combines, then hashes, the following data:

  • Your account auth token
  • The x-twilio-signature header value from Twilio
  • The Webhook URL set in Twilio
  • All request parameters

Twilio hashes the signature with the HMAC-SHA1 hashing algorithm using your account auth token as the secret key.

(error)

Webhook parameters can change

The parameters included in webhook events vary by channel and event type and might change in the future. Twilio occasionally adds parameters without advance notice. Your integration with Twilio webhooks must support evolving parameter sets for signature validation. Twilio recommends using the provided signature validation library from a Twilio SDK. Don't implement your own signature validation.

Validate Signature of Request (x-www-form-urlencoded body)Link to code sample: Validate Signature of Request (x-www-form-urlencoded body)
1
// Get twilio-node from twilio.com/docs/libraries/node
2
const client = require('twilio');
3
4
// Your Auth Token from twilio.com/console
5
const authToken = process.env.TWILIO_AUTH_TOKEN;
6
7
// Store Twilio's request URL (the url of your webhook) as a variable
8
const url = 'https://mycompany.com/myapp';
9
10
// Store the application/x-www-form-urlencoded parameters from Twilio's request as a variable
11
// In practice, this MUST include all received parameters, not a
12
// hardcoded list of parameters that you receive today. New parameters
13
// may be added without notice.
14
const params = {
15
CallSid: 'CA1234567890ABCDE',
16
Caller: '+12349013030',
17
Digits: '1234',
18
From: '+12349013030',
19
To: '+18005551212',
20
};
21
22
// Store the X-Twilio-Signature header attached to the request as a variable
23
const twilioSignature = 'Np1nax6uFoY6qpfT5l9jWwJeit0=';
24
25
// Check if the incoming signature is valid for your application URL and the incoming parameters
26
console.log(client.validateRequest(authToken, twilioSignature, url, params));
Validate Signature of Request (application/json body)Link to code sample: Validate Signature of Request (application/json body)
1
// Get twilio-node from twilio.com/docs/libraries/node
2
const client = require('twilio');
3
4
// Your Auth Token from twilio.com/console
5
const authToken = process.env.TWILIO_AUTH_TOKEN;
6
7
// Store Twilio's request URL (the url of your webhook) as a variable
8
// including all query parameters
9
const url =
10
'https://example.com/myapp?bodySHA256=5ccde7145dfb8f56479710896586cb9d5911809d83afbe34627818790db0aec9';
11
12
// Store the application/json body from Twilio's request as a variable
13
// In practice, this MUST include all received parameters, not a
14
// hardcoded list of parameters that you receive today. New parameters
15
// may be added without notice.
16
const body = '{"CallSid":"CA1234567890ABCDE","Caller":"+12349013030"}';
17
18
// Store the X-Twilio-Signature header attached to the request as a variable
19
const twilioSignature = 'hqeF3G9Hrnv6/R0jOhoYDD2PPUs=';
20
21
// Check if the incoming signature is valid for your application URL and the incoming body
22
console.log(
23
client.validateRequestWithBody(authToken, twilioSignature, url, body)
24
);

To learn more about how Twilio signs requests to your app, see Validating Requests.

Understand parameters in signature validation

understand-parameters-in-signature-validation page anchor

Twilio webhooks deliver data to your app based on the content type of the request. To validate webhook signatures, prepare to ingest all three parameter types: query, form, and body.

Query parameters

query-parameters page anchor

Query parameters appear in the webhook URL after the ? character.

For example: The URL https://example.com/webhook?foo=1&bar=2 contains two query parameters: foo and bar.

As query parameters comprise part of the full URL, they get passed your validation function URL. Never extract query parameters and pass them separately to the function's params argument.

When making a webhook request, use the exact URL from Twilio including any URL-encoded characters(link takes you to an external page). If you decode or re-encode the URL, signature validation fails.

The POST request body includes form parameters using the content-type(link takes you to an external page) application/x-www-form-urlencoded. These parameters include webhook-specific fields such as CallSid, From, To, and Body.

Extract the form parameters from the request body and pass them to the validation function as a collection of name and value pairs, such as a dictionary or hash map. Twilio sorts these parameters alphabetically and appends them to the URL when calculating the signature. For a working example in your language, see the signature validation code samples.

Twilio can also send JSON payloads with the content type application/json. For these requests, Twilio appends a bodySHA256 query parameter to your webhook URL. The parameter value is a SHA-256 hash of the raw JSON request body.

When validating JSON webhooks:

  • Don't extract individual JSON properties or treat them as form parameters.
  • Use your SDK's JSON-specific validation method (for example, validateRequestWithBody) and pass the raw request body string.

The SDK performs two checks:

  1. It verifies that the SHA-256 hash of the raw body matches the bodySHA256 query parameter.
  2. It validates the request signature by including the bodySHA256 value during the calculation.

Tutorials for validating incoming Twilio requests

tutorials-for-validating-incoming-twilio-requests page anchor

To add Twilio request validation to your app, follow one of the following tutorials for your preferred language and framework.


Webhooks and IP addresses

webhooks-and-ip-addresses page anchor

Twilio provides services through cloud architecture. This results in Twilio not having a fixed range of IP addresses that issue webhooks.

When designing your network architecture, you may want to have one set of servers and a load balancer in a DMZ that receive webhook requests from Twilio. You can then proxy those requests to your private network.

To learn more about Twilio and IP addresses, see All About Twilio IP Addresses(link takes you to an external page).


Twilio supports HTTP Basic and Digest Authentication. This allows you to password-protect the TwiML URLs on your web server so that only you and Twilio can access them. You may provide a username and password via the following URL format.

https://username:password@www.myserver.com/my_secure_document

To learn more about how Twilio uses HTTP authentication for webhook requests, see the Security guide.