Skip to main content

Subscription

Unit uses webhooks to notify your application when an event occurs.

Example events: Application denied, Customer created, Transaction created. See Events for the full list.

caution

New event types are continuously added to the platform. It is up to you to decide which events you want to process and how, but your implementation of the event listener must be able to handle new event types without breaking.

When one of those events occurs, an HTTP POST request is sent to the webhook's configured URL, allowing you to act upon it.

info

Unit highly recommends that you make your webhook handlers Idempotent, to ensure events are only handled once on your end.

Use Unit's Dashboard or API to create and manage your webhooks.

Unit sends POST requests to your webhook's URL from one of the following IP addresses:

EnvironmentIP Addresses
Sandbox54.81.62.38
35.169.213.205
Live3.209.193.26
54.156.65.95

Please note that these IP addresses are subject to change.

Include Resources#

When creating the webhook through the API or the Dashboard, you may specify whether you would like events to include the the full resource that is associated with the event.

When this option is being used every webhook that is related to a specific resource will have the full resource included in the payload of the event - for instance, the customer.created event will include the full customer resource.

Delivery method#

Unit supports two methods of delivery attempts for the webhook subscriptions:

  • At most once (single)
  • At least once (batched)

When creating the webhook, you can specify this in the dashboard (or programmatically via the API).

When using At most once, an attempt will be made to deliver a single webhook event to the specified URL. If the delivery fails for any reason (timeout or HTTP response code other than 200), the event will not be retried. An event will be fired as soon as it is created but only after a response for the last event has been received (therefore delays might occur when a large number of events are triggered at the same time or if responses from the client's webhook server are delayed).

When using At least once, multiple events will be batched in a single payload (in the form of an array of multiple event ids) and will be delivered to the specified URL, retrying delivery in case of a timeout, or a non-successful HTTP POST. Events will be fired as soon as they are created but only after a response for the last batch has been received. The maximum number events for a single batch is 64.

caution

To avoid processing the retried events more than once when using the At least once delivery mode, make sure to implement idempotence using the eventId as the key.

info

When using the At least once delivery, retrying is performed using the Fibonacci backoff algorithm for up to 1 hour.

Securing your webhooks#

Ensure your server is only receiving the expected Unit requests.#

Once your server is configured to receive payloads, it'll listen for any payloads sent to the endpoint you configured.

For security reasons, you probably want to verify that the payloads are coming from Unit.

To verify the payloads when creating a webhook you can set up a secret token which Unit will use to sign the payloads.

Setting up your secret token#

You'll need to set up your secret token in two places: Unit dashboard and your server. To set your token in Unit Dashboard:

  1. Navigate to Webhooks on the top menu under Developer section.
  2. Click on create and fill up the token field.

Verifying payloads from Unit#

If your secret token is set, Unit will use it to create a hash signature with the entire body of the webhook request.

This hash signature, encoded with base64 is passed along with each request in the headers as X-Unit-Signature.

Unit uses an HMAC SHA1 to compute the hash.

Example of a NodeJS server verifying webhook payload
const express = require('express')var crypto = require('crypto')const app = express()const port = 4000
app.post('/my-webhhok', (request, response) => {  response.send('request passed signature validation...')})
app.use(express.json());app.use(express.urlencoded({    extended: true}));
app.use((request, response, next) => {    var signature = request.header("x-unit-signature")    var hmac = crypto.createHmac('sha1', <your secret>)    hmac.update(JSON.stringify(request.body))
    if(hmac.digest('base64') == signature) {        next()    }    else {        response.status(500).send("Signatures didn't match!")    }  })

app.listen(port, (err) => {  console.log(`server is listening on ${port}`)})

Testing#

To test the Webhook functionality you can use https://webhook.site. This site will let you generate a unique URL to use for your Webhook and then capture incoming requests, allowing you to examine the event's contents.

Another alternative is to use https://ngrok.com which enables you to expose a port on your development machine to the internet.

Create Webhook#

Creates a webhook.

VerbPOST
Urlhttps://api.s.unit.sh/webhooks
Required Scopewebhooks-write
Data Typewebhook
Timeout (Seconds)5

Attributes#

NameTypeDescription
labelstringA label describing the webhook.
urlstringThe URL of the webhook endpoint.
tokenstringThe secret token (see Securing your webhooks).
contentTypestringThe type of content you wish to receive. Either Json or JsonAPI.
deliveryModestringThe attempted delivery mode of the webhook. Either AtMostOnce or AtLeastOnce.
includeResourcesbooleanOptional. Default: false. Indicates whether to include full resource in events payload.
Example Request:
curl -X POST 'https://api.s.unit.sh/webhooks'-H 'Content-Type: application/vnd.api+json'-H 'Authorization: Bearer ${TOKEN}'--data-raw '{  "data": {    "type": "webhook",    "attributes": {      "label": "some label",      "url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488d",      "token": "MyToken",      "contentType": "Json",      "deliveryMode": "AtLeastOnce",      "includeResources": false    }  }}'

Get by Id#

Get a webhook resource by id.

VerbGET
Urlhttps://api.s.unit.sh/webhooks/{id}
Required Scopewebhooks
Timeout (Seconds)5

Response#

Response is a JSON:API document.

200 OK#

FieldTypeDescription
dataWebhookThe requested resource after the operation was completed.
curl -X GET 'https://api.s.unit.sh/webhooks/10' \-H "Authorization: Bearer ${TOKEN}"

List#

List webhook resources. Paging can be applied.

VerbGET
Urlhttps://api.s.unit.sh/webhooks
Required Scopewebhooks
Timeout (Seconds)5

Query Parameters#

NameTypeDefaultDescription
page[limit]integer100Optional. Maximum number of resources that will be returned. Maximum is 1000 resources. See Pagination.
page[offset]integer0Optional. Number of resources to skip. See Pagination.
filter[since]RFC3339 Date string(empty)Optional. Filters the results that occurred after the specified date. e.g. 2020-01-13T16:01:19.346Z
filter[until]RFC3339 Date string(empty)Optional. Filters the results that occurred before the specified date. e.g. 2020-01-02T20:06:23.486Z
filter[fromId]Integer(empty)Optional. Filters the results that have an id that is higher or equal to the specified id. e.g. 17421
filter[toId]Integer(empty)Optional. Filters the results that have an id that is lower or equal to the specified id. e.g. 17432
curl -X GET 'https://api.s.unit.sh/webhooks?page[limit]=20&page[offset]=10' \-H "Authorization: Bearer ${TOKEN}"

Response#

Response is a JSON:API document.

200 OK#

FieldTypeDescription
dataArray of WebhookArray of webhook resources.
Example Response:
{  "data": [    {      "type": "webhook",      "id": "1",      "attributes": {        "createdAt": "2021-02-03T08:17:28.010Z",        "label": "111",        "url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488c",        "status": "Disabled",        "contentType": "Json",        "token": ""      }    },    {      "type": "webhook",      "id": "2",      "attributes": {        "createdAt": "2021-02-09T14:54:42.612Z",        "label": "some label",        "url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488d",        "status": "Enabled",        "contentType": "Json",        "token": "MyToken"      }    }  ]}

Update#

Update a webhook.

VerbPATCH
Urlhttps://api.s.unit.sh/webhooks/:id
Required Scopewebhooks-write
Timeout (Seconds)5

Attributes#

NameTypeDescription
labelstringThe label of the webhook. To modify or add specify the new label.
urlstringThe URL of the webhook endpoint. To modify or add specify the new URL.
contentTypestringThe content type of the webhook. To modify or add specify the new content type.
tokenstringThe secret token of the webhook. To modify or add specify the token.
includeResourcesbooleanIndicates whether to include full resource in events payload.

Response#

Response is a JSON:API document.

200 OK#

FieldTypeDescription
dataWebhookThe requested resource after the operation was completed.
Example Request:
{  "data": {    "type": "webhook",    "attributes": {      "label": "some label",      "contentType": "Json",      "includeResources": true    }  }}

Enable#

Enable a webhook.

VerbPOST
Urlhttps://api.s.unit.sh/webhooks/:id/enable
Required Scopewebhooks-write
Timeout (Seconds)5

Response#

Response is a JSON:API document.

200 OK#

FieldTypeDescription
dataWebhookThe requested resource after the operation was completed.
curl -X POST 'https://api.s.unit.sh/webhooks/7/enable' \-H "Authorization: Bearer ${TOKEN}"

Disable#

Disable a webhook.

VerbPOST
Urlhttps://api.s.unit.sh/webhooks/:id/disable
Required Scopewebhooks-write
Timeout (Seconds)5

Response#

Response is a JSON:API document.

200 OK#

FieldTypeDescription
dataWebhookThe requested resource after the operation was completed.
curl -X POST 'https://api.s.unit.sh/webhooks/7/disable' \-H "Authorization: Bearer ${TOKEN}"