# Webhooks

Webhook endpoints receive a signed event when a referral is claimed, flagged or updated. These routes manage the endpoints and read what was delivered. [Receive referral webhooks](https://warplink.app/docs/guides/webhooks) covers the payloads, the signature check, retries and the limits. The MCP server has the same operations as `list_webhook_endpoints`, `create_webhook_endpoint`, `update_webhook_endpoint`, `delete_webhook_endpoint`, `rotate_webhook_secret`, `send_test_webhook` and `list_webhook_deliveries`.

## Authentication and Permissions

Reading needs an API key with the `referrals:read` scope. Every change needs `referrals:write`, and the key's creator must be an owner or admin. The masked signing secret appears in reads only when the creator is an owner or admin. SDK keys are refused with `403 SDK_KEY_ROUTE_FORBIDDEN`.

## List Endpoints

GET /apps/{id}/webhook-endpoints: List an app's webhook endpoints

The response includes the plan's endpoint limit per app: 1 on Free and 5 on paid plans.

## Add an Endpoint

POST /apps/{id}/webhook-endpoints: Add a webhook endpoint

The address must be a public `https` address. The full signing secret, which starts with `whsec_`, is in `secret` in this response only. Later reads show a masked form.

## Update an Endpoint

PATCH /webhook-endpoints/{id}: Update a webhook endpoint

Change the address, turn the endpoint on or off with `status`, or set `send_flagged` to `false` to stop receiving `referral.flagged` (it is `true` by default). After a plan change that allows fewer endpoints, `keep_active` chooses the endpoint that stays active.

## Delete an Endpoint

DELETE /webhook-endpoints/{id}: Delete a webhook endpoint

## Rotate the Secret

POST /webhook-endpoints/{id}/rotate: Rotate a webhook signing secret

The new secret is in `secret` once. The old one keeps signing beside it until `previous_secret_expires_at`, 24 hours later, so a receiver can switch without a gap.

## Send a Test Event

POST /webhook-endpoints/{id}/test: Send a test event

One signed `webhook.test` event goes to the saved address, and the response shows what your server answered. It is sent once and never retried.

## List Deliveries

GET /webhook-endpoints/{id}/deliveries: List an endpoint's deliveries

The newest 100 events of the endpoint, each with every attempt. A delivery's `id` is the value to pass to the resend route.

## Resend an Event

POST /webhook-events/{id}/resend: Resend a webhook event

A delivered or failed event can be sent again for 7 days after its last attempt, with the same event id and payload. An event still in flight answers `409 CONFLICT`, and an older one answers `410 GONE`.
