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

# Manage account webhooks

> Add, list, update, rotate and remove a managed account's webhook endpoints.

These are the account's ordinary webhooks, the same endpoints `/api/webhooks` manages, with the
same deliveries and the same `X-Webhook-Signature` HMAC. The signing `secret` is returned only when
it is created or rotated (and on an exact idempotent replay of that response); listings never
include it.

Because the account was provisioned through the partner API, every event delivered to these
endpoints carries `data.account`: the account's SpitShake `id` and your `external_id` for it, so
one endpoint can serve all of your accounts and pick the signing secret before parsing anything
else. Accounts not provisioned by a partner get no `account` key. See
[Webhooks](/guides/webhooks).

```bash theme={null}
curl -X POST https://spitshake.io/api/partner/v1/accounts/412/webhooks \
  -H "Authorization: Bearer $SPITSHAKE_PARTNER_KEY" \
  -H "Idempotency-Key: firm-8675309-webhook" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://platform.example/webhooks/spitshake", "events": ["form.completed", "submission.completed"] }'
```

```json 201 theme={null}
{
  "id": 77,
  "url": "https://platform.example/webhooks/spitshake",
  "events": ["form.completed", "submission.completed"],
  "enabled": true,
  "created_at": "2026-10-16T12:00:00Z",
  "updated_at": "2026-10-16T12:00:00Z",
  "secret": "4c1f0e9a2b...",
  "account": { "id": 412, "external_id": "firm-8675309" }
}
```

| Request | Effect |
| - | - |
| `GET /accounts/{id}/webhooks` | The account's webhooks, without secrets. |
| `POST /accounts/{id}/webhooks` | Add one: `url` (http(s), resolving to a public address) and a non-empty `events` list of events SpitShake sends; optional `enabled`. The plan must include webhooks. |
| `PUT /accounts/{id}/webhooks/{webhook_id}` | Change `url`, `events` and/or `enabled` (`PATCH` also works). |
| `DELETE /accounts/{id}/webhooks/{webhook_id}` | Remove it. Allowed on an archived account. |
| `POST /accounts/{id}/webhooks/{webhook_id}/rotate_secret` | Issue a new secret, returned once. The old one stops signing deliveries immediately. |

Each change is audited (`partner.webhook_created`, `partner.webhook_updated`,
`partner.webhook_deleted`, `partner.webhook_secret_rotated`). A webhook can also be created at
[provisioning](/api-reference/partner/provisioning#optional-provisioning-inputs).

| Status | Meaning |
| - | - |
| `404` | The account is not owned by this partner, or the webhook is not in that account. |
| `409` | The account is archived. |
| `422` | Invalid or blocked URL, unknown events, nothing to update, or a plan without webhooks. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.