---
title: "Manage subscriptions"
description: "Create, scope, test, pause, inspect, retry, and delete webhook subscriptions through the Server API."
---

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

# Manage subscriptions

Use the Webhooks API when subscription setup must be repeatable across customer
provisioning, environments, or deployment pipelines. One-off integrations can
use the dashboard over the same underlying resources.

## Authentication

Secret keys have organization authority. Dashboard reads allow signed-in
members; writes require an admin. Event-scoped manage tokens cannot access
webhook configuration.

| Method and path | Purpose |
|---|---|
| `GET /v1/webhooks` | List subscriptions and seven-day uptime |
| `POST /v1/webhooks` | Create; signing secret returned once |
| `PATCH /v1/webhooks/:id` | Update URL, events, disabled state, or scope |
| `DELETE /v1/webhooks/:id` | Delete subscription |
| `POST /v1/webhooks/:id/test` | Send an inline signed test |
| `GET /v1/webhooks/:id/deliveries` | Inspect delivery attempts |
| `POST /v1/webhooks/:id/deliveries/:deliveryId/retry` | Redeliver one stored payload |

## Create a subscription

**POST /v1/webhooks** — Authentication: Secret key or admin dashboard session

```bash
curl -sX POST "https://api.seatlayer.io/v1/webhooks" \
  -H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/seatlayer",
    "events": [
      "seat.booked",
      "seat.released",
      "event.soldout"
    ]
  }'
```

The URL must use HTTPS and `events` must be a non-empty set of known names.

```json
{
  "sub": {
    "id": "sub_8a2f",
    "url": "https://example.com/webhooks/seatlayer",
    "events": ["seat.booked", "seat.released", "event.soldout"],
    "disabled": false,
    "lastStatus": null,
    "lastAt": null,
    "createdAt": 1761436800000,
    "mode": "live",
    "environment": "prod",
    "uptime7d": null
  },
  "secret": "whsec_1f8c"
}
```

> **Store the secret now**
>
> `secret` is returned only at creation and is never included in list or patch
> responses. If it is lost, create a replacement subscription, deploy the new
> receiver secret, and delete the old subscription.

## Scope delivery

Subscriptions can filter by `mode` and `environment`.

- A secret-key create inherits that key's mode and environment.
- A dashboard-session create defaults to live mode and accepts an optional
  environment.
- A `null` field is a wildcard after patching.

```json
{
  "url": "https://staging.example.com/webhooks/seatlayer",
  "events": ["seat.booked"],
  "mode": "test",
  "environment": "staging"
}
```

A secret key cannot use request fields to escape its own routing scope.

## Update or pause

**PATCH /v1/webhooks/:id** — Authentication: Secret key or admin dashboard session

Send only changed fields. `events` replaces the full set.

```json
{
  "events": [
    "seat.booked",
    "seat.released",
    "hold.created",
    "hold.expired"
  ],
  "disabled": true
}
```

Pause with `disabled: true` while repairing a receiver. Existing delivery
history remains available. Send `mode: null` or `environment: null` to restore
the wildcard for that axis.

## Send a test

**POST /v1/webhooks/:id/test** — Authentication: Secret key or admin dashboard session

With no body, SeatLayer sends a signed `ping` and waits up to five seconds:

```json
{
  "status": 200,
  "ok": true,
  "event": "ping",
  "responseBody": null
}
```

You can also request a representative payload:

```json
{
  "event": "seat.booked"
}
```

Representative tests are available for seat booked/released/blocked, hold
created/expired, and event created/sold-out branches. Exercise
`hold.extended` using a test-mode event. Test requests carry `test: true`,
are delivered inline, and are not written to the normal delivery ledger.

## Inspect deliveries

**GET /v1/webhooks/:id/deliveries** — Authentication: Secret key or dashboard session

Query parameters:

| Parameter | Behavior |
|---|---|
| `limit` | Default 20; maximum 50 |
| `status` | `ok`, `failed`, or omit for both |
| `before` | Timestamp cursor from `nextBefore` |

Cursor pages can overlap at the timestamp boundary; de-duplicate by delivery
`id`. Each record includes status, attempt count, retry state, occurrence id,
stored payload, and—on failure—a truncated receiver response or transport error.

## Retry one delivery

**POST /v1/webhooks/:id/deliveries/:deliveryId/retry** — Authentication: Secret key or admin dashboard session

This sends the stored payload to that subscription only. It keeps the original
`occurrenceId`, creates a new delivery attempt and signature, and does not
restart the automatic retry chain.

## Delete

**DELETE /v1/webhooks/:id** — Authentication: Secret key or admin dashboard session

Deletion removes the subscription. If temporary downtime is expected, prefer
`disabled: true` so configuration and history remain available.

Continue to [event payloads](/webhooks/events),
[delivery and retries](/webhooks/delivery-and-retries), and
[signature verification](/webhooks/signatures).

Source: https://docs.seatlayer.io/webhooks/manage-subscriptions/index.mdx
