# Overview

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

Example events: `Application denied`, `Customer created`, `Transaction created`. See [Webhook Events](https://unit.co/docs/api/events.md) for the full list.

Important Info

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.

Suggestion

Unit highly recommends that you make your webhook handlers [Idempotent](https://en.wikipedia.org/wiki/Idempotence), 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:

### Unit IPs[​](#unit-ips "Direct link to Unit IPs")

| Environment | IP Addresses                                            |
| ----------- | ------------------------------------------------------- |
| **Sandbox** | `54.81.62.38`<br />`35.169.213.205`<br />`3.234.105.75` |
| **Live**    | `3.209.193.26`<br />`54.156.65.95`<br />`54.165.224.37` |

Please note that these IP addresses are subject to change.

Suggestion

On production, webhooks that were unresponsive for 7 days will change status to `Unavailable` and will cease to receive events until they are re-enabled.

On sandbox, webhooks that were unresponsive for 2 days will be changed to status `Unavailable`.

### Include Resources[​](#include-resources "Direct link to 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[​](#delivery-method "Direct link to 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.

It is recommended to use 'OnlyAuthorizationRequest' in case of implementing [Programmatic authorization of card use](https://unit.co/docs/api/cards-authorization-requests/overview.md#programmatic-authorization-of-card-use) with 'AtMostOnce' deliveryMode due to the sensitive nature of this flow.

Important Info

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.

Suggestion

When using the **At least once** delivery, retrying is performed using the [Fibonacci backoff](https://en.wikipedia.org/wiki/Exponential_backoff) algorithm, with up to 1 hour between retries.

## Securing your webhooks[​](#securing-your-webhooks "Direct link to Securing your webhooks")

### Ensure your server is only receiving the expected Unit requests.[​](#ensure-your-server-is-only-receiving-the-expected-unit-requests "Direct link to 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[​](#setting-up-your-secret-token "Direct link to 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[​](#verifying-payloads-from-unit "Direct link to 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.use(express.raw({type: ['application/json', 'application/vnd.api+json']}));

app.use((request, response, next) => {
    var signature = request.header("x-unit-signature")
    var hmac = crypto.createHmac('sha1', <your secret>)
    hmac.update(request.body)

    if(hmac.digest('base64') == signature) {
        next()
    }
    else {
        response.status(500).send("Signatures didn't match!")
    }
  })
  
app.post('/my-webhook', (request, response) => {
  response.send('request passed signature validation...')
})

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

## Subscription types[​](#subscription-types "Direct link to Subscription types")

We have 3 subscription types:

* 'All' - subscribe to all events
* 'OnlyAuthorizationRequest' - subscribe only to authorization request `authorizationRequest.pending`, `authorizationRequest.approved`, `authorizationRequest.declined`
* 'NotAuthorizationRequest' - subscribe to events except for authorization requests

## Testing[​](#testing "Direct link to 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[​](#create-webhook "Direct link to create-webhook")

Creates a webhook.

Note

A new webhook will not be created if there are already 100 webhooks with the status 'Enabled'. Please disable existing webhooks to proceed. Occurs only in the Sandbox environment.

|                   |                                  |
| ----------------- | -------------------------------- |
| Verb              | `POST`                           |
| URL               | `https://api.s.unit.sh/webhooks` |
| Required Scope    | `webhooks-write`                 |
| Data Type         | `webhook`                        |
| Timeout (Seconds) | `5`                              |

### Attributes[​](#attributes "Direct link to Attributes")

| Name                                                                  | Type    | Description                                                                                                                                                           |
| --------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| label[](#attributes_label "Copy link") Required                       | string  | A label describing the webhook.                                                                                                                                       |
| url[](#attributes_url "Copy link") Required                           | string  | The URL of the webhook endpoint.                                                                                                                                      |
| token[](#attributes_token "Copy link") Required                       | string  | The secret token (see [Securing your webhooks](#securing-your-webhooks)).                                                                                             |
| contentType[](#attributes_contentType "Copy link") Required           | string  | The type of content you wish to receive. Either `Json` or `JsonAPI`.                                                                                                  |
| deliveryMode[](#attributes_deliveryMode "Copy link") Required         | string  | The attempted delivery mode of the webhook. Either `AtMostOnce` or `AtLeastOnce`.                                                                                     |
| includeResources[](#attributes_includeResources "Copy link") Optional | boolean | Default: false. Indicates whether to include full resource in events payload.                                                                                         |
| subscriptionType[](#attributes_subscriptionType "Copy link") Optional | string  | specify the subscription type. Default: All. Either 'All' or 'OnlyAuthorizationRequest' or 'NotAuthorizationRequest'(see [Subscription types](#subscription-types)) . |

Example Request:

CURL

```
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,
      "subscriptionType": "OnlyAuthorizationRequest"
    }
  }
}'
```

## Get by Id[​](#get-webhook "Direct link to get-webhook")

Get a webhook resource by id.

|                   |                                       |
| ----------------- | ------------------------------------- |
| Verb              | `GET`                                 |
| URL               | `https://api.s.unit.sh/webhooks/{id}` |
| Required Scope    | `webhooks`                            |
| Timeout (Seconds) | `5`                                   |

### Response[​](#response "Direct link to Response")

Response is a JSON:API document.

#### 200 OK[​](#200-ok "Direct link to 200 OK")

| Name                               | Type                                       | Description                                               |
| ---------------------------------- | ------------------------------------------ | --------------------------------------------------------- |
| data[](#response_data "Copy link") | [Webhook](https://unit.co/docs/api/resources.md#webhook) | The requested resource after the operation was completed. |

CURL

```
curl -X GET 'https://api.s.unit.sh/webhooks/10' \
-H "Authorization: Bearer ${TOKEN}"
```

## List[​](#list-webhooks "Direct link to list-webhooks")

List webhook resources. Paging can be applied.

|                   |                                  |
| ----------------- | -------------------------------- |
| Verb              | `GET`                            |
| URL               | `https://api.s.unit.sh/webhooks` |
| Required Scope    | `webhooks`                       |
| Timeout (Seconds) | `5`                              |

### Query Parameters[​](#query-parameters "Direct link to Query Parameters")

| Name            | Type                | Default | Description                                                                                                                                             |
| --------------- | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| page\[limit]    | integer             | 100     | Optional. Maximum number of resources that will be returned. Maximum is 1000 resources. See [Pagination](https://unit.co/docs/api/using-the-api.md#intro-pagination). |
| page\[offset]   | integer             | 0       | Optional. Number of resources to skip. See [Pagination](https://unit.co/docs/api/using-the-api.md#intro-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

```
curl -X GET 'https://api.s.unit.sh/webhooks?page[limit]=20&page[offset]=10' \
-H "Authorization: Bearer ${TOKEN}"
```

### Response[​](#response-1 "Direct link to Response")

Response is a JSON:API document.

#### 200 OK[​](#200-ok-1 "Direct link to 200 OK")

| Name                                 | Type                                                | Description                 |
| ------------------------------------ | --------------------------------------------------- | --------------------------- |
| data[](#response-1_data "Copy link") | Array of [Webhook](https://unit.co/docs/api/resources.md#webhook) | Array 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": "",
        "subscriptionType": "OnlyAuthorizationRequest"
      }
    },
    {
      "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",
        "subscriptionType": "NotAuthorizationRequest"
      }
    }
  ]
}
```

## Update[​](#update-webhook "Direct link to update-webhook")

Update a webhook.

|                   |                                      |
| ----------------- | ------------------------------------ |
| Verb              | `PATCH`                              |
| URL               | `https://api.s.unit.sh/webhooks/:id` |
| Required Scope    | `webhooks-write`                     |
| Timeout (Seconds) | `5`                                  |

### Attributes[​](#attributes-1 "Direct link to Attributes")

| Name                                                                    | Type    | Description                                                                     |
| ----------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------- |
| label[](#attributes-1_label "Copy link")                                | string  | The label of the webhook. To modify or add specify the new label.               |
| url[](#attributes-1_url "Copy link")                                    | string  | The URL of the webhook endpoint. To modify or add specify the new URL.          |
| contentType[](#attributes-1_contentType "Copy link")                    | string  | The content type of the webhook. To modify or add specify the new content type. |
| token[](#attributes-1_token "Copy link")                                | string  | The secret token of the webhook. To modify or add specify the token.            |
| includeResources[](#attributes-1_includeResources "Copy link")          | boolean | Indicates whether to include full resource in events payload.                   |
| subscriptionType[](#attributes-1_subscriptionType "Copy link") Optional | string  | specify the subscription type (see [Subscription types](#subscription-types)).  |

### Response[​](#response-2 "Direct link to Response")

Response is a JSON:API document.

#### 200 OK[​](#200-ok-2 "Direct link to 200 OK")

| Name                                 | Type                                       | Description                                               |
| ------------------------------------ | ------------------------------------------ | --------------------------------------------------------- |
| data[](#response-2_data "Copy link") | [Webhook](https://unit.co/docs/api/resources.md#webhook) | The requested resource after the operation was completed. |

Example Request:

```
{
  "data": {
    "type": "webhook",
    "attributes": {
      "label": "some label",
      "contentType": "Json",
      "includeResources": true,
      "subscriptionType": "OnlyAuthorizationRequest"
    }
  }
}
```

## Enable[​](#enable "Direct link to enable")

Enable a webhook.

Note

A webhook cannot be enabled if there are already 100 webhooks with the status 'Enabled'. Please disable an existing webhook before enabling a new one. Occurs only in the Sandbox environment.

|                   |                                             |
| ----------------- | ------------------------------------------- |
| Verb              | `POST`                                      |
| URL               | `https://api.s.unit.sh/webhooks/:id/enable` |
| Required Scope    | `webhooks-write`                            |
| Timeout (Seconds) | `5`                                         |

### Response[​](#response-3 "Direct link to Response")

Response is a JSON:API document.

#### 200 OK[​](#200-ok-3 "Direct link to 200 OK")

| Name                                 | Type                                       | Description                                               |
| ------------------------------------ | ------------------------------------------ | --------------------------------------------------------- |
| data[](#response-3_data "Copy link") | [Webhook](https://unit.co/docs/api/resources.md#webhook) | The requested resource after the operation was completed. |

CURL

```
curl -X POST 'https://api.s.unit.sh/webhooks/7/enable'
-H 'Content-Type: application/vnd.api+json'
-H 'Authorization: Bearer ${TOKEN}'
```

## Disable[​](#disable "Direct link to disable")

Disable a webhook. Webhooks that have been disabled or become `Unavailable` due to inactivity may be enabled.

|                   |                                              |
| ----------------- | -------------------------------------------- |
| Verb              | `POST`                                       |
| URL               | `https://api.s.unit.sh/webhooks/:id/disable` |
| Required Scope    | `webhooks-write`                             |
| Timeout (Seconds) | `5`                                          |

### Response[​](#response-4 "Direct link to Response")

Response is a JSON:API document.

#### 200 OK[​](#200-ok-4 "Direct link to 200 OK")

| Name                                 | Type                                       | Description                                               |
| ------------------------------------ | ------------------------------------------ | --------------------------------------------------------- |
| data[](#response-4_data "Copy link") | [Webhook](https://unit.co/docs/api/resources.md#webhook) | The requested resource after the operation was completed. |

CURL

```
curl -X POST 'https://api.s.unit.sh/webhooks/7/disable'
-H 'Content-Type: application/vnd.api+json'
-H 'Authorization: Bearer ${TOKEN}'
```
