# Webhooks

Endpoints that are notified as soon as certain events happen in Bookingmood. See [our documentation](/docs/integrations/webhooks) for how webhooks work

Endpoint: `https://api.bookingmood.com/v1/webhooks`, supporting `GET`, `POST`, `DELETE`, `PATCH`. Authenticate with the header `Authorization: Bearer YOUR_API_KEY` (see [authentication](https://www.bookingmood.com/hr-HR/api-reference/authentication.md)).

## The webhook object

| Attribute | Type | Description |
| --- | --- | --- |
| `id` | `uuid` | Unique identifier. |
| `organization_id` | `uuid` | Identifier of the organization this webhook is defined in. References [`organizations.id`](https://www.bookingmood.com/hr-HR/api-reference/organizations.md). |
| `created_at` | `timestamp with time zone` | Creation timestamp. Read-only: set by the database. |
| `updated_at` | `timestamp with time zone` | Last modification timestamp. Read-only: set by the database. |
| `description` | `text` | Description of the webhook. |
| `endpoint` | `text` | URL notifications are sent to. |
| `events` | `Array<WebhookEvent>` | Events the webhook is subscribed to. See [the complete list](/docs/integrations/webhooks#event-types). |
| `signing_secret` | `text` | Secret used to sign notifications, so their validity can be verified. |
| `source` | `text` | Where the webhook was registered: in the admin, through the API, or by an external tool such as Zapier. |

```json
{
  "id": "00000000-0000-0000-0000-000000000000",
  "organization_id": "00000000-0000-0000-0000-000000000000",
  "created_at": "2026-10-30T23:37:06.667Z",
  "updated_at": "2026-10-30T23:37:06.667Z",
  "description": "A short description.",
  "endpoint": "",
  "events": [
    "bookings.created"
  ],
  "signing_secret": "md5((random())::text)",
  "source": ""
}
```

### Types

```typescript
type WebhookEvent = 
  | "bookings.created"
  | "bookings.updated"
  | "calendar_events.created"
  | "calendar_events.updated"
  | "calendar_events.confirmed"
  | "calendar_events.cancelled"
  | "contacts.created"
  | "contacts.updated"
  | "invoices.created"
  | "invoices.updated"
  | "payments.created"
  | "payments.updated"
  | "payments.paid"
  | "tasks.created"
  | "tasks.updated"
  | "tasks.completed"
  | "members.created"
  | "members.updated"
  | "products.created"
  | "products.updated"
  | "sites.created"
  | "sites.updated"
  | "widgets.created"
  | "widgets.updated";
```

### Related resources

Embed related resources with the [`select` parameter](https://www.bookingmood.com/hr-HR/api-reference/selecting.md), e.g. `select=*,organizations(*)`. Resources related through more than one column need the column as a hint, like `table!column(*)`.

| Embed | Type | Description |
| --- | --- | --- |
| `organizations(*)` | `object \| null` | The [organization](https://www.bookingmood.com/hr-HR/api-reference/organizations.md) referenced by `organization_id`. |
| `webhook_notifications(*)` | `array` | The [webhook notifications](https://www.bookingmood.com/hr-HR/api-reference/webhook_notifications.md) referencing this webhook through `webhook_notifications.webhook_id`. |

## List webhooks

`GET /v1/webhooks`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/hr-HR/api-reference/filtering.md)). Choose columns and embed related resources with `select` (see [selecting](https://www.bookingmood.com/hr-HR/api-reference/selecting.md)), and sort and paginate with `order`, `limit` and `offset` (see [sorting and pagination](https://www.bookingmood.com/hr-HR/api-reference/sorting-pagination.md)).

```bash
curl -X GET "https://api.bookingmood.com/v1/webhooks?select=*&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: A list of webhooks with the selected columns. `206` when the list is a partial range.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.

## Create webhooks

`POST /v1/webhooks`

Insert one webhook or an array of webhooks. The body is a `Partial` webhook object, so columns with a default can be left out. Read-only attributes can't be written.

```bash
curl -X POST "https://api.bookingmood.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "00000000-0000-0000-0000-000000000000",
    "description": "A short description.",
    "endpoint": "",
    "events": [
      "bookings.created"
    ],
    "signing_secret": "md5((random())::text)",
    "source": ""
  }'
```

Responses:

- `201`: The newly created webhooks with the selected columns.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

## Delete webhooks

`DELETE /v1/webhooks`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/hr-HR/api-reference/filtering.md)). Without filters, this request deletes all webhooks you have access to. Always filter on at least one column, e.g. `id=eq.{id}`.

```bash
curl -X DELETE "https://api.bookingmood.com/v1/webhooks?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: The deleted webhooks with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.

## Update webhooks

`PATCH /v1/webhooks`

Filter on any attribute with `column=operator.value` (see [filtering](https://www.bookingmood.com/hr-HR/api-reference/filtering.md)). Without filters, this request updates all webhooks you have access to. Always filter on at least one column, e.g. `id=eq.{id}`. The body holds the attributes to change.

```bash
curl -X PATCH "https://api.bookingmood.com/v1/webhooks?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "A short description."
  }'
```

Responses:

- `200`: The updated webhooks with the selected columns. `204` without a body when sending the header `Prefer: return=minimal`.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key has no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.

Errors have a JSON body with a `code`, `message`, `details` and `hint`. See the [introduction](https://www.bookingmood.com/hr-HR/api-reference.md) for more on errors. The full API is described by the OpenAPI spec at https://api.bookingmood.com/v1/openapi.json.
