> ## Documentation index
> Fetch the complete documentation index at: https://docs.htspilot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook endpoints

> Register, change, test and delete webhooks through the API, and read the deliveries of a webhook.

These operations manage the webhooks themselves. What a webhook sends, how to verify it and how it retries is in
[Webhooks](/webhooks.md). All of them need the `admin` role; creating, changing and testing also need the plan
feature `feature.webhooks`.

## The webhook object

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | The id of the webhook |
| `url` | string | Where deliveries are sent |
| `events` | array | The event names it receives. Empty means every event |
| `active` | boolean | A paused webhook receives nothing |
| `created_at` | string | ISO 8601, UTC |
| `last_status` | integer or null | The HTTP status your endpoint gave to the latest delivery |
| `last_error` | string or null | Why the latest delivery failed |
| `last_delivery_at` | string or null | When the latest delivery ended |
| `secret` | string | The key of the signature. Only in the answer of `POST /api/webhooks` |

## The delivery object

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | integer | The delivery id, as sent in `X-HTS-Delivery` |
| `event` | string | The event name |
| `status_code` | integer or null | The HTTP status of the last attempt. `null` when no answer was received |
| `error` | string or null | Why it failed: the start of your endpoint's answer, or a general reason |
| `attempts` | integer | How many attempts were made |
| `created_at` | string | ISO 8601, UTC |

## Register a webhook

`POST /api/webhooks`

**Changes data in your account when executed.** The answer contains `secret`, the key of the `X-HTS-Signature` header. It is shown only here. Leave `events` empty to receive every event. The URL must be `https` and resolve to a public address. Needs the admin role.

**Request body** (`application/json`)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | Yes | Up to 2083 characters |
| `events` | string[] | No | Empty = all events |

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl -X POST "https://htspilot.com/api/webhooks" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://erp.example.com/hooks/hts-pilot",
  "events": []
}'
```

**Example response** `200`

```json
{
  "id": "4eaf866e6ff24b4b895c222fac1d71ed",
  "url": "https://erp.example.com/hooks/hts-pilot",
  "events": [],
  "active": true,
  "created_at": "2026-10-04T20:23:38.000075+00:00",
  "last_status": null,
  "last_error": null,
  "last_delivery_at": null,
  "secret": "0123456789abcdef0123456789abcdef0123456789abcdef"
}
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/createWebhook

## List webhooks

`GET /api/webhooks`

Needs the admin role.

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl "https://htspilot.com/api/webhooks" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME"
```

**Example response** `200`

```json
[
  {
    "id": "4eaf866e6ff24b4b895c222fac1d71ed",
    "url": "https://erp.example.com/hooks/hts-pilot",
    "events": [],
    "active": true,
    "created_at": "2026-10-04T20:23:38.000075",
    "last_status": 200,
    "last_error": null,
    "last_delivery_at": "2026-10-04T20:23:39.402651"
  }
]
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/listWebhooks

## Change or pause a webhook

`PATCH /api/webhooks/{hook_id}`

**Changes data in your account when executed.** Needs the admin role.

**Path parameters**

| Name | Type | Description |
| --- | --- | --- |
| `hook_id` | string | - |

**Request body** (`application/json`)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string or null | No | Up to 2083 characters |
| `events` | string[] or null | No | - |
| `active` | boolean or null | No | - |

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl -X PATCH "https://htspilot.com/api/webhooks/4eaf866e6ff24b4b895c222fac1d71ed" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
  "active": false
}'
```

**Example response** `200`

```json
{
  "id": "4eaf866e6ff24b4b895c222fac1d71ed",
  "url": "https://erp.example.com/hooks/hts-pilot",
  "events": [],
  "active": false,
  "created_at": "2026-10-04T20:23:38.000075",
  "last_status": 200,
  "last_error": null,
  "last_delivery_at": "2026-10-04T20:23:39.402651"
}
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/updateWebhook

Send only what changes. A new `url` is checked like a new webhook. The secret cannot be changed here; to rotate it,
delete the webhook and register it again.

## Delete a webhook

`DELETE /api/webhooks/{hook_id}`

**Deletes for real when executed, and cannot be undone.** Needs the admin role.

**Path parameters**

| Name | Type | Description |
| --- | --- | --- |
| `hook_id` | string | - |

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl -X DELETE "https://htspilot.com/api/webhooks/4eaf866e6ff24b4b895c222fac1d71ed" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME"
```

**Example response** `200`

```json
{
  "ok": true
}
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/deleteWebhook

## Send a test event

`POST /api/webhooks/{hook_id}/test`

**Changes data in your account when executed.** Sends the event `ping` now, with the same body shape, headers and signature as a real event, and answers with the result. Needs the admin role.

**Path parameters**

| Name | Type | Description |
| --- | --- | --- |
| `hook_id` | string | - |

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl -X POST "https://htspilot.com/api/webhooks/4eaf866e6ff24b4b895c222fac1d71ed/test" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME"
```

**Example response** `200`

```json
{
  "ok": true,
  "id": "4eaf866e6ff24b4b895c222fac1d71ed",
  "url": "https://erp.example.com/hooks/hts-pilot",
  "events": [],
  "active": true,
  "created_at": "2026-10-04T20:23:38.000075",
  "last_status": 200,
  "last_error": null,
  "last_delivery_at": "2026-10-04T20:23:39.402651"
}
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/testWebhook

`ok` is `true` when your endpoint answered `2xx`.

## List deliveries

`GET /api/webhooks/{hook_id}/deliveries`

Needs the admin role.

**Path parameters**

| Name | Type | Description |
| --- | --- | --- |
| `hook_id` | string | - |

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl "https://htspilot.com/api/webhooks/4eaf866e6ff24b4b895c222fac1d71ed/deliveries" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME"
```

**Example response** `200` (long lists and texts are cut)

```json
[
  {
    "id": 7,
    "event": "ping",
    "status_code": 200,
    "error": null,
    "attempts": 1,
    "created_at": "2026-10-04T20:23:39.401145"
  },
  {
    "id": 6,
    "event": "lookup.completed",
    "status_code": 200,
    "error": null,
    "attempts": 1,
    "created_at": "2026-10-04T20:23:39.174679"
  }
]
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/listWebhookDeliveries

## List event names

`GET /api/webhooks/events`

Needs the admin role.

**Returns** `200` with a JSON object, as in the example.

**Errors**: `401` No valid API key was sent; `403` The role of the key, or the plan of the account, does not allow this call; `422` The request is not valid; `500` An unexpected failure.

**Example request**

```bash
curl "https://htspilot.com/api/webhooks/events" \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME"
```

**Example response** `200`

```json
{
  "lookup.completed": "A lookup finished",
  "lookup.decided": "A reviewer approved / overrode / rejected a code",
  "batch.completed": "A batch file finished processing",
  "tariff.changed": "A new tariff version and code changes were detected",
  "sku.alert": "A SKU is affected by a tariff change"
}
```

Try it: https://docs.htspilot.com/explorer/#/Webhooks/listWebhookEvents
