Webhook events are a facility to stream real-time information about email delivery and user engagement from PostageApp directly into applications.

These require an always-on HTTP or HTTPS receiver that can ingest JSON or URI-formatted POST payloads. Adding one of these to an existing application is usually quite straightforward.

Event Types

Webhook events can be sent whenever one of the following events occur:

  • Delivered Message (delivered)
  • Failure Message (failed)
  • Bounced Message (bounced)

These events require open and click tracking to be enabled:

  • Message Opened (opened)
  • Link Clicked (clicked)

Additional events may be provided for hard unsubscribe requests made through the PostageApp opt-out portal:

  • Unsubscribed (unsubscribed)

Where the destination domain provides a Spam Feedback Loop service, spam reports will be processed and forwarded:

  • Spam Complaint (spammed)

Payload Formats

The payload can be delivered in one of two formats. The JSON payload type is the easiest to handle. The URL-Encoded form is provided for applications which do not easily ingest JSON-formatted payloads.

The default format for new webhooks is JSON v1.1.

JSON (Version 1.1)

Delivered as a JSON payload with a Content-Type header of application/json. The structure resembles the following and varies depending on which variables are defined in either the API call and/or the template(s) involved:

{
  "event": "delivered",
  "account": "example",
  "project": "Example Webhook Message",
  "message_id": 532124327,
  "message_uid": "9586ea80bd6cd17a09bbecaeab43303cd5e0340a",
  "message_headers": [
    [
      "x-example",
      "Example Header "
    ],
    [
      "Subject",
      "This is a test email!"
    ],
    [
      "From",
      "Webhook Demonstration <demo@postageapp.com>"
    ]
  ],
  "message_variables": {
    "global_variable": "(global)",
    "parent_variable": "(parent)",
    "child_variable": "(child)",
    "recipient_variable": "(recipient: demo@postageapp.com)"
  },
  "recipient": "demo@postageapp.com",
  "domain": "postageapp.com",
  "template": "sample_child_template",
  "timestamp": "2020-01-09 03:52:00 UTC",
  "token": "k97CWrl4_Zyawm2JAHqjM18fgwZygQKVnP7t-Zm3pOHn8u4PbvojJ2Sp8tN7iW7YY4c=",
  "signature": "18f91ea056d496f62d3a2a78acf8b81662115584f2eb7976eddb75e6a04c4281",
  "smtp_code": "SMTP_250",
  "smtp_message": "2.0.0 OK Received"
}

message_headers contains a serialized payload describing the headers present in JSON format. These are presented as an array of pairs since some headers may be duplicated.

message_variables contains the final variables used to render the message for the listed recipient. These include variables supplied as globals in the API call as well as recipient-specific overrides.

The signature field represents the HMAC signature of the combination of timestamp and token signed with the project’s corresponding API key and can be used to verify the authenticity of the webhook call.

JSON (Version 1.0)

Delivered as a JSON payload with a Content-Type header of application/json. The structure resembles the following and varies depending on which variables are defined in either the API call and/or the template(s) involved:

{
  "event": "delivered",
  "account": "example",
  "project": "Example Project Name",
  "recipient": "test@example.com",
  "domain": "example.com",
  "template": "main_template",
  "timestamp": 1538849965,
  "token": "Df8BUmR_UKk3rccU10cdVnnJtigUhkR5Au6n8d-poJJ1WX_eP_T5y4Zdng6E1QnLZpk=",
  "signature": "efff14d0f321d5dd9b0b811b95d4d623086fa8fe9957dbc6fae5c5ab2e3122bd",
  "message_headers": "[[\"x-example\",\"Example Header \"],[\"Subject\",\"Demo Email\"],[\"From\",\"Sender Example <sender@postageapp.com>\"]]",
  "smtp_code": "SMTP_250",
  "smtp_message": "2.0.0 OK 1569262700 b21si12459791iot.118 - gsmtp",
  "example_variable": "Example Variable Value"
}

message_headers contains a serialized payload describing the headers present in JSON format.

The JSON 1.0 format remains available for legacy support and should not be used in new applications.

URL-Encoded (Option 1)

Delivered via POST with Content-Type application/x-www-form-urlencoded:

account=test&
domain=example.com&
event=delivered&
example_variable=Example+Variable+Value&
message_headers=%5B%5B%22x-example%22%2C%22Example+Header&+%7B%7Bexample_header_variable%7D%7D%22%5D%2C%5B%22Subject%22%2C%22Demo+Email%22%5D%2C%5B%22From%22%2C%22Sender+Example+%3Csender%40postageapp.com%3E%22%5D%5D&
project=Example+Project+Name&
recipient=test%40example.com&
signature=870df822af06537fd347044efb1b0d64be46106d704032bfabe8383c531b8973&
smtp_code=SMTP_250&
smtp_message=2.0.0+OK+1569262885+b3si15742426ion.94+-+gsmtp&
example_variable=Example+Variable+Value&
template=sample_child_template&
timestamp=1569262885&
token=mEzUhLii7KsTAlfuA4n2SLk-UWNVq5OIXYGf6abPuWWHn20f8OCmPvnlMjFk-YESdKM%3D

This is displayed on multiple lines for readability, but the actual payload has no newline characters.

message_headers contains a serialized payload describing the headers present in JSON format.