David Multer
David Multer
Founder of Hookalu
Mar 27, 2019 4 min read

What's in a webhook request?

Webhooks are a simple, yet powerful approach for delivering event notifications to your application. In this article, I will focus on the aspect of webhooks that is most meaningful to you as an application developer, the payload. The payload contains data fields that convey the meaning of an event. These fields are typically sent in the body of a webhook HTTP request.

The exact format of this payload is entirely up to the source that sends you the webhook request. The most important data field describes the type of event that occurred. A service that handles mailing lists might include event types like subscribed, unsubscribed, and sent email. Each of these events would then include additional fields to identify a subscriber, delivery details, and so on. The type of event can be indicated in many ways, but is most clearly described when it follows a noun.verb format.

Here’s an example from the Stripe API documentation. Note the type field with a value of invoice.created. The event name follows the noun.verb format, making the intent of the event crystal clear.

{
  "id": "evt_1CiPtv2eZvKYlo2CcUZsDcO6",
  "created": 1530291411,
  "type": "invoice.created",
}

Events often include fields that are shared across multiple event types. The event type I just described is one example of a common field. Another common field you often find is used to represent the date and time that the event was generated. This timestamp can be represented in a variety of formats, timezones, and different levels of precision. The timestamp can be used to help identify duplicate events and ensure the correct ordering of events. Some events also include an identifier (ID) field to uniquely identify every event. This can be used as a more precise way to eliminate duplicate events.

Looking again at the Stripe example, you’ll find the id and created fields provide both ID and timestamp values. The timestamp is in UNIX Epoch time seconds format. Often you’ll find the time specified as a string in ISO-8601 format as well.

{
  "id": "evt_1CiPtv2eZvKYlo2CcUZsDcO6",
  "created": 1530291411,
  "type": "invoice.created",
}

In a few cases, you can control the fields that are sent in the payload. Datadog allows full configuration of custom payloads with whatever fields and values you like. Zendesk and Leanplum have standard event types that also let you configure additional custom fields.

The content type used in the HTTP request will affect the structure of the payload. The most common format you’ll find is JSON, which is very simple to process in a variety of application programming languages. A less common format is HTML form URL encoded data. You’ll need to decode key/value pairs for each type of event in this case. You might find the content encoded using XML in rare cases. You’ll need to use XML parsing libraries specific to your application programming language for these payloads.

Most payloads will be relatively small and convey the critical information you need to process a specific event. Other webhook sources expect you to make additional API requests to their service to collect more details related to the event. In a few rare cases, you’ll want to take special care when the payload size becomes very large. A few of these webhook sources can include file attachments directly in the payload that can be many megabytes in size.

The payload for most webhook requests contains a single event. A few webhook sources will batch these events into a single webhook payload. Batched events can help save you from a flood of HTTP requests when many events are sent at a time, but it then becomes your responsibility to handle processing for all events. Acknowledging a batched request lets the webhook source know that you have taken on this responsibility. Typically the payload will have a list of events in the webhook payload.

Here’s an example of batched events from Mailjet. The event field is used to identify the event type, the time field is in UNIX Epoch time format, and the MessageID field is unique for every event.

[
  {
    "event": "open",
    "time": 1552244670,
    "MessageID": 456,
  },
  {
    "event": "open",
    "time": 1552244731,
    "MessageID": 457,
  },
]

You should find detailed developer documentation on the webhook source website explaining exactly how they handle all the payload topics I’ve covered in this article. Be aware that it can be challenging to track down and understand all these details for each webhook source and the events they support.

Hookalu is here to help you tackle webhook complexity so you can focus on delivering business value to your customers.