# Webhook endpoints API

> Endpoints that receive signed events.

Verify Checkbox-Signature with the endpoint secret (HMAC-SHA256 of "{t}.{raw body}", 5-minute tolerance). Failed deliveries are retried with backoff for about three days.

| Operation | Endpoint |
|---|---|
| [List webhook endpoints](#listWebhookEndpoints) | `GET /v1/webhook_endpoints` |
| [Create a webhook endpoint](#createWebhookEndpoint) | `POST /v1/webhook_endpoints` |
| [Retrieve a webhook endpoint](#retrieveWebhookEndpoint) | `GET /v1/webhook_endpoints/{webhook_endpoint}` |
| [Update a webhook endpoint](#updateWebhookEndpoint) | `POST /v1/webhook_endpoints/{webhook_endpoint}` |
| [Delete a webhook endpoint](#deleteWebhookEndpoint) | `DELETE /v1/webhook_endpoints/{webhook_endpoint}` |
| [Roll a webhook signing secret](#rollWebhookEndpointSecret) | `POST /v1/webhook_endpoints/{webhook_endpoint}/roll_secret` |

## The WebhookEndpoint object

Where Checkbox sends signed event notifications (Checkbox-Signature: t=…,v1=…).

| Field | Type | Description |
|---|---|---|
| `id` | string | Unique identifier of the webhook endpoint (we_…). |
| `object` | enum | String representing the object's type. Always "webhook_endpoint". |
| `livemode` | boolean | true for live-mode objects, false for test mode (ck_test_ keys act on an isolated sandbox). |
| `url` | string | HTTPS URL Checkbox POSTs events to. |
| `description` | string \| null | Your description. |
| `enabled_events` | array of strings | Event types sent to this endpoint ("*" = all). |
| `status` | enum | Disabled endpoints receive nothing. One of `enabled`, `disabled`. |
| `api_version` | string | API version events are rendered with. |
| `metadata` | object | Up to 20 key/value string pairs you can attach to the object. |
| `secret` | string | Signing secret (whsec_…). Only returned when the endpoint is created or the secret is rolled; store it. |
| `created` | integer | When the endpoint was created. Unix timestamp in seconds. |

## List webhook endpoints {#listWebhookEndpoints}

`GET /v1/webhook_endpoints`

Webhook endpoints of this mode, newest first.

**Scope** `webhook_endpoints:read` · **Operation** `listWebhookEndpoints`

SDK: `checkbox.webhookEndpoints.list()` (Node) · `checkbox.webhook_endpoints.list()` (Python). MCP / agents: operation `listWebhookEndpoints`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `limit` | query | integer | Number of objects to return, 1-100 (default 10). |
| `starting_after` | query | string | Cursor: an object id; returns the objects after it (older). |
| `ending_before` | query | string | Cursor: an object id; returns the objects before it (newer). |

#### Returns

Returns a list (`{ object: "list", data, has_more, url }`) of [WebhookEndpoint](https://checkbox.site/docs/api/webhook-endpoints#the-webhookendpoint-object) objects.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl -G https://app.checkbox.site/v1/webhook_endpoints \
  -u "$CHECKBOX_SECRET_KEY:" \
  -d limit=3
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoints = await checkbox.webhookEndpoints.list({ limit: 3 });
console.log(webhookEndpoints.data);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoints = checkbox.webhook_endpoints.list(limit=3)
print(webhook_endpoints.data)
```

```json title="Response"
{
  "object": "list",
  "data": [
    {
      "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "object": "webhook_endpoint",
      "livemode": false,
      "url": "https://acme.example/webhooks/checkbox",
      "description": "Production listener",
      "enabled_events": [
        "*"
      ],
      "status": "enabled",
      "api_version": "2026-10-30",
      "metadata": {
        "order_ref": "A-1001"
      },
      "secret": "whsec_6Jf…",
      "created": 1793318400
    }
  ],
  "has_more": false,
  "url": "/v1/sites"
}
```

## Create a webhook endpoint {#createWebhookEndpoint}

`POST /v1/webhook_endpoints`

Registers an HTTPS endpoint for the given event types. The response contains the signing `secret` (only now). Respond 2xx quickly; do slow work asynchronously.

**Scope** `webhook_endpoints:write` · **Idempotent** (send `Idempotency-Key`) · **Operation** `createWebhookEndpoint`

SDK: `checkbox.webhookEndpoints.create()` (Node) · `checkbox.webhook_endpoints.create()` (Python). MCP / agents: operation `createWebhookEndpoint`.

#### Body

| Field | Type | Description |
|---|---|---|
| `url` **required** | string | HTTPS URL. |
| `enabled_events` **required** | array of strings | Event types to send, or ["*"] for all: site.score_changed, site.insurable_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, consent.created, test_run.completed, test_run.failed, plan.updated, site.compliant, task.verified. |
| `description` | string | Description. |
| `metadata` | object | Up to 20 key/value string pairs you can attach to the object. |

#### Returns

Returns a [WebhookEndpoint](https://checkbox.site/docs/api/webhook-endpoints#the-webhookendpoint-object) object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/webhook_endpoints \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://acme.example/webhooks/checkbox",
  "enabled_events": [
    "finding.created",
    "site.insurable_changed"
  ]
}'
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoint = await checkbox.webhookEndpoints.create({
  url: 'https://acme.example/webhooks/checkbox',
  enabled_events: ['finding.created', 'site.insurable_changed'],
});
console.log(webhookEndpoint);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoint = checkbox.webhook_endpoints.create(
    url="https://acme.example/webhooks/checkbox",
    enabled_events=["finding.created", "site.insurable_changed"],
)
print(webhook_endpoint)
```

```json title="Response"
{
  "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://acme.example/webhooks/checkbox",
  "description": "Production listener",
  "enabled_events": [
    "*"
  ],
  "status": "enabled",
  "api_version": "2026-10-30",
  "metadata": {
    "order_ref": "A-1001"
  },
  "secret": "whsec_6Jf…",
  "created": 1793318400
}
```

## Retrieve a webhook endpoint {#retrieveWebhookEndpoint}

`GET /v1/webhook_endpoints/{webhook_endpoint}`

One webhook endpoint (without its secret).

**Scope** `webhook_endpoints:read` · **Operation** `retrieveWebhookEndpoint`

SDK: `checkbox.webhookEndpoints.retrieve()` (Node) · `checkbox.webhook_endpoints.retrieve()` (Python). MCP / agents: operation `retrieveWebhookEndpoint`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `webhook_endpoint` **required** | path | string | Unique identifier of the webhook endpoint (we_…). |

#### Returns

Returns a [WebhookEndpoint](https://checkbox.site/docs/api/webhook-endpoints#the-webhookendpoint-object) object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/webhook_endpoints/we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:"
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoint = await checkbox.webhookEndpoints.retrieve('we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b');
console.log(webhookEndpoint);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoint = checkbox.webhook_endpoints.retrieve("we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b")
print(webhook_endpoint)
```

```json title="Response"
{
  "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://acme.example/webhooks/checkbox",
  "description": "Production listener",
  "enabled_events": [
    "*"
  ],
  "status": "enabled",
  "api_version": "2026-10-30",
  "metadata": {
    "order_ref": "A-1001"
  },
  "secret": "whsec_6Jf…",
  "created": 1793318400
}
```

## Update a webhook endpoint {#updateWebhookEndpoint}

`POST /v1/webhook_endpoints/{webhook_endpoint}`

Changes the URL, event types, description, metadata, or disables / re-enables the endpoint.

**Scope** `webhook_endpoints:write` · **Idempotent** (send `Idempotency-Key`) · **Operation** `updateWebhookEndpoint`

SDK: `checkbox.webhookEndpoints.update()` (Node) · `checkbox.webhook_endpoints.update()` (Python). MCP / agents: operation `updateWebhookEndpoint`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `webhook_endpoint` **required** | path | string | Unique identifier of the webhook endpoint (we_…). |

#### Body

| Field | Type | Description |
|---|---|---|
| `url` | string | HTTPS URL. |
| `enabled_events` | array of strings | Event types to send, or ["*"] for all: site.score_changed, site.insurable_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, consent.created, test_run.completed, test_run.failed, plan.updated, site.compliant, task.verified. |
| `description` | string \| null | Description (null clears it). |
| `disabled` | boolean | true disables the endpoint, false enables it. |
| `metadata` | object | Up to 20 key/value string pairs you can attach to the object. |

#### Returns

Returns a [WebhookEndpoint](https://checkbox.site/docs/api/webhook-endpoints#the-webhookendpoint-object) object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/webhook_endpoints/we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled_events": [
    "finding.created",
    "site.insurable_changed"
  ]
}'
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoint = await checkbox.webhookEndpoints.update('we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b', {
  enabled_events: ['finding.created', 'site.insurable_changed'],
});
console.log(webhookEndpoint);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoint = checkbox.webhook_endpoints.update("we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b", enabled_events=["finding.created", "site.insurable_changed"])
print(webhook_endpoint)
```

```json title="Response"
{
  "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://acme.example/webhooks/checkbox",
  "description": "Production listener",
  "enabled_events": [
    "*"
  ],
  "status": "enabled",
  "api_version": "2026-10-30",
  "metadata": {
    "order_ref": "A-1001"
  },
  "secret": "whsec_6Jf…",
  "created": 1793318400
}
```

## Delete a webhook endpoint {#deleteWebhookEndpoint}

`DELETE /v1/webhook_endpoints/{webhook_endpoint}`

Deletes the endpoint; pending deliveries to it are dropped.

**Scope** `webhook_endpoints:write` · **Operation** `deleteWebhookEndpoint`

SDK: `checkbox.webhookEndpoints.del()` (Node) · `checkbox.webhook_endpoints.delete()` (Python). MCP / agents: operation `deleteWebhookEndpoint`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `webhook_endpoint` **required** | path | string | Unique identifier of the webhook endpoint (we_…). |

#### Returns

Returns a `DeletedWebhookEndpoint` object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/webhook_endpoints/we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:" \
  -X DELETE
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoint = await checkbox.webhookEndpoints.del('we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b');
console.log(webhookEndpoint);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoint = checkbox.webhook_endpoints.delete("we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b")
print(webhook_endpoint)
```

```json title="Response"
{
  "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "webhook_endpoint",
  "deleted": true
}
```

## Roll a webhook signing secret {#rollWebhookEndpointSecret}

`POST /v1/webhook_endpoints/{webhook_endpoint}/roll_secret`

Replaces the signing secret immediately and returns the new one (only now).

**Scope** `webhook_endpoints:write` · **Idempotent** (send `Idempotency-Key`) · **Operation** `rollWebhookEndpointSecret`

SDK: `checkbox.webhookEndpoints.rollSecret()` (Node) · `checkbox.webhook_endpoints.roll_secret()` (Python). MCP / agents: operation `rollWebhookEndpointSecret`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `webhook_endpoint` **required** | path | string | Unique identifier of the webhook endpoint (we_…). |

#### Returns

Returns a [WebhookEndpoint](https://checkbox.site/docs/api/webhook-endpoints#the-webhookendpoint-object) object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/webhook_endpoints/we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/roll_secret \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{}'
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const webhookEndpoint = await checkbox.webhookEndpoints.rollSecret('we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b');
console.log(webhookEndpoint);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

webhook_endpoint = checkbox.webhook_endpoints.roll_secret("we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b")
print(webhook_endpoint)
```

```json title="Response"
{
  "id": "we_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://acme.example/webhooks/checkbox",
  "description": "Production listener",
  "enabled_events": [
    "*"
  ],
  "status": "enabled",
  "api_version": "2026-10-30",
  "metadata": {
    "order_ref": "A-1001"
  },
  "secret": "whsec_6Jf…",
  "created": 1793318400
}
```
