return to Table of Contents, API

Webhooks

Webhooks are a convenient way for your web application be notified of events that happen in a Direct Mail project, without resorting to polling our API for changes. Your web application can be notified, in real-time, of the following events:

  • New address inserted
  • Address deleted
  • Address updated
  • Address unsubscribed
  • Address hard bounced
  • Campaign sent

Requirements

You will need to be familiar with the principles explained in our API Getting Started guide in order to use webhooks. In addition, your Direct Mail project will need to be moved to the cloud in order to take advantage of webhooks features.

How Webhooks Work

Webhooks work by watching your Direct Mail project for events that you want to be notified about (like a new address in your address group). When a matching event occurs, our servers will issue an HTTP POST request to the URL that you provided when you set up the webhook. The body of the request contains information about the event (for example, the new address that was added to the group). In order to acknowledge the request, your server should reply to the request with a 200 OK response.

Creating and Deleting Webhooks

Webhooks are created via our API (see the documentation for the web hooks resource). Webhooks can be deleted via our API or via the Direct Mail user interface (in the Share window). Webhooks are also deleted automatically if the Direct Mail project is removed from the cloud.

Zero, one, or more webhooks can be created for the same event in a project.

Handling a Webhook Request

When our servers invoke your webhook, an HTTP POST request will be made to the URL that you provided when the webhook was created. The request includes the following headers:

Header Description
X-Webhook-Event The event that triggered this webhook (e.g. address-inserted, campaign-sent, etc.)
X-Webhook-Event-ID An integer identifier for this instance of the event. Event IDs begin at 1 for each new webhook and increase monotonically. You are guaranteed to never receive a higher-numbered event before a lower-numbered event. You can use the event ID to ignore requests that you have already handled or prevent replay attacks.
User-Agent Requests from our servers can be identified (but not authenticated) by consulting this header. Please see the Authentication and Security section below for more information.
Content-Type The content type of the POST body: application/json; charset=utf-8.
Content-Length The length of the POST body.
X-Total-Count The number of JSON objects in the POST body.

The body of the request will be a JSON-encoded array with one or more objects. Each object is the resource that the event is describing. For example, the body of the webhook request for the address-inserted event would include an array with one object for each address that was inserted. This would typically just be one address, but could be more in the case of a batch insert. See the address resource for a description of the keys and values for an address object.

Your server should respond to all requests with the 200 OK status code. This lets us know that the event was handled and we can proceed to send your server the next event, if any.

If your server responds with the 410 Gone status code, the webhook will be deleted and no more requests will be made.

Our servers will not follow 3xx redirect responses.

Handling Failures

If our servers do not receive a 200 OK or 410 Gone response from your server, we will retry the request. Subsequent requests are delayed using an exponential backoff algorithm. After a 12 hours of failures, an email notification will be sent to the project owner and webhook creator. After seven days of failures, the webhook will be automatically deleted.

Authentication and Security

Webhooks can be created using either HTTP or HTTPS URLs. We strongly recommend using HTTPS to protect your data from being observed or altered while in transit across the Internet.

Your server may want to take steps to verify that requests made to your webhook URL are, in fact, coming from our servers and not a third-party. We recommend the following:

  1. Use an HTTPS webhook URL
  2. On your server, require HTTP Basic authentication when accessing your webhook URL
  3. Embed the username and password in the URL when you create the webhook. For example: https://username:password@www.yourserver.com/webhook/campaign-sent
  4. Keep the URL, username, and password secret

An alternate approach is to pass and verify a shared secret as a query parameter to your webhook URL.

Example

Here is an example of creating a webhook that will be invoked whenever an address in one of our groups is unsubscribed. Assume that you have already configured the URL http://requestb.in/t3e7ejt3 to accept webhook requests.

Using the API to create the webhook

POST /api/v2/projects/d9c858c81c98408b083e0a13edf589bc/webhooks HTTP/1.1
Authorization: Basic QzFENDREMjEtNTA4MC00NTM3LUFFOD
Accept: application/json
Content-Type: application/json
Host: secure.directmailmac.com
Content-Length: 135

{
    "events": [
        {
            "type": "address-unsubscribed"
            "options": {
                "address_group": "D0693CAB-1CAF-417A-8973-337DA5AD82F2"
            },
        }
    ],
    "url": "http://requestb.in/t3e7ejt3"
}

HTTP/1.1 201 Created
Date: Sat, 02 May 2015 00:58:53 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 483
Connection: close

{
    "date_created": "2015-05-01T17:58:54-07:00",
    "events": [
        {
            "type": "address-unsubscribed"
            "options": {
                "address_group": "D0693CAB-1CAF-417A-8973-337DA5AD82F2"
            },
        }
    ],
    "last_request_date": null,
    "last_response_status_code": null,
    "links": [
        {
            "href": "https://secure.directmailmac.com/api/v2/projects/d9c858c81c98408b083e0a13edf589bc/webhooks/427FD341-C3D1-4AAB-9788-0BCFFAFBA4B6",
            "rel": "self"
        }
    ],
    "next_retry_date": null,
    "url": "http://requestb.in/t3e7ejt3",
    "uuid": "427FD341-C3D1-4AAB-9788-0BCFFAFBA4B6"
}

Sample webhook HTTP POST request when johnd@example.com unsubscribes

POST /t3e7ejt3 HTTP/1.1
Host: requestb.in
X-Webhook-Event: address-unsubscribed
X-Webhook-Event-Id: 1
Content-Type: application/json; charset=utf-8
User-Agent: DirectMailHookBot/1.0.0
X-Total-Count: 1
Content-Length: 921

[
    {
        "bounced": false,
        "company_name": "ABC Widgets, Inc.",
        "custom_1": null,
        "custom_10": null,
        "custom_11": null,
        "custom_12": null,
        "custom_13": null,
        "custom_14": null,
        "custom_15": null,
        "custom_2": null,
        "custom_3": null,
        "custom_4": null,
        "custom_5": null,
        "custom_6": null,
        "custom_7": null,
        "custom_8": null,
        "custom_9": null,
        "email": "johnd@example.com",
        "first_name": "John Doe",
        "last_name": "Doe",
        "links": [
            {
                "href": "https://secure.directmailmac.com.test/api/v2/projects/187812f26ba37d9769d8691d2a83c95c/address-groups/D0693CAB-1CAF-417A-8973-337DA5AD82F2/addresses/2E4F29F2-65AC-414B-85ED-EE5D7AEADEBC",
                "rel": "self"
            },
            {
                "href": "https://secure.directmailmac.com.test/api/v2/projects/187812f26ba37d9769d8691d2a83c95c/address-groups/D0693CAB-1CAF-417A-8973-337DA5AD82F2",
                "rel": "group"
            }
        ],
        "marked": true,
        "number_of_groups": 1,
        "subscribe_date": null,
        "unsubscribe_date": "2015-05-01T19:42:44+0000",
        "unsubscribed": true,
        "uuid": "2E4F29F2-65AC-414B-85ED-EE5D7AEADEBC"
    }
]

Development and Debugging Tips

RequestBin

If you're just getting started with the implementation of your server-side webhook handling, you may find RequestBin to be a useful (and free) service. RequestBin provides you a URL that can be used to collect and display the webhook POST requests from our servers.

Paw

Paw is a handy macOS app for interacting with REST services. You can use Paw for building HTTP requests, sending requests to the Direct Mail API, and inspecting responses from the API. It is a convenient and friendly way to get started exploring our API.

Did you find this article helpful? Yes | No