# Webhooks

Source: https://developers.swell.is/backend-api/webhooks

Use webhooks to get notified about events that happen in your Swell account. Swell is an event-based architecture that allows you to configure webhooks on a variety of events that occur within each data model. A webhook can be configured by a Swell App, or manually from the Swell dashboard, to receive incoming HTTP calls that contain data describing the event.

To configure a webhook manually, visit your Swell dashboard and go to **Developer > Webhooks.** Specify the URL to your webhook handler and one or more events to receive.

> **Note:** To view webhooks that have fired within your store, see the `/events:webhooks` endpoint.

> **Tip:** See the [Apps webhook reference](https://developers.swell.is/apps/webhooks) to learn how to configure webhooks in Swell Apps.

## The webhook model

### Fields

- `id` (objectId, auto): The unique identifier for the webhook.
- `alias` (string): Alias used to refer to the webhook configuration.
- `api` (string, required): API the webhook subscribes to—`com` for the store API.
- `url` (string, required): URL endpoint for the webhook.
- `events` (array of string, required): Array of trigger events for the webhook.
- `enabled` (boolean): Determines whether the webhook is enabled. Defaults to `false`. Default: `false`.
- `auto_disabled` (boolean, auto): Indicates whether the webhook was automatically disabled. This occurs when the webhook has failed for 4 days with no successful delivery in that time.
- `retry_disabled_events` (boolean): Determines whether the webhook retries disabled events.
- `attempts_failed` (int): The number of failed webhook attempts.
- `date_first_failed` (date, auto): The date of the webhook's first failed attempt.
- `date_last_success` (date): Date of the last successful webhook delivery.
- `date_last_warned` (date, auto): The date of the last warning for a failed attempt.
- `date_final_attempt` (date): The final attempt for a webhook after continuous failed attempts. Webhooks are disabled after failing for 4 days with no successful delivery.

### Example response

```json
{
  "url": "http://localhost:5000",
  "enabled": false,
  "alias": "webhook",
  "description": null,
  "events": [
    "order.created",
    "order.submitted",
    "order.updated"
  ],
  "api": "com",
  "date_final_attempt": null,
  "date_scheduled": null,
  "date_created": "2021-09-27T16:30:11.837Z",
  "date_updated": "2021-10-28T16:04:21.648Z",
  "id": "6151f193ae97e82ccbf6f0a7"
}
```


## Create a webhook

When setting up webhooks for custom models, you will need to create them via the API referencing the events listed on the custom model. For webhooks that utilize Swell's standard models, we recommend configuration through the Swell dashboard under **Developer tools > Webhooks**—each standard model's events are easily referenced within the UI.

### Arguments

- `url` (string, required): URL endpoint for the webhook.
- `events` (array of string, required): Array of trigger events for the webhook.
- `id` (objectId, auto): The unique identifier for the webhook.
- `alias` (string): Alias used to refer to the webhook configuration.
- `api` (string, required): API the webhook subscribes to—`com` for the store API.
- `enabled` (boolean): Determines whether the webhook is enabled. Defaults to `false`. Default: `false`.
- `auto_disabled` (boolean, auto): Indicates whether the webhook was automatically disabled. This occurs when the webhook has failed for 4 days with no successful delivery in that time.
- `retry_disabled_events` (boolean): Determines whether the webhook retries disabled events.
- `attempts_failed` (int): The number of failed webhook attempts.
- `date_first_failed` (date, auto): The date of the webhook's first failed attempt.
- `date_last_success` (date): Date of the last successful webhook delivery.
- `date_last_warned` (date, auto): The date of the last warning for a failed attempt.
- `date_final_attempt` (date): The final attempt for a webhook after continuous failed attempts. Webhooks are disabled after failing for 4 days with no successful delivery.

### Example request

`POST /:webhooks`

**cURL**

```bash
$ curl https://api.swell.store/:webhooks \
  -u store-id:secret-key \
  -d url=http://localhost:5000 \
  -d "events[0]=order.created" \
  -d "events[1]=order.submitted"
```

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.post('/:webhooks', {
  url: 'http://localhost:5000',
  events: [
    'order.created',
    'order.submitted'
  ]
});
```

**PHP**

```php
<?php $swell = new \Swell\Client('store-id', 'secret-key');

$swell->post('/:webhooks', [
  'url' => 'http://localhost:5000',
  'events' => ['order.created', 'order.submitted']
]);
```

### Example response

```json
{
  "url": "http://localhost:5000",
  "enabled": false,
  "alias": "webhook",
  "description": null,
  "events": [
    "order.created",
    "order.submitted",
    "order.updated"
  ],
  "api": "com",
  "date_final_attempt": null,
  "date_scheduled": null,
  "date_created": "2021-09-27T16:30:11.837Z",
  "date_updated": "2021-10-28T16:04:21.648Z",
  "id": "6151f193ae97e82ccbf6f0a7"
}
```


## Retrieve a webhook

Retrieve an existing webhook using the id that was returned during creation.

### Arguments

- `id` (objectId, auto): The unique identifier for the webhook.
- `alias` (string): Alias used to refer to the webhook configuration.
- `api` (string, required): API the webhook subscribes to—`com` for the store API.
- `url` (string, required): URL endpoint for the webhook.
- `events` (array of string, required): Array of trigger events for the webhook.
- `enabled` (boolean): Determines whether the webhook is enabled. Defaults to `false`. Default: `false`.
- `auto_disabled` (boolean, auto): Indicates whether the webhook was automatically disabled. This occurs when the webhook has failed for 4 days with no successful delivery in that time.
- `retry_disabled_events` (boolean): Determines whether the webhook retries disabled events.
- `attempts_failed` (int): The number of failed webhook attempts.
- `date_first_failed` (date, auto): The date of the webhook's first failed attempt.
- `date_last_success` (date): Date of the last successful webhook delivery.
- `date_last_warned` (date, auto): The date of the last warning for a failed attempt.
- `date_final_attempt` (date): The final attempt for a webhook after continuous failed attempts. Webhooks are disabled after failing for 4 days with no successful delivery.

### Example request

`GET /:webhooks/:id`

**cURL**

```bash
$ curl https://api.swell.store/:webhooks/662ba123becf7601325cefa3 \
  -u store-id:secret-key
```

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/:webhooks/{id}', {
  id: '662ba123becf7601325cefa3'
});
```

**PHP**

```php
<?php $swell = new \Swell\Client('store-id', 'secret-key');

$swell->get('/:webhooks/{id}', [
  'id' => '662ba123becf7601325cefa3'
]);
```

### Example response

```json
{
  "url": "http://localhost:5000",
  "enabled": false,
  "alias": "webhook",
  "description": null,
  "events": [
    "order.created",
    "order.submitted",
    "order.updated"
  ],
  "api": "com",
  "date_final_attempt": null,
  "date_scheduled": null,
  "date_created": "2021-09-27T16:30:11.837Z",
  "date_updated": "2021-10-28T16:04:21.648Z",
  "id": "6151f193ae97e82ccbf6f0a7"
}
```


## Update a webhook

Update a webhook.

### Arguments

- `id` (objectId, required): The unique identifier for the webhook.
- `alias` (string): Alias used to refer to the webhook configuration.
- `url` (string): URL endpoint for the webhook.
- `events` (string): Array of trigger events for the webhook.
- `enabled` (boolean): Determines whether the webhook is enabled. Defaults to false.
- `retry_disabled_events` (boolean): Determines whether the webhook retries disabled events.
- `schedule` (object): Schedule for specifying when a webhook is to be fired.
  - `hour` (int): The hour for which to fire the webhook. Min `0`, max `23`.
  - `month_day` (int): The day of the month for which to fire the webhook. Min `1`, max `31`.
  - `month` (int): The month for which to fire the webhook. Min `1`, max `12`.
  - `week_day` (int): The month for which to fire the webhook. Min `0`, max `6`.
- `date_scheduled` (date): Date for which the webhook is scheduled to fire.

### Example request

**Update**

`PUT /:webhooks/:id`

**cURL**

```bash
$ curl https://api.swell.store/:webhooks/6151f193ae97e82ccbf6f0a7 \
  -u store-id:secret-key \
  -d enabled=true \
  -X PUT
```

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.put('/:webhooks/{id}', {
  id: '6151f193ae97e82ccbf6f0a7',
  enabled: true
});
```

**PHP**

```php
<?php $swell = new \Swell\Client('store-id', 'secret-key');

$swell->put('/:webhooks/{id}', [
  'id' => '6151f193ae97e82ccbf6f0a7',
  'enabled' => true
]);
```

### Example response

```json
{
  "url": "http://localhost:5000",
  "enabled": false,
  "alias": "webhook",
  "description": null,
  "events": [
    "order.created",
    "order.submitted",
    "order.updated"
  ],
  "api": "com",
  "date_final_attempt": null,
  "date_scheduled": null,
  "date_created": "2021-09-27T16:30:11.837Z",
  "date_updated": "2021-10-28T16:04:21.648Z",
  "id": "6151f193ae97e82ccbf6f0a7"
}
```


## List all webhooks

Return a list of webhooks.

### Arguments

- `expand` (string): Expand link fields and child collections by using the expand argument.

  - For example, `expand=account` would return a related customer account if one exists.

  When the field represents a collection, you can specify the query limit.

  - For example, `expand=variants:10` would return up to 10 records of the variants collection.

  See [expanding](https://developers.swell.is/backend-api/querying/expanding) for more details.
- `fields` (string): Returns only the specified fields in the result.

  - For example `fields=name,slug` would return only the fields `name` and `slug` in the response.

  Supports nested object and array fields using dot-notation.

  - For example, `items.product_id`. The product `id` is always returned.
- `include` (object): Include one or more arbitrary queries in the response which are potentially related to the main query.

  See [including](https://developers.swell.is/backend-api/querying/including) for more details.
- `limit` (int): Limit the number of records returned, ranging between `1` and `1000`. Defaults to `15`. Default: `15`.
- `page` (int): The page number of results to return given the specified or default `limit`.
- `search` (string): A text search is performed using the search argument. Searchable fields are defined by the model.

  - For example, `search=red` would return records containing the word "red" anywhere in the defined text fields.

  See [searching](https://developers.swell.is/backend-api/querying/searching) for more details.
- `sort` (string): Expression to sort results by using a format similar to a SQL sort statement.

  - For example, `sort=name asc` would return records sorted by name ascending.

  See [sorting](https://developers.swell.is/backend-api/querying/sorting) for more details.
- `where` (object): An object with criteria to filter the result.

  - For example, `active=true` would return records containing a field `active` with the value `true`.

  It's also possible to use query operators, for example, `$eq`, `$ne`, `$gt`, and more.

  See [querying](https://developers.swell.is/backend-api/querying) for more details.

### Example request

`GET /:webhooks`

**cURL**

```bash
$ curl https://api.swell.store/:webhooks?where[enabled]=true&limit=25&page=1 \
  -u store-id:secret-key \
  -G
```

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.get('/:webhooks', {
  where: { enabled: true },
  limit: 25,
  page: 1,
});
```

**PHP**

```php
<?php $swell = new \Swell\Client('store-id', 'secret-key');

$swell->get('/:webhooks', [
  'where' => [ 'enabled' => true ],
  'limit' => 25,
  'page' => 1,
]);
```

### Example response

```json
{
  "count": 4,
  "results": [
    {
      "url": "http://a30d184f.ngrok.io/api/testing",
      "enabled": true,
      "alias": null,
      "description": null,
      "events": [
        "order.created",
        "order.submitted",
        "order.updated"
      ],
      "api": "com",
      "date_final_attempt": "2022-05-09T16:49:19.017Z",
      "date_scheduled": "2022-05-03T03:00:00.000Z",
      "date_created": "2021-09-27T16:30:11.837Z",
      "date_updated": "2022-05-03T02:00:34.789Z",
      "attempts_failed": 30,
      "date_first_failed": "2022-05-02T16:49:19.017Z",
      "id": "6151f193ae97e82ccbf6f0a7"
    },
    {
      "url": "https://schema-webhooks-example.herokuapp.com/",
      "enabled": false,
      "alias": "Test",
      "description": "custom field test",
      "events": [
        "account.created",
        "account.deleted",
        "account.updated",
        "cart.created",
        "cart.deleted",
        "category.created",
        "category.updated",
        "coupon.created",
        "coupon.updated",
        "invoice.created",
        "invoice.updated",
        "order.created",
        "order.updated"
      ],
      "api": "com",
      "date_final_attempt": null,
      "date_scheduled": null,
      "date_created": "2021-04-05T14:22:58.995Z",
      "date_updated": "2021-04-05T14:24:49.173Z",
      "id": "606b1d42f82c45625c64d81f"
    },
    {
      "alias": "test_scheduled",
      "url": "http://a30d184f.ngrok.io/api/webhook3",
      "events": [
        "webhook.scheduled"
      ],
      "enabled": false,
      "schedule": {
        "hour": 0
      },
      "api": "com",
      "date_final_attempt": null,
      "date_scheduled": null,
      "date_created": "2020-04-30T22:25:23.019Z",
      "date_updated": "2020-05-01T17:31:25.304Z",
      "id": "5eab5052ccb62171e667e9e7"
    },
    {
      "alias": "example",
      "api": "com",
      "attempts_failed": 0,
      "date_created": "2017-02-05T19:18:51.000Z",
      "date_final_attempt": null,
      "date_first_failed": null,
      "date_updated": "2021-04-01T15:56:44.173Z",
      "enabled": false,
      "events": [
        "webhook.test",
        "product.updated",
        "order.submitted",
        "payment.succeeded"
      ],
      "url": "https://schema-webhooks-example.herokuapp.com/",
      "testField": "xyz",
      "id": "58977a9badc3891811b54f3c"
    }
  ],
  "page": 1,
  "page_count": 1,
  "limit": 25
}
```


## Delete a webhook

Delete a webhook.

### Arguments

- `id` (objectId, required): The id of the webhook to delete.

### Example request

`DELETE /:webhooks/:id`

**cURL**

```bash
$ curl https://api.swell.store/:webhooks/662ba123becf7601325cefa3 \
  -u store-id:secret-key \
  -X DELETE
```

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');

await swell.delete('/:webhooks/{id}', {
  id: '662ba123becf7601325cefa3',
});
```

**PHP**

```php
<?php $swell = new \Swell\Client('store-id', 'secret-key');

$swell->delete('/:webhooks/{id}', [
  'id' => '662ba123becf7601325cefa3',
]);
```

### Example response

```json
{
  "url": "http://localhost:5000",
  "enabled": false,
  "alias": "webhook",
  "description": null,
  "events": [
    "order.created",
    "order.submitted",
    "order.updated"
  ],
  "api": "com",
  "date_final_attempt": null,
  "date_scheduled": null,
  "date_created": "2021-09-27T16:30:11.837Z",
  "date_updated": "2021-10-28T16:04:21.648Z",
  "id": "6151f193ae97e82ccbf6f0a7"
}
```


## Using HTTPS

You may use an HTTPS URL for your webhook endpoint. In that case, Swell will validate your SSL certificate before sending event data. Your server must be correctly configured to support HTTPS.


## Receiving webhooks

Webhook event data is sent as JSON in a POST body. The payload represents a single event with attributes based on the event type. Events may contain additional data attributes that are useful in processing the event.

Your webhook might need to fetch the associated record using `data.id` before performing a relevant action.

If you need to verify that a webhook was sent from Swell's servers, you can check that it originates from one of the following IP addresses:

- `52.52.111.237`
- `54.219.85.17`
- `54.241.235.166`

In addition, you should allow traffic from the following IP ranges (CIDR notation):

- `216.218.185.0/27`
- `216.218.244.192/27`
- `74.80.234.0/24`

### Example response

```json
{
  "id": "58991ed385c95b9e2e0aa433",
  "date_created": "2019-02-07T01:11:47.219Z",
  "model": "subscriptions",
  "type": "subscription.paid",
  "data": {
    "id": "58991ed285c95b9e2e0aa42c",
    "payment_id": "5ca3806f0e41a74b7138d085"
  }
}
```


## Responding to webhooks

Your endpoint must respond to successful requests with a `2xx` HTTP status code. Response codes outside this range will indicate that you were not able to receive the webhook event.

Any other information returned by your script is ignored. Real-time order webhooks are an exception: a webhook configured for the `taxes` or `shipping` event reads the response body and merges it into the cart or order being processed. See [Functions and webhooks](https://developers.swell.is/guides/core-concepts/functions-and-webhooks) for the response format.

If a webhook is not acknowledged successfully, Swell retries it after 1 minute and then with an exponential back-off, up to 10 attempts a day. After every 10th failed attempt, the next retry is 12 hours later. The store's admins receive a warning email after every 10 failed attempts, at most once a day. If the endpoint keeps failing for 4 days without a successful delivery, the webhook is disabled until it is re-enabled, and the admins are notified. Re-enabling the webhook retries its pending events.

To stop retries for an event, respond with status `410`, or with a non-2xx response whose JSON body includes `"retry": false`.

Unless otherwise specified, webhook requests have a timeout of 10 seconds. In cases where webhook handlers are long-running or resource-intensive, we recommend implementing a messaging queue to handle incoming webhook requests asynchronously.

