Define Event Types for Outgoing Webhooks

When you send webhooks to your users, it's crucial to provide clear and well-defined event types, often referred to as "topics." This practice empowers users to subscribe only to the specific information they need, reducing unnecessary traffic to their servers and simplifying their integration with your platform. By offering granular control over webhook subscriptions, you enhance the developer experience for your users.

This guide explains how to implement an event type system for your outgoing webhooks using Hookdeck Connections and Filters features.

Implementing event types with Hookdeck

The core concept is to use Hookdeck's filter rules on Connections to represent user subscriptions to your event types. Your platform is responsible for defining the event types and including them in the webhook payload, while Hookdeck handles the logic of routing events based on user preferences.

Your platform's role

  1. Define a clear list of event types. Establish a consistent and well-documented set of event types that your platform can emit. For example:

    • user.created
    • user.updated
    • invoice.paid
    • invoice.failed
    • item.shipped
  2. Include the event type in the webhook payload. When your application publishes an event to a Hookdeck Source using the Publish API, you must include the event type within the request. You can place it in the JSON body or in a request header.

    A common approach is to use a type field in the JSON payload:

Example Event Payload
Copied json
{
  "type": "user.created",
  "data": {
    "id": "user_123",
    "name": "Jane Doe",
    "email": "jane.doe@example.com"
  }
}

Alternatively, you can use a custom header like X-Event-Type:

Publish API Call with Custom Header
Copied bash
curl -X POST "https://api.hookdeck.com/2024-03-01/events" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -H "X-Event-Type: user.created" \
  -H "X-Hookdeck-Source-Id: src_..." \
  -d '{ ... }'

User subscription UI

In your application's UI, you should allow users to select which event types they want to receive for a specific webhook endpoint.

When a user configures their subscriptions:

  1. Create or update their Hookdeck Connection. A Connection links a Source (your platform) to a Destination (the user's webhook URL).

  2. Add filter rules to the Connection. Based on the user's selection, add filter rules to their Connection to ensure only the desired events are delivered.

For example, if a user subscribes to invoice.paid events, the filter rule would be applied to either the body of the event or a custom header::

Body Filter Rule for a Single Event Type
Copied json
{
  "type": "invoice.paid"
}

If you used a header, the filter would be:

Header Filter Rule
Copied json
{
  "x-event-type": "invoice.paid"
}

Example scenario

Imagine a user wants to receive notifications for invoice.paid and invoice.failed at their endpoint https://example.com/webhooks/billing.

  1. Your platform creates a Destination for the user's URL and a Connection that links your Source to their new Destination.

  2. Your platform adds a filter rule to that Connection to match the two selected event types. The $in operator is perfect for this.

    Filter Rule for Multiple Event Types
    Copied json
    {
      "type": {
        "$in": ["invoice.paid", "invoice.failed"]
      }
    }
    
  3. When your platform publishes an invoice.paid event to the Source, Hookdeck evaluates the filter rule, finds a match, and delivers the Event to the user's Destination.

  4. When your platform publishes an order.created event, Hookdeck sees that it doesn't match the filter rule for this Connection and discards it, so it never reaches the user's server.

Managing event type definitions

To ensure your event types are easy to understand and use, maintain an internal registry or public documentation of all available types and their corresponding payload schemas.

When evolving your API, consider how you will version your event types and payloads to avoid breaking your users' integrations. A common strategy is to include a version number in the event type itself, such as user.created.v2.

To learn more about the features used in this guide, refer to the following documentation:

Filters ->

Conditionally allow and route events based on their contents.