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

# Remove Webhook

> Hard-delete a webhook (history retained)

Remove a webhook from a store. This is a **hard delete** — the row is removed from `store.store_webhooks` immediately, with no soft-delete flag. Historical `webhook_deliveries` records are retained for audit (the `storeWebhookId` foreign key is set to `null`).

```
POST /v1/actions/store/remove-webhook
```

**Authentication:** API Key (owner or admin role required)

## Request Body

| Field | Type   | Required | Description  |
| ----- | ------ | -------- | ------------ |
| `id`  | string | Yes      | Webhook UUID |

## Example Request

<CodeGroup>
  ```typescript SDK theme={"system"}
  import { WaffoPancake } from "@waffo/pancake-ts";

  const client = new WaffoPancake({
    merchantId: process.env.WAFFO_MERCHANT_ID!,
    privateKey: process.env.WAFFO_PRIVATE_KEY!,
  });

  const { webhook } = await client.webhooks.remove({
    id: "11111111-2222-3333-4444-555555555555",
  });
  // webhook contains a snapshot of the row before deletion
  ```

  ```bash cURL theme={"system"}
  curl -X POST https://api.waffo.com/v1/actions/store/remove-webhook \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $WAFFO_MERCHANT_ID" \
    -H "X-Signature: ..." \
    -d '{ "id": "11111111-2222-3333-4444-555555555555" }'
  ```
</CodeGroup>

## Success Response (200)

Returns the webhook entity as it existed immediately before deletion (so the caller can confirm what was removed). Same shape as [`add-webhook`](/api-reference/endpoints/webhooks/add-webhook#success-response-200).

## Response Fields

| Field       | Type           | Description                                          |
| ----------- | -------------- | ---------------------------------------------------- |
| `id`        | string         | Webhook UUID                                         |
| `storeId`   | string         | Owning store UUID                                    |
| `channel`   | string         | Webhook channel                                      |
| `url`       | string         | Target webhook URL                                   |
| `events`    | string\[]      | Subscribed event types                               |
| `testMode`  | boolean        | `true` for test transactions, `false` for production |
| `secret`    | string \| null | Channel-specific credential, `null` if unset         |
| `createdAt` | string         | Creation timestamp (ISO 8601)                        |
| `updatedAt` | string         | Last update timestamp (ISO 8601)                     |

## Errors

> **Retry policy:** Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).

| Status | `errors[0].message`                                | What it means                                                            | Recommended handling                                                     |
| ------ | -------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| 400    | `Missing required field: id`                       | `id` was not provided                                                    | Fix the request body, resubmit                                           |
| 400    | `id must be a valid UUID`                          | `id` is not a valid UUID                                                 | Fix the `id`, resubmit                                                   |
| 403    | `Not authorized to manage webhooks for this store` | The caller's merchant role on the owning store is not `owner` or `admin` | Switch to an API Key whose merchant has the required role                |
| 404    | `Webhook not found`                                | No webhook matches the supplied `id` (or already removed)                | The webhook is already gone — treat as success and reconcile local state |
| 500    | `Internal server error`                            | Unexpected server-side failure                                           | Retry with exponential backoff (start 5s, max 3 attempts)                |
