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

# Webhooks

> Register endpoints, verify signatures, and handle Swapnice async events.

Ingest and consent revocation are accepted quickly. Work that happens after that — archive and profile refresh — is asynchronous. Webhooks are how your backend learns without polling.

Endpoint **registration** is live in V1. **Delivery** of signed posts is near-term. Build the receiver during the pilot so you are ready when delivery is turned on.

## Register an endpoint

```ts theme={null}
const { endpoint, signing_secret } = await swapnice.webhookEndpoints.create({
  url: "https://partner.example.com/swapnice/webhooks",
  enabled_events: ["event.processed", "event.failed", "consent.revoked", "profile.updated"],
});
```

```json theme={null}
{
  "endpoint": {
    "id": "wh_91",
    "url": "https://partner.example.com/swapnice/webhooks",
    "enabled_events": ["event.processed", "event.failed", "consent.revoked", "profile.updated"],
    "status": "active",
    "created_at": "2026-08-26T16:20:00.000Z"
  },
  "signing_secret": "whsec_..."
}
```

Store `signing_secret` once. List endpoints with `GET /v1/webhook-endpoints`.

## Event types

| Type                                        | When                                   | V1 status                       |
| ------------------------------------------- | -------------------------------------- | ------------------------------- |
| `event.processed`                           | Archive finished for an ingested event | Config live, delivery near-term |
| `event.failed`                              | Projection failed                      | Config live, delivery near-term |
| `consent.revoked`                           | A purpose or receipt was revoked       | Config live, delivery near-term |
| `profile.updated`                           | Resolved facts changed for a customer  | Config live, delivery near-term |
| `connection.created` / `connection.revoked` | Link lifecycle                         | Designed                        |
| `consent.granted`                           | Receipt created                        | Designed                        |

Until delivery ships, poll `GET /v1/events/:id` and `GET /v1/workflows/:id`.

## Designed delivery envelope

```json theme={null}
{
  "id": "wev_3301",
  "type": "event.processed",
  "created_at": "2026-08-26T16:04:01.004Z",
  "data": {
    "event_id": "evt_9c21",
    "customer_id": "cust_8f2a1c",
    "status": "processed"
  }
}
```

Verify the signature with the endpoint secret before you trust the body. Reject unsigned or stale timestamps. Respond `2xx` quickly; do heavier joins on your side asynchronously.

## What to do with each event

| Type              | Partner action                                                            |
| ----------------- | ------------------------------------------------------------------------- |
| `event.processed` | Safe to read profile / intents for that customer                          |
| `event.failed`    | Inspect the event, fix schema, retry with a new idempotency key if needed |
| `consent.revoked` | Stop using that customer's intelligence for the revoked purpose           |
| `profile.updated` | Refresh a cached personalization payload                                  |

`consent.revoked` is the suppression path to implement before go-live, even if you poll rather than wait for the webhook.
