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

# Webhooks

> Receive signed HTTP callbacks for account events.

Register a URL per account and receive a signed POST for every event.

## Configure

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X PUT https://api.onlyfanskit.dev/v1/accounts/$ID/webhook \
  -H "Authorization: Bearer $OFK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/onlyfanskit",
    "events": ["message", "subscribed", "tips"]
  }'
```

Omit `events` to receive everything. The response includes a `signingSecret`
— **store it on write**; it isn't returned again.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "webhook": {
    "url": "https://yourapp.com/hooks/onlyfanskit",
    "events": ["message", "subscribed", "tips"],
    "signingSecret": "whsec_...",
    "createdAt": "...",
    "updatedAt": "..."
  }
}
```

## Verify deliveries

Each delivery carries an `X-Webhook-Signature: sha256=<hmac>` header — an
HMAC-SHA256 of the raw body keyed by your signing secret. Verify it with the
SDK helper:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { WebhookHandler } from "onlyfanskit";

const handler = new WebhookHandler({ secret: process.env.WEBHOOK_SECRET! });

const event = handler.verifyAndParse({
  rawBody: req.body,                               // the raw string
  signatureHeader: req.headers["x-webhook-signature"] as string,
});
```

<Warning>
  Always verify the signature against the **raw** request body before trusting
  a payload. Reject anything that doesn't match.
</Warning>

## Test connectivity

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.onlyfanskit.dev/v1/accounts/$ID/webhook/test \
  -H "Authorization: Bearer $OFK_KEY"
```

Delivers a synthetic `test` event (signed identically to live events) and
returns whether your endpoint accepted it:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{ "delivered": true, "status": 200, "durationMs": 142, "responseSnippet": "ok" }
```

## Manage

| Operation     | Endpoint                              | Scope            |
| ------------- | ------------------------------------- | ---------------- |
| Get config    | `GET /v1/accounts/{id}/webhook`       | `webhooks:read`  |
| Set / replace | `PUT /v1/accounts/{id}/webhook`       | `webhooks:write` |
| Delete        | `DELETE /v1/accounts/{id}/webhook`    | `webhooks:write` |
| Test          | `POST /v1/accounts/{id}/webhook/test` | `webhooks:write` |
