Webhooks

How you can get notified of events that happen in Whippy.

Configuration

Whippy can be configured to send webhooks as POST requests for various events. This can be set up through the Developers tab in Settings. For each API key you can create many Developer Applications. An application can be associated with only one key. After you create an application, you can add Endpoints to it. These are endpoints of servers that would receive webhooks. You can have one that receives all webhooks or many for different events. Each developer endpoint is subscribed to different events and would receive webhooks for them. Developer applications and endpoints can be enabled and disabled by the users. In order to receive webhooks, both the developer application and the specific endpoint that the will be sent to need to be enabled.

Events

Whippy webhook events have a format that consists of an event resource and an event type joined by a dot. For example, for a newly created message, an event named "message.created" will be sent, while for an updated campaign "campaign.updated" will be sent. You don't have to receive webhooks for all events. When you create a developer endpoint, you choose which events you want to subscribed to. An endpoint can subscribe to many events, and an event can be added to many endpoints.

Webhook Body

The body of the webhook POST requests has the following format:

{
  "data": { ... },
  "event": "event.type",
  "request_id": "unique.id"
}

For example, for a new message the webhook sent would will have the following payload:

{
  "data":{
    "id":"5e09c7cc-27e8-4d91-89ee-4ea5bafaaa15",
    "to":"+14244023931",
    "body":"The answer to the Great Question is 42.",
    "from":"+12183925232",
    "step_id":null,
    "language":null,
    "direction":"OUTBOUND",
    "channel_id":"be1ecaf2-9ce7-448c-8755-e5009ccc4345",
    "contact_id":"8241b8e5-98a2-44d7-975b-15f5c2bf3cf4",
    "created_at":"2023-08-24T10:05:18.432652Z",
    "updated_at":"2023-08-24T10:05:18.432652Z",
    "attachments":[
      
    ],
    "campaign_id":null,
    "conversation_id":"742993a5-c9c6-4d7d-bf09-31417a1c04a9",
    "delivery_status":"pending",
    "step_contact_id":null,
    "translated_body":null,
    "campaign_contact_id":null,
    "translation_language":null
  },
  "event":"message.created",
  "request_id":"00552b38-d0e7-460f-9877-a7c8c8b2ff8c"
}

You can see a list of all webhook events with examples in the webhook examples section.

Retrying

If a webhook is not successful, it will be retried after a period of time. It will be retried 6 times with an increasing amount of time between them where the last attempt could happen on the following day. This is to ensure any issues on the receiving end have a higher chance of being resolved.

Whippy saves each webhook request and response so that you can at any time follow if the webhooks are processed as expected.

Ordering

Whippy webhooks are processed in the order they are created at, as they are all ordered based on our internal timestamps. This is important for message events, as creating and sending a message will result in approximately 4 events, one of type message.created and 3 of type message.updated. We want to ensure that the webhooks for these events are received in the same order they occur. However, if another event, for example campaign.created, happens around the same time as a message.created event, then there is no guarantee that these events will come in the correct order. This can happen due to concurrency and the fact that the processing time for webhooks of different resources may vary, e.g. a message.created event can start being processed right after a campaign.created event, and finish while campaign.created is still being processed.

Verification

Each Whippy webhook request contains the X-Whippy-Signature custom header. It contains a value that can be used to verify that the webhook is sent by Whippy. It is generated in the following manner:

  • for each webhook attempt, a UNIX timestamp is generated;
  • the body of the webhook is encoded to JSON without (without being prettified);
  • a the timestamp and the encoded body are added to a string with a dot between them, e.g. "unix_timestamp.encoded_body";
  • the string is encrypted by using a hash-based message authentication code (HMAC) with a SHA-256 cryptographic hash function using the API key associated with the developer application that the webhook is part of (each webhook is associated with the developer endpoint that it is sent to and each endpoint belongs to a developer application);
  • it is then Base64-encoded without padding;
  • in the end it is sent as the value for the X-Whippy-Signature together with the UNIX timestamp in the format of: "t=#{unix_timestamp},v1=#{signed_payload}". v1 stands for the signature scheme version which is currently 1, there are no other signature schemes as of now;
  • users can extract the timestamp and use their API key and webhook body to verify that the request is valid.

Testing

If you want to test receiving webhooks before integrating with your application, we recommend that using Pipe Dream’s Request Bin. You can create a public endpoint with a unique identifier and set it up as a Developer Endpoint in Whippy, and select which events you want the webhook url to subscribe to. Once you have this configured you can generate events by taking actions in Whippy e.g. sending a message, creating a contact or starting a campaign.

Helpful Resources

If you’re new to learning about webhooks or just need a refresher on how they work, here are some helpful resources that we have found useful for both technical and non technical audiences alike.