Twilio Webhooks

Twilio offers several methods for subscribing to webhooks for incoming and outgoing messages. Webhooks can be configured:

To register an Event Stream webhook requires two steps. First, you must register the endpoint, called a Sink Instance, where the webhook callbacks will be delivered. Second, you must register the event types to subscribe to.

Create a Sink instance

You can register a Sink Instance in the Twilio Console, or via the Twilio CLI. This is how you would do it with the Twilio CLI:

twilio api:events:v1:sinks:create --description "My Event Streams webhook" \
--sink-configuration '{"destination":"https://mydomain.com/event-streams","method":"POST","batch_events":false}' \
--sink-type webhook

That will retun a SID and other metadata for the new sink instance.

Date Created                   Date Updated                   Description                  SID                                 Sink Configuration                                                                                 Sink Type  Status
Sep 17 2021 14:37:59 GMT-0700  Sep 17 2021 14:37:59 GMT-0700  My Event Streams webhook  DGb9b6d761eb1ae92aedcd1752d1e5fd7e  {"batch_events":false,"destination":"https://mydomain.com/event-streams","method":"post"}  webhook    active

Subscribe to Events

Next, you must subscribe to the events you want to receive at your sink instance endpoint. Following are the messaging events available:

# outbound message events
com.twilio.messaging.message.queued 
com.twilio.messaging.message.sent 
com.twilio.messaging.message.delivered 
com.twilio.messaging.message.failed 
com.twilio.messaging.message.undelivered
com.twilio.messaging.message.read

# inbound message events
com.twilio.messaging.inbound-message.received

To subscribe to all of these events, you would run the following command in the Twilio CLI:

twilio api:events:v1:subscriptions:create \
  --description "Subscribe to all 7 messaging events" \
  --sink-sid DGb9b6d761eb1ae92aedcd1752d1e5fd7e \
  --types '{"type":"com.twilio.messaging.message.queued","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.message.sent","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.message.delivered","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.message.failed","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.message.undelivered","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.message.read","schema_version":1}' \
  --types '{"type":"com.twilio.messaging.inbound-message.received","schema_version":1}'

Webhook Payloads

Once you’ve configured the Event Streams, you will begin receiving webhook callbacks for all the events you subscribed to.

Incoming Webhook Payload

Below is an example of an incoming Webhook payload.

[
    {
        "specversion": "1.0",
        "type": "com.twilio.messaging.inbound-message.received",
        "source": "/2010-04-01/Accounts/ACe674d877011b71537aec97f4e3745338/Messages/SM39f76ae22dacd2309e6f7c37de8981d7.json",
        "id": "EZ585d065eee9337a082f974e461d38648",
        "dataschema": "https://events-schemas.twilio.com/Messaging.InboundMessage/1",
        "datacontenttype": "application/json",
        "time": "2021-09-17T21:56:11.000Z",
        "data": {
            "fromState": "WA",
            "eventName": "com.twilio.messaging.inbound-message.received",
            "body": "Hello World!",
            "numMedia": 0,
            "toZip": "98112",
            "timestamp": "2021-09-17T21:56:11.000Z",
            "fromCity": "SEATTLE",
            "messageStatus": "QUEUED",
            "accountSid": "ACe674d877011b71537aec97f4e3745338",
            "to": "+12062991481",
            "toCountry": "SEATTLE",
            "toState": "WA",
            "toCity": "SEATTLE",
            "from": "+12063996587",
            "fromCountry": "US",
            "numSegments": 1,
            "messageSid": "SM39f76ae22dacd2309e6f7c37de8981d7",
            "fromZip": "98223"
        }
    }
]

Outgoing Webhook Payload

An outgoing Webhook payload looks like this. The key properties of this payload are the type, eventName, and messageStatus, which indicate the delivery status of the outgoing message.

[
    {
        "specversion": "1.0",
        "type": "com.twilio.messaging.message.delivered",
        "source": "/2010-04-01/Accounts/ACe674d877011b71537aec97f4e3745338/Messages/SM98f58340fe924a67b671c3c0c9242a9f.json",
        "id": "EZc8b34eba5a3c2a6abe5483e79f33bcf7",
        "dataschema": "https://events-schemas.twilio.com/Messaging.MessageStatus/1",
        "datacontenttype": "application/json",
        "time": "2021-09-17T22:00:13.531Z",
        "data": {
            "eventName": "com.twilio.messaging.message.delivered",
            "timestamp": "2021-09-17T22:00:13.531Z",
            "messageStatus": "DELIVERED",
            "accountSid": "ACe674d877011b71537aec97f4e3745338",
            "to": "+12063996576",
            "from": "+12065580734",
            "apiVersion": "2010-04-01",
            "messageSid": "SM98f58340fe924a67b671c3c0c9242a9f"
        }
    }
]

Note: The Twilio outgoing webhooks payload does not include a message body like the Zipwhip webhook payload does. If you rely on outgoing webhooks for the message body, you will have to perform an additional API request to fetch the body from the message resource.