Webhooks

We can forward you events in real-time to a web page of your choosing so that you integrate your own systems, for processing or analytics. You can choose what events you are interested in, so you only receive the information you want and need.

Creating a web page to receive data

Receiving events

In order to setup a webhook registration you will need to create a web page that the event data will be posted to. The web page will have JSON data sent to it via HTTPS POST and will be expected to return an appropriate HTTP status code such as: HTTP 200 - OK response if it successfully accepts the posted data; the expected HTTP status codes are:

HTTP Status Code

Type

Description

200, 201, 2XX

OK

Data accepted

401

Unauthorized

Issue authenticating the sender, or HMAC not valid

400

Bad Request

Could not process the data sent; this will not be retried

Any other

Failed to accept data, this will be retried

Retry Policy

If a failure occurs accepting data or your server cannot be contacted we will use a gradual back off retry schema for up to 24 hours and then move the event to dead queue. This system will ensure glitches and downtime do not result in data loss, but it will be delayed.

The retry schedule is as follows:

  • 5 seconds
  • 5 seconds
  • 30 seconds
  • 30 seconds
  • 1 minute
  • 2 minutes
  • 5 minutes
  • 10 minutes
  • 15 minutes
  • 30 minutes
  • 1 hour
  • 2 hours
  • 4 hours
  • 4 hours
  • 4 hours
  • 4 hours
  • 4 hours

Processing the events

Maximum permitted time

Your system will be permitted 10 seconds to respond to a forwarded event before we will consider the server unresponsive and the event send in error. We strongly recommend that your webhook reception page validates and then queues webhook events for processing, as the mechanism is designed for data exchange and 10 seconds is not enough time to reliably process events in.

Batch vs. single events

We can forward events either individually or as a batch of events. We strongly recommend that you design your webhook reception page to accept batches of events, as this can greater improves efficiency, especially during peak times.

Batches

Batches of events are very simply a JSON array of individual webhook events.

You can control the maximum amount of events in a batch as part of your webhooks configuration [1-500] and the maximum amount of time we should wait before sending the batch of events [1-60 seconds].

We send the batch of events when either of the conditions below is met:

  • The batch is full; it hit the maximum number of events permitted; or...
  • The time since the last batch was sent has exceeded the batch timeout limit

By tweaking the values for the batch timeout and maximum batch size you can finely tune the webhook between efficiency and responsiveness.

Single events

Each forwarded event is sent individually, and therefore at peak times your system must be able to accept many parallel calls.

{
  "eventId": "ca58832d-d67a-412e-9b28-e51b675ea142",
  "accountId": 123,
  "apiSpaceId": "c124df6e-4352-4b26-a32a-c3032bea7a01",
  "name": "message.sent",
  "payload": {
    "id": "ec7e182f-4d87-4135-b989-b26ab8d74f05",
    "details": {
      "channel": "sms",
      "additionalInfo": {
        "to": "441231123123",
        "successful": true
      },
      "channelStatus": {
        "sms": {
          "status": "sent",
          "details": {
            "to": "441231123123",
            "successful": true
          },
          "updatedOn": "2017-04-11T08:19:48.106Z"
        }
      }
    },
    "updatedOn": "2017-04-11T08:19:48.106Z"
  },
  "revision": 2,
  "etag": "\"2e-PNWSn3HlxaIB/CYz7LaR1XhMvDE\"",
  "timestamp": "2017-04-11T08:19:48.494Z"
}
[
  {
    "eventId": "ca58832d-d67a-412e-9b28-e51b675ea142",
    "accountId": 123,
    "apiSpaceId": "c124df6e-4352-4b26-a32a-c3032bea7a01",
    "name": "message.sent",
    "payload": {
      "id": "ec7e182f-4d87-4135-b989-b26ab8d74f05",
      "details": {
        "channel": "sms",
        "additionalInfo": {
          "to": "441231123123",
          "successful": true
        },
        "channelStatus": {
          "sms": {
            "status": "sent",
            "details": {
              "to": "441231123123",
              "successful": true
            },
            "updatedOn": "2021-04-11T08:19:48.106Z"
          }
        }
      },
      "updatedOn": "2021-04-11T08:19:48.106Z"
    },
    "revision": 2,
    "etag": "\"2e-PNWSn3HlxaIB/CYz7LaR1XhMvDE\"",
    "timestamp": "2021-04-11T08:19:48.494Z"
  },
  {
    "eventId": "1b4d4b5e-4176-4c91-a01c-3c927bd75a1a",
    "accountId": 123,
    "apiSpaceId": "c124df6e-4352-4b26-a32a-c3032bea7a01",
    "name": "message.sent",
    "payload": {
      "id": "fc1df0c5-35b8-4d34-bcc3-1994df7b6cdf",
      "details": {
        "channel": "sms",
        "additionalInfo": {
          "to": "44321321321",
          "successful": true
        },
        "channelStatus": {
          "sms": {
            "status": "sent",
            "details": {
              "to": "44321321321",
              "successful": true
            },
            "updatedOn": "2021-04-11T08:19:48.106Z"
          }
        }
      },
      "updatedOn": "2021-04-11T08:19:48.106Z"
    },
    "revision": 2,
    "etag": "\"2e-PNWSn3HlxaIB/CYz7LaR1XhMvDE\"",
    "timestamp": "2021-04-11T08:19:48.494Z"
  }
]

Event message structure

Each event will be sent in a standard envelope message with a payload that is the actual event data. The event payloads are documented in the sub sections following this page, such as App Messaging - Message Events .

The envelope format is:

Property

Type

Description

eventId

string

The unique identifier for this event

accountId

int

The account id the event is associated with

apiSpaceId

string

The API Space Id the event is from

name

string

The name/type of the event being received

payload

object

The specific event data (see this sections pages for more details)

revision

int

The revision number for the event which increments with each event

etag

string

The ETag entity hash, commonly used for detecting change

timestamp

date time

The UTC time the event occurred in ISO 8601 format

The following is an example event you could receive:

{
  "eventId": "ca58832d-d67a-412e-9b28-e51b675ea142",
  "accountId": 123,
  "apiSpaceId": "c124df6e-4352-4b26-a32a-c3032bea7a01",
  "name": "message.sent",
  "payload": {
    "id": "ec7e182f-4d87-4135-b989-b26ab8d74f05",
    "details": {
      "channel": "sms",
      "additionalInfo": {
        "to": "441231123123",
        "successful": true
      },
      "channelStatus": {
        "sms": {
          "status": "sent",
          "details": {
            "to": "441231123123",
            "successful": true
          },
          "updatedOn": "2017-04-11T08:19:48.106Z"
        }
      }
    },
    "updatedOn": "2017-04-11T08:19:48.106Z"
  },
  "revision": 2,
  "etag": "\"2e-PNWSn3HlxaIB/CYz7LaR1XhMvDE\"",
  "timestamp": "2017-04-11T08:19:48.494Z"
}
{
  "eventId": "e8b015b0-dd11-4f2d-a4b8-52c20739e16b",
  "accountId": 123,
  "apiSpaceId": "c124cf6e-4352-4b26-a71a-c3032bea7a01",
  "name": "profile.create",
  "payload": {
    "id": "Bob Smith"
  },
  "revision": 0,
  "etag": "\"15-w27xhc3Oc4ZW/h3hpKppJQ88/rU\"",
  "timestamp": "2017-04-10T14:52:29.484Z"
}

📘

Testing made simple

You can test receiving events simply by creating a request bin page for free, setting this as the URL for your webhook. Alternatively if you want to receive the data to your development machine then NGROK is a great tool for achieving this.

Security

The following processing and guidance should be followed in order to ensure your webhook remains secure:

HTTPS Recommended

We will forward data to either HTTP or HTTPS URLs, but we recommend using HTTPS connections to ensure data privacy. Please ensure your web page can accept HTTPS requests, and uses a certificate from a public certificate authority as we cannot accept self signed certificates.

Authenticating and verifying data

We use the HMAC hashes to both authenticate and ensure the data has not been altered in transit.

We will use the secret you configure on your webhook settings to create a hash of the event data (HTTP body) using the HMAC SHA-1 algorithm and then store this in the requests HTTP headers as X-Comapi-Signature. When you receive data via your webhook page your must create a hash of the received request body using UTF-8 encoding with the SHA-1 algorithm and your secret, and then compare it against the received hash from the X-Comapi-Signature HTTP header. If they match you can trust the data, otherwise you should reject the data and return a HTTP 401.

🚧

Ensure you calculate the HMAC on the raw body

Many web frameworks will give you access to a web requests body data but after they have interpreted it e.g. created a object from JSON. Any change to the data at all will cause the HMAC hash to differ, and therefore it is very important to calculate your HMAC on the raw HTTP body data. See the Webhook Quick Starts for coding examples of how to do this.

🚧

The HMAC is not Base64 encoded!

Some out of the box HMAC SHA-1 algorithms return the HMAC result Base64 encoded, please note we do not Base64 encode the HMAC result!

Revision processing

The Revision property will increment for each message type, therefore giving you an indication of relative order. The sequence may not be contiguous, but will always increment as more events are generated.

In some circumstances the Revision property value can be used to recognise when it is safe to discard data, such as when you receive a message status update with a lower revision id than the last one you processed for a message.

🚧

We do not guarantee events in the correct sequence

Due to the nature of large distributed systems we cannot guarantee the order events will be forwarded in exactly the chronological order they occurred in, and therefore the provide a Revision property to help you sequence the events when you receive them.

Deduping

On rare occasions we will send an event more than once, this is called the "at least once" pattern. To avoid issues we recommend using the eventid to dedupe received events.

Setting up to receive data from the webhook

Configure the forwarding

To setup or modify a webhook registration go to the Enterprise Communications Portal and open the Hub -> Webhooks page from the left hand menu, your configured webhooks will be displayed:

Setting up a webhookSetting up a webhook

Setting up a webhook

Adding a new webhook registration

  • Click the Add new Webhook button to open the new webhook wizard
  • In the wizard fill in the Name field with a meaningful name for your webhook e.g. Analytics feed
  • Add your URL to your webhook page to the Target URL field
  • Add a secret to be used to hash your events, so that you can verify we sent the data and it hasn't been tampered with (See the security section above)
  • Select whether you want batches of events, or individual events sending; we recommend batches
    • Select the maximum amount of events that can be in a batch
    • Select the maximum time in seconds a batch will wait before being sent
  • Click Next to choose the webhook events you want to receive
  • Choose your events to receive, either pick one of the event templates such as Message events (A good option for understanding your messaging) or click Advanced Options to pick your own

🚧

Only take the events you need!

To maximise webhook performance and to save your system having to process events that you don't need which take up resources please only select the webhooks events you need.

  • Now click Create to create the webhook

👍

Check out the quick starts....

See our Receiving Data using Webhooks quick start for some example code for creating a webhook reception page.