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

# Configure Webhooks in Pilot Status — API and Dashboard

> Register and manage webhook URLs via the Pilot Status API or dashboard. Subscribe to specific events or receive all events on a single endpoint.

# Configure webhooks

Manage the full webhook lifecycle via the public API — or use the dashboard **Webhooks** page (`/webhooks`). A webhook is configured **per number**; once configured, events are delivered automatically (no API-key linking is required).

For payloads and the full event list, see the [event reference](/api/webhooks/events).

## Endpoints

| Method   | Endpoint                 | Description                                              |
| -------- | ------------------------ | -------------------------------------------------------- |
| `GET`    | `/v1/webhooks`           | List the webhooks visible to the key's scope.            |
| `POST`   | `/v1/webhooks`           | Create a webhook subscribed to **one** number.           |
| `GET`    | `/v1/webhooks/{id}`      | Fetch one webhook.                                       |
| `PATCH`  | `/v1/webhooks/{id}`      | Update `name`, `url`, `active`, `events`.                |
| `DELETE` | `/v1/webhooks/{id}`      | Permanently delete the webhook.                          |
| `GET`    | `/v1/webhooks/{id}/logs` | Recent delivery attempts (`limit` 1–50, `event` filter). |

## Number scoping

A webhook belongs to a single WhatsApp number.

* With a **number-scoped** key the number comes from the key itself; a `whatsappNumberId` in the body must match it (else **400 `NUMBER_MISMATCH`**).
* With a **tenant-scoped** key, pass the target number via the `whatsappNumberId` body field or the `x-whatsapp-number-id` header — omitting both returns **400 `NUMBER_REQUIRED`**; a number outside your tenant returns **404 `NUMBER_NOT_FOUND`**.
* `GET /v1/webhooks` lists only the webhooks visible to the key's scope (a number-scoped key sees only its own number's webhooks). A webhook outside the key's scope returns **404 `WEBHOOK_NOT_FOUND`**.

## Examples

<CodeGroup>
  ```bash Create theme={null}
  curl -X POST "https://pilotstatus.com.br/v1/webhooks" \
    -H "x-api-key: ps_your_token_here" \
    -H "Content-Type: application/json" \
    -d '{ "url": "https://example.com/hooks/in", "name": "My hook", "events": ["message.received", "message.sent"] }'
  ```

  ```bash Pause (keep it, stop delivering) theme={null}
  curl -X PATCH "https://pilotstatus.com.br/v1/webhooks/wh_abc" \
    -H "x-api-key: ps_your_token_here" \
    -H "Content-Type: application/json" \
    -d '{ "active": false }'
  ```

  ```bash Delete theme={null}
  curl -X DELETE "https://pilotstatus.com.br/v1/webhooks/wh_abc" \
    -H "x-api-key: ps_your_token_here"
  ```

  ```bash Delivery logs theme={null}
  curl "https://pilotstatus.com.br/v1/webhooks/wh_abc/logs?limit=20&event=message.received" \
    -H "x-api-key: ps_your_token_here"
  ```
</CodeGroup>

## Event gating

<Warning>
  An **empty (or omitted) `events` list dispatches NOTHING** — there is no implicit "subscribe to all". Use `"*"` to subscribe to every event.
</Warning>

* On `PATCH`, **`events` replaces the whole subscription list** (it is not a merge).
* Events the number's provider cannot emit are silently dropped.

## Rules and errors

| Rule                                                                                              | Error                                  |
| ------------------------------------------------------------------------------------------------- | -------------------------------------- |
| Create without a number (tenant-scoped key, no `whatsappNumberId` / header)                       | **400 `NUMBER_REQUIRED`**              |
| `whatsappNumberId` differs from a number-scoped key's number                                      | **400 `NUMBER_MISMATCH`**              |
| `whatsappNumberId` on `PATCH` (the number cannot be changed after creation — delete and recreate) | **400 `NUMBER_RESCOPE_NOT_SUPPORTED`** |
| Number outside your tenant                                                                        | **404 `NUMBER_NOT_FOUND`**             |
| Webhook not visible to the key's scope                                                            | **404 `WEBHOOK_NOT_FOUND`**            |

<Note>
  **The signing `secret` is never returned** by any of these endpoints.
</Note>

## Dashboard

Everything above is also available in the dashboard at **`/webhooks`**: create/edit webhooks per number, pick events, pause/resume, and inspect delivery logs. The New/Edit Webhook UI includes the notice that `message.read` only fires when the recipient has WhatsApp read receipts enabled.
