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

# Webhook Event Catalog

> Every webhook event subject you can subscribe to — customer and transfer events, with their triggers and example payloads.

This page lists every event you can pass in `subscribedEvents` when [registering a webhook endpoint](/concepts/webhooks/managing-endpoints). Event names follow the `{resource}.{subject}` convention. Events fire on transitions of the resource's publicly observable status — internal-only states never produce webhook events.

## Wildcards

In addition to individual event names, `subscribedEvents` accepts:

| Value        | Subscribes to       |
| ------------ | ------------------- |
| `*`          | Every event         |
| `customer.*` | All customer events |
| `transfer.*` | All transfer events |

## Customer events

Fired as a customer's [verification profile](/concepts/onboarding/verification-profile) moves through its status lifecycle. One event fires per verification profile per transition — a customer with multiple profiles produces an independent event stream per profile.

| Event               | Trigger                                                                                                                                                                              |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `customer.created`  | `POST /v2/customer` succeeds. `previousStatus` is `null`, `status` is `incomplete`, and `verificationProfile` is `null` (the event marks entity creation, not a profile transition). |
| `customer.pending`  | All `required` criteria items resolve for a verification profile.                                                                                                                    |
| `customer.approved` | SpherePay completes review and approves the verification profile.                                                                                                                    |
| `customer.rejected` | SpherePay completes review and rejects the verification profile.                                                                                                                     |

Example — `customer.approved`:

```json theme={"dark"}
{
  "id": "event_01HXP9ZK7Q4ABC123",
  "type": "customer.approved",
  "apiVersion": "v2",
  "originalCreateDate": "2026-08-07T14:00:00.123456Z",
  "livemode": true,
  "sequence": 3,
  "data": {
    "id": "customer_f31121c389624d3697cbf3ea8830b7a4",
    "type": "customer",
    "applicationId": "application_1324354657",
    "verificationProfile": "kyc_profile_a",
    "previousStatus": "pending",
    "previousStatusAt": "2026-08-06T10:15:30.000Z",
    "status": "approved",
    "statusAt": "2026-08-07T14:00:00.000Z",
    "cause": null
  }
}
```

<Note>
  The `cause` field is reserved for a machine-readable rejection reason. It is currently always `null`, including on `customer.rejected` — structured rejection reasons ship in an upcoming release.
</Note>

## Transfer events

Fired as a [transfer](/concepts/transfers/lifecycle) moves through its status lifecycle. Webhooks are now the recommended way to track transfer progress.

| Event                               | Trigger                                                                                                                                                                             |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transfer.created`                  | `POST /v2/transfer` succeeds. `previousStatus` is `null`; `status` is the initial state (typically `pendingFunding`).                                                               |
| `transfer.pendingFunding`           | The transfer returned to `pendingFunding` — for example, after clearing `pendingReview`. The initial `pendingFunding` state is covered by `transfer.created`, not a separate event. |
| `transfer.pendingReview`            | The transfer entered `pendingReview` — the payment may require additional compliance review.                                                                                        |
| `transfer.fundsReceived`            | SpherePay detected funds from the customer.                                                                                                                                         |
| `transfer.processing`               | Processing started.                                                                                                                                                                 |
| `transfer.succeeded`                | Terminal success — funds delivered to the destination.                                                                                                                              |
| `transfer.returned`                 | The destination bank returned the transfer.                                                                                                                                         |
| `transfer.pendingRefundInformation` | SpherePay needs information from the customer to complete a refund.                                                                                                                 |
| `transfer.refunded`                 | The refund was delivered to the customer.                                                                                                                                           |
| `transfer.failed`                   | Terminal failure.                                                                                                                                                                   |
| `transfer.canceled`                 | The customer canceled before funding.                                                                                                                                               |
| `transfer.expired`                  | The transfer expired before funding.                                                                                                                                                |
| `transfer.failedPrecondition`       | Customer-provided information failed a precondition check.                                                                                                                          |
| `transfer.unexpectedError`          | An unexpected error occurred during processing.                                                                                                                                     |

Example — `transfer.succeeded`:

```json theme={"dark"}
{
  "id": "event_01HXPA3M9R7DEF456",
  "type": "transfer.succeeded",
  "apiVersion": "v2",
  "originalCreateDate": "2026-08-07T14:05:30.000Z",
  "livemode": true,
  "sequence": 5,
  "data": {
    "id": "payout_d243ab2b1de4447d8a046d87fefe58cf",
    "type": "transfer",
    "applicationId": "application_1324354657",
    "customerId": "customer_f31121c389624d3697cbf3ea8830b7a4",
    "transferType": "oneTimeTransfer",
    "previousStatus": "processing",
    "previousStatusAt": "2026-08-07T14:02:15.000Z",
    "status": "succeeded",
    "statusAt": "2026-08-07T14:05:30.000Z",
    "cause": null
  }
}
```

<Note>
  Transfer event names use the public API resource name (`transfer.*`), while `data.id` uses the `payout_` prefix — matching the IDs returned by the `/v2/transfer` API today. `transferType` is `staticTransfer` for on-ramper accounts and offloader wallets, `oneTimeTransfer` otherwise. The deprecated `undeliverable` status does not produce events.
</Note>

<Note>
  The `cause` field is reserved for a machine-readable failure reason on terminal failure events (`transfer.failed`, `transfer.returned`, `transfer.expired`, `transfer.canceled`, `transfer.failedPrecondition`, `transfer.unexpectedError`). It is currently always `null` — structured failure reasons ship in an upcoming release.
</Note>
