# Webhook endpoints

> Create, update, pause and delete webhook endpoints, rotate their signing secrets, send test events and redeliveries, and read delivery attempts.

Last updated: 2026-09-17

Register the endpoints Fingerly sends [webhooks](https://docs.fingerly.io/docs/webhooks) to. Admin and developer management keys can do all of this. An organization can have up to 10 endpoints.

**Path parameter**

- `organization_id` (string, required): Your organization, from [Describe the key](https://docs.fingerly.io/reference/management/overview#describe-the-key). A path naming any other organization answers `404`.

## List endpoints

```http
GET /api/v1/management/organizations/{organization_id}/webhooks
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Response**

- `endpoints` (WebhookEndpoint[]): Every endpoint, newest first.
  - `id` (string): The endpoint's ID.
  - `url` (string): Where deliveries are sent.
  - `description` (string): Your description.
  - `environment` (string): `live` for production traffic, `test` for staging and development.
  - `events` (string[]): The event types the endpoint receives.
  - `status` (string): `active`, `paused` or `failing`.
  - `secret_last4` (string): The last four characters of the signing secret.
  - `previous_secret_expires_at` (string): During a rotation, when the previous secret stops signing.
  - `delivered_24h` (integer): Deliveries that succeeded in the last 24 hours.
  - `failed_24h` (integer): Deliveries that failed in the last 24 hours.
  - `last_delivery_at` (string): When the endpoint last received a delivery.
  - `created_at` (string): When the endpoint was created.

## Create an endpoint

```http
POST /api/v1/management/organizations/{organization_id}/webhooks
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Body**

- `url` (string, required): An `https://` URL that resolves to a public address. Redirects are not followed.
- `environment` (string, required): `live` or `test`.
- `events` (string[], required): Event types, such as `identification.completed`. `billing.status_changed` needs `live`.
- `description` (string, required): To tell endpoints apart. May be empty.

Answers `201` with `endpoint` and `secret`, the signing secret, shown once. A request past the limit of 10 endpoints answers `409` with `webhook_limit`.

## Update an endpoint

```http
PATCH /api/v1/management/organizations/{organization_id}/webhooks/{webhook_id}
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Body**

- `url` (string): A new URL.
- `description` (string): A new description.
- `environment` (string): `live` or `test`.
- `events` (string[]): The complete new list of event types.
- `paused` (boolean): `true` pauses the endpoint; `false` resumes it.

Send only the fields to change. Answers with the endpoint.

## Delete an endpoint

```http
DELETE /api/v1/management/organizations/{organization_id}/webhooks/{webhook_id}
```

Authentication: Management key (`x-api-key: fly_mk_…`)

Removes the endpoint and answers `204`. Deliveries stop at once.

## Rotate the signing secret

```http
POST /api/v1/management/organizations/{organization_id}/webhooks/{webhook_id}/rotate-secret
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Body**

- `previous_secret_valid_hours` (integer, default `24`): How long the previous secret keeps signing deliveries, from `0` to `168`.

Answers with `endpoint` and the new `secret`, shown once. See [rotate a secret](https://docs.fingerly.io/docs/webhooks#rotate-a-secret).

## Send a test event

```http
POST /api/v1/management/organizations/{organization_id}/webhooks/{webhook_id}/test
```

Authentication: Management key (`x-api-key: fly_mk_…`)

Queues one signed `webhook.test` delivery and answers `202` with its `event_id`. A test or redelivery already queued for the endpoint answers `409` with `webhook_busy`.

## Redeliver an event

```http
POST /api/v1/management/organizations/{organization_id}/webhooks/{webhook_id}/redeliver
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Body**

- `event_id` (string, required): The ID of an event this endpoint received in the last 30 days.

Queues one more delivery of the event, with the same `id`, and answers `202`.

## List delivery attempts

```http
GET /api/v1/management/organizations/{organization_id}/webhook-deliveries
```

Authentication: Management key (`x-api-key: fly_mk_…`)

**Query parameters**

- `environment` (string, default `'all'`): `live`, `test` or `all`.
- `limit` (integer, default `50`): Attempts per page.
- `cursor` (string): The `next_cursor` of the previous page.

**Response**

- `deliveries` (Delivery[]): Attempts from the last 30 days, newest first: `id`, `endpoint_id`, `endpoint_url`, `event_id`, `event`, `environment`, `status` (`delivered`, `retrying` or `failed`), `response_code`, `duration_ms`, `attempt`, `error` and `occurred_at`.
- `next_cursor` (string): Pass it as `cursor` for the next page. Omitted on the last page.

## Example request

```bash cURL
curl -X POST "https://us.api.fingerly.io/api/v1/management/organizations/01a0a7f2-3c18-7b40-8d2e-5f6a9b1c0d37/webhooks" \
  -H "x-api-key: $FINGERLY_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://risk.example.com/webhooks/fingerly",
    "description": "Risk review queue",
    "environment": "live",
    "events": [
      "identification.completed",
      "visitor.suspect"
    ]
  }'
```

## Example response

```json 201
{
  "endpoint": {
    "id": "01a0a860-2b7d-7c4e-9f13-8a5b6c7d8e9f",
    "url": "https://risk.example.com/webhooks/fingerly",
    "description": "Risk review queue",
    "environment": "live",
    "events": [
      "identification.completed",
      "visitor.suspect"
    ],
    "status": "active",
    "secret_last4": "a91F",
    "delivered_24h": 0,
    "failed_24h": 0,
    "created_at": "2026-09-16T09:31:55Z"
  },
  "secret": "whsec_…"
}
```

```json 409
{
  "error": {
    "code": "webhook_limit",
    "message": "an organization may have at most 10 webhook endpoints",
    "status": 409
  },
  "request_id": "01a0a84c-0f11-7a3e-9c2d-4b5e6f708192"
}
```
