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

# Webhooks

> Receive real-time event notifications from Conduit

## Overview

Webhooks deliver real-time HTTP callbacks when events happen in your Conduit account. Instead of polling the API, register an endpoint and Conduit pushes events to you.

Conduit guarantees **at-least-once delivery** — your endpoint may receive the same event more than once. Clients SHOULD dedup by `id` and order by `createdAt`. We do not guarantee strict transport ordering.

## Setting Up

### 1. Create an endpoint

```bash theme={null}
curl -X POST https://api.conduit.financial/v2/webhooks/endpoints \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/conduit",
    "subscription": {
      "mode": "selected",
      "eventTypes": ["application.approved", "application.rejected"]
    }
  }'
```

The response includes a `secret`. Save it securely, it is only shown once and cannot be retrieved later.

`subscription` is a tagged union:

* `{ "mode": "all" }` (the default if `subscription` is omitted) subscribes the endpoint to every event type.
* `{ "mode": "selected", "eventTypes": ["..."] }` subscribes only to the listed event types. `eventTypes` must be non-empty.

To change the subscription later, `PATCH /v2/webhooks/endpoints/:id` with the same `subscription` shape.

### 2. Verify signatures

Every webhook request includes a `X-Conduit-Signature` header in the format:

```
t=<unix-timestamp>,v1=<hex-hmac>[,v1=<hex-hmac>]
```

Where each `v1` is `HMAC-SHA256(<unix-timestamp>.<raw-body>, secret)`, computed over the raw request bytes before any JSON parsing.

A delivery normally carries a single `v1`. While you are rotating an endpoint's signing secret, deliveries carry **two** `v1` values for a grace period — one signed with your new secret and one with the previous one — so deliveries keep verifying while you roll your secret over. **Verify by recomputing the digest for your secret and accepting the delivery if it matches any `v1` value.** Once the grace period ends, only the current secret is used.

We recommend rejecting deliveries where `t` is older than 300 seconds to guard against replay attacks.

<Warning>
  **The `whsec_` prefix is part of the HMAC key — do not strip it.** Your
  signing secret is shaped `whsec_<64-hex>`. Pass the FULL string verbatim,
  including the `whsec_` prefix, as the HMAC-SHA256 key. Stripping the prefix
  produces a different digest and every valid delivery fails verification —
  the failure mode is identical to a tampered signature (silent 401, no
  diagnostic).
</Warning>

```js Node.js / Bun theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

/**
 * Reference Node.js/Bun verifier. Other runtimes: use the equivalent
 * HMAC-SHA256 + constant-time compare. `rawBody` MUST be the raw UTF-8
 * bytes (do not parse JSON first). `t` is unix seconds. `secret` is the
 * full per-endpoint string including the `whsec_` prefix — pass it as-is.
 */
function verifyWebhookSignature(rawBody, signatureHeader, secret) {
  const pairs = signatureHeader.split(",").map((p) => p.split("="));
  const t = pairs.find(([k]) => k === "t")?.[1];
  // A delivery carries more than one v1 while you rotate the signing secret
  // (the previous secret co-signs during the grace period). Collect every
  // valid v1 and accept if your secret matches any of them. Each v1 must be a
  // 64-char hex string (32 bytes); rejecting anything else protects
  // timingSafeEqual from throwing on a length mismatch.
  const signatures = pairs
    .filter(([k, v]) => k === "v1" && /^[0-9a-f]{64}$/i.test(v ?? ""))
    .map(([, v]) => v);
  if (!t || signatures.length === 0) return false;

  const tNum = Number(t);
  if (!Number.isFinite(tNum)) return false;

  const ageSeconds = Math.floor(Date.now() / 1000) - tNum;
  if (ageSeconds > 300 || ageSeconds < 0) return false;

  // `secret` is the full `whsec_...` string. Do NOT strip the prefix.
  const expected = createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  const expectedBuf = Buffer.from(expected, "hex");

  return signatures.some((v1) =>
    timingSafeEqual(expectedBuf, Buffer.from(v1, "hex")),
  );
}
```

```python Python 3 theme={null}
import hmac
import time
from hashlib import sha256

def verify_webhook_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    """
    Reference Python verifier. ``raw_body`` MUST be the raw request bytes
    (do not ``json.loads`` first). ``signature_header`` is the
    ``X-Conduit-Signature`` header value. ``secret`` is the full
    per-endpoint string including the ``whsec_`` prefix — pass it as-is.
    """
    pairs = [p.split("=", 1) for p in signature_header.split(",")]
    t = next((v for k, v in pairs if k == "t"), None)
    # A delivery carries more than one v1 while you rotate the signing secret
    # (the previous secret co-signs during the grace period). Collect every
    # valid v1 and accept if your secret matches any of them. Each v1 must be a
    # 64-char lowercase hex string (32 bytes).
    signatures = [
        v
        for k, v in pairs
        if k == "v1"
        and len(v) == 64
        and all(c in "0123456789abcdef" for c in v.lower())
    ]
    if not t or not signatures:
        return False
    try:
        t_int = int(t)
    except ValueError:
        return False
    age_seconds = int(time.time()) - t_int
    if age_seconds > 300 or age_seconds < 0:
        return False
    # ``secret`` is the full ``whsec_...`` string. Do NOT strip the prefix.
    expected = hmac.new(
        secret.encode("utf-8"),
        f"{t}.{raw_body.decode('utf-8')}".encode("utf-8"),
        sha256,
    ).hexdigest()
    return any(hmac.compare_digest(expected, v1) for v1 in signatures)
```

<Warning>
  Always verify signatures before processing webhook payloads. Reject requests
  where the signature does not match or the timestamp is stale.
</Warning>

#### Common verification mistakes

| Mistake                                                                      | Symptom                                                                                | Fix                                                                              |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Stripping the `whsec_` prefix before computing HMAC                          | Every valid delivery returns 401; logs look identical to a tampered request            | Pass the secret verbatim — the prefix is key material, not a label               |
| Parsing the request body as JSON before computing HMAC                       | Most deliveries pass, but any payload where field ordering or whitespace changes fails | Compute HMAC over the raw bytes received on the wire, before any deserialization |
| Comparing digests with `==`                                                  | Subtle timing side-channel; nothing visibly broken                                     | Use `crypto.timingSafeEqual` (Node) / `hmac.compare_digest` (Python)             |
| Trusting `X-Conduit-Event` for routing without verifying the signature first | Endpoint accepts forged events from anyone who can reach the URL                       | Verify the signature before reading any header or body field                     |

### 3. Rotate your signing secret

If your signing secret is leaked — or you rotate secrets on a schedule — call:

```
POST /v2/webhooks/endpoints/:id/rotate
```

The response returns a **new** secret once, in the same shape as create (`{ ...endpoint, "secret": "whsec_...", "signature": { ... } }`). Store it immediately; it is never shown again.

<Warning>
  This request requires an `Idempotency-Key` header. Rotation is destructive —
  it replaces your current secret — so a retried request that reused no key
  could rotate twice and discard the secret you just deployed. With a key, a
  retry replays the original response instead of rotating again. Use a fresh
  key per intentional rotation.
</Warning>

Rotation does not cut over instantly. For a grace period (about 48 hours) every delivery is signed with **both** the new and the previous secret — two `v1` values in `X-Conduit-Signature` (see [Verify signatures](#2-verify-signatures)). This lets you roll your verification over without dropping events:

1. Call rotate and store the new secret.
2. Deploy the new secret to your verifier. Because you accept **any** matching `v1`, deliveries keep verifying throughout — under the old secret before you deploy, under the new one after.
3. Once the grace period ends, only the new secret signs. Any verifier still on the old secret stops verifying — which is the forcing function that completes the rollover.

The grace deadline is not exposed on endpoint reads; size your rollout to complete within the window.

## Webhook Headers

Every webhook request includes these headers:

| Header                  | Description                                                                                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Content-Type`          | `application/json`                                                                                                                             |
| `X-Conduit-Signature`   | `t={unix},v1={hmac-hex}` — timestamp + HMAC-SHA256 signature (a second `v1` is present while a signing-secret rotation is in its grace period) |
| `X-Conduit-Delivery-Id` | Unique ID for this delivery attempt                                                                                                            |
| `X-Conduit-Event`       | The event type (e.g., `application.approved`)                                                                                                  |

## Payload Format

```json theme={null}
{
  "id": "evt_...",
  "type": "application.approved",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "applicationId": "app_..."
  }
}
```

The `data` object varies by event type. Use the `type` field to determine how to process the payload.

| Field        | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `id`         | Unique event ID. Use for client-side dedup.                     |
| `type`       | Event name (e.g. `application.approved`).                       |
| `createdAt`  | Timestamp the event was created (ISO 8601 UTC).                 |
| `apiVersion` | Public API major version: `"2"`.                                |
| `mode`       | `"live"` or `"sandbox"`. Lets one endpoint receive both safely. |
| `data`       | Event-specific payload. See `GET /v2/webhooks/event-types`.     |

### Tracking transaction progress via webhooks

`transaction.created` carries a `stage` field — the same progress signal as `GET /v2/transactions/:id`'s
`stage` (see [Progress: the `stage` field](/guides/send-payout#progress-the-stage-field)). Narrower
events that fire between creation and a terminal outcome (`transaction.processing`,
`transaction.awaiting_signature`, `transaction.signature_collected`, `transaction.quorum_met`,
`transaction.awaiting_sender_information`) do not carry `stage` — the event itself is a more
specific progress signal than `stage` would add.
Terminal events (`transaction.completed`, `.cancelled`, `.failed`) don't carry it either since `status`
already conveys the outcome. If you need the current `stage` between those events, poll
`GET /v2/transactions/:id` or `GET /v2/payouts/:id`.

<Note>
  For a non-custodial payout, `transaction.awaiting_signature` is discriminated by `signingMode`. A
  wallet in the `passkey_required` mode carries the signer's `verificationUrl` (use the latest
  `attempt`'s URL and discard earlier ones); for how to obtain that link, re-fetch it if you missed
  the delivery, and the one request pattern to avoid, see
  [Getting the signing link](/guides/non-custodial-payout-lifecycle#getting-the-signing-link). A
  wallet in a `programmatic` mode carries a `signingRequestId` — see
  [Machine-signer stamping](/guides/machine-signer-stamping) — plus an **optional** `verificationUrl`
  when its roster has a human passkey signer who may also approve on the verify page (a machine-only
  roster omits it).
</Note>

## Event Reference

<Tip>
  Use `GET /v2/webhooks/event-types` for the current list of available events,
  including example payloads for each event type.
</Tip>

### Paired events

A single business transition can emit more than one event. See the per-event descriptions in `GET /v2/webhooks/event-types` for the canonical dedupe rule on each pair.

## Delivery Lifecycle

Each webhook delivery goes through these statuses:

| Status       | Description                                |
| ------------ | ------------------------------------------ |
| `pending`    | Queued for delivery or scheduled for retry |
| `processing` | Currently being delivered                  |
| `succeeded`  | Your endpoint responded with a 2xx status  |
| `failed`     | All retry attempts exhausted               |

### Retries

Failed deliveries are retried with increasing delays:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | 30 seconds |
| 2       | 2 minutes  |
| 3       | 15 minutes |
| 4       | 1 hour     |
| 5+      | 4 hours    |

You can also manually retry a failed delivery:

```bash theme={null}
curl -X POST https://api.conduit.financial/v2/webhooks/deliveries/wdl_.../retry \
  -H "x-api-key: YOUR_API_KEY"
```

## Managing Endpoints

| Operation           | Endpoint                                                                                |
| ------------------- | --------------------------------------------------------------------------------------- |
| List endpoints      | `GET /v2/webhooks/endpoints`                                                            |
| Get endpoint        | `GET /v2/webhooks/endpoints/:id`                                                        |
| Update endpoint     | `PATCH /v2/webhooks/endpoints/:id`                                                      |
| Delete endpoint     | `DELETE /v2/webhooks/endpoints/:id`                                                     |
| List deliveries     | `GET /v2/webhooks/deliveries?endpointId=:id&status=failed&eventType=transaction.failed` |
| Get delivery detail | `GET /v2/webhooks/deliveries/:id`                                                       |

The `status` query parameter accepts `pending`, `processing`, `succeeded`, or `failed` (case-insensitive); unknown values return `400`. Filters compose with `endpointId`.

The `eventType` query parameter accepts an exact lowercase match against the event type (e.g. `transaction.failed` or `order.failed`). Unknown event types return an empty page. All three filters (`endpointId`, `status`, `eventType`) are optional and may be combined freely.

### `failureMessage` symmetry contract

The `failureMessage` value is consistent across three surfaces: the database row, the polled `GET /v2/transactions/{id}` response, and the `transaction.failed` webhook payload. Applies equally to `order.failed`.

| Failure origin                                             | DB `failure_message`            | Polled GET `failureMessage`             | Webhook `failureMessage`                |
| ---------------------------------------------------------- | ------------------------------- | --------------------------------------- | --------------------------------------- |
| Operator-driven (`simulate/*` with a `reason`)             | the supplied `reason`, verbatim | the supplied `reason`, verbatim         | the supplied `reason`, verbatim         |
| Compliance-driven (compliance review, sender-info timeout) | NULL                            | static `ErrorCatalog` text for the code | static `ErrorCatalog` text for the code |
| Money sent to an order's funding address                   | not reported                    | fixed text, and no `failureCode`        | fixed text, and no `failureCode`        |

The polled GET and the webhook payload never diverge, so an integrator can rely on either as the source of truth. On the last row the two agree with each other and carry the same fixed text however such a transfer ends, which is what makes them safe to branch on: there is no code to switch on, so treat the transfer as not completed and read `GET /v2/transactions?type=deposit_return` to see whether the funds went back.

### Pausing an Endpoint

Set `status: "disabled"` (via `PATCH /v2/webhooks/endpoints/:id`) to stop receiving new deliveries on an endpoint. The endpoint is excluded from event fan-out — no new deliveries are enqueued. In-flight deliveries already queued at the moment of the flip continue to retry per the [retry schedule](#retries) and are not cancelled. Set it back to `status: "active"` to resume receiving new deliveries.

## Best Practices

* **Respond quickly.** Return a 2xx status within 5 seconds. Process the event asynchronously after acknowledging receipt.
* **Deduplicate.** Use the event `id` to detect and skip duplicate deliveries.
* **Verify signatures.** Always validate `X-Conduit-Signature` before processing the payload.
* **Handle unknown events.** Your endpoint may receive new event types as the API evolves. Return 2xx for events you don't recognize — don't reject them.
* **Use HTTPS.** Webhook endpoint URLs must use HTTPS.

***

## application.approved

Fired when an application is approved. `applicationType` discriminates the variant — route on it: `customer_onboarding` — customer is now active; paired with `customer.created` (same applicationId, customerId, clientReferenceId); dedupe on (applicationId, customerId) if your handler reacts to either; idempotent re-approval does not re-emit the pair. `virtual_account` — virtual account has been created; `asset` carries the asset code/chain; the VA activates asynchronously and fires `virtual_account.activated` when ready. `crypto_wallet` — customer is now eligible for `POST /v2/customers/:customerId/wallets/claim-non-custodial`; no wallets have been provisioned yet. `customer_update` — the customer data change was accepted. `organization_onboarding` — organization is approved; no `customerId` is present.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "application.approved",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "applicationType": "customer_onboarding",
    "applicationId": "app_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-onboarding-001"
  }
}
```

| Field               | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                    |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationType`   | enum: "customer\_onboarding" \| "organization\_onboarding" \| "virtual\_account" \| "crypto\_wallet" \| "customer\_update"                                                                                                                                                                                                                                                                                                                                       | Yes      | Which ApplicationType approval this fires for. Use to route on your side.                                                                                      |
| `applicationId`     | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the approved application.                                                                                                                         |
| `customerId`        | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Customer associated with the approved application. Present for every applicationType except organization\_onboarding (which has no customer at approval time). |
| `asset`             | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Asset the virtual account will hold. Present only when applicationType is virtual\_account.                                                                    |
| `asset.code`        | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                   |
| `asset.chain`       | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat                                                                                                             |
| `clientReferenceId` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                               |

## application.rejected

Fired when an application is rejected. `applicationType` discriminates the variant. `failureCode` (machine-readable) and `failureMessage` (human-readable) are present when a specific reason is available. `customerId` is present for `virtual_account`, `crypto_wallet`, and `customer_update` rejections (customer exists by rejection time); absent for `organization_onboarding`; optional for `customer_onboarding` (absent when rejection occurs before customer creation). For `crypto_wallet`: jurisdiction-ineligible requests are refused synchronously with `422` at request time and do not create an application row, so no webhook fires for that case.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "application.rejected",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "applicationType": "customer_onboarding",
    "applicationId": "app_2xKjF9mQb7vN4hL1pR3w8t",
    "failureCode": "rejected_by_ops",
    "failureMessage": "Application does not meet compliance requirements",
    "clientReferenceId": "ext-onboarding-001"
  }
}
```

| Field               | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                                                                                                                                    |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationType`   | enum: "customer\_onboarding" \| "organization\_onboarding" \| "virtual\_account" \| "crypto\_wallet" \| "customer\_update"                                                                                                                                                                                                                                                                                                                                       | Yes      | Which ApplicationType rejection this fires for. Use to route on your side.                                                                                                                                                                                                                     |
| `applicationId`     | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the rejected application.                                                                                                                                                                                                                                                         |
| `customerId`        | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Customer associated with this application. Required for virtual\_account, crypto\_wallet, and customer\_update rejections (customer exists by rejection time). Absent for organization\_onboarding. Optional for customer\_onboarding (absent when rejection occurs before customer creation). |
| `asset`             | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Asset the virtual account would have held. Present only when applicationType is virtual\_account.                                                                                                                                                                                              |
| `asset.code`        | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                                   |
| `asset.chain`       | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat                                                                                                                                                                                                                                             |
| `failureCode`       | enum: "rejected\_by\_ops" \| "compliance\_denied"                                                                                                                                                                                                                                                                                                                                                                                                                | No       | Machine-readable failure code identifying the rejection category. Mirrors `failureCode` on `GET /v2/applications/:id`.                                                                                                                                                                         |
| `failureMessage`    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Human-readable message intended for display to your end user, if provided.                                                                                                                                                                                                                     |
| `resubmittable`     | boolean                                                                                                                                                                                                                                                                                                                                                                                                                                                          | No       | Present only when applicationType is organization\_onboarding. true: a fresh draft was opened and the organization can edit and resubmit. false: the rejection was final — the onboarding form stays closed and no resubmission is possible.                                                   |
| `clientReferenceId` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                               |

## claim.completed

Fired when a non-custodial claim resolves: every roster signer has enrolled and the wallets are activated. Carries the claimId returned by POST /v2/customers/:id/wallets/claim-non-custodial plus the activated wallet IDs, so you can close the loop on a claim you were polling.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "claim.completed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "claimId": "wcc_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletIds": [
      "wlt_2xKjF9mQb7vN4hL1pR3w8t"
    ]
  }
}
```

| Field        | Type            | Required | Description                                              |
| ------------ | --------------- | -------- | -------------------------------------------------------- |
| `claimId`    | string          | Yes      | The claim returned by POST /wallets/claim-non-custodial. |
| `customerId` | string          | Yes      | Customer whose non-custodial claim resolved.             |
| `walletIds`  | array of string | Yes      | Wallets activated by the claim, ready to receive funds.  |

## claim.failed

Fired when a non-custodial claim fails during provisioning — after the claim was accepted (202). Carries the claimId and a human-readable failure reason to surface to your user. (Synchronous validation failures — roster/threshold/jurisdiction — are returned inline on the POST as a 4xx and do NOT fire this webhook.)

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "claim.failed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "claimId": "wcc_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "failureReason": "Wallet provisioning could not be completed. Please try the claim again; if it keeps failing, contact support."
  }
}
```

| Field           | Type   | Required | Description                                               |
| --------------- | ------ | -------- | --------------------------------------------------------- |
| `claimId`       | string | Yes      | The claim returned by POST /wallets/claim-non-custodial.  |
| `customerId`    | string | Yes      | Customer whose non-custodial claim failed.                |
| `failureReason` | string | Yes      | Human-readable reason the claim could not be provisioned. |

## crypto\_wallet.completed

Fired when the customer's end user has finished onboarding their non-custodial wallets and the wallets are ready to receive funds. Carries the customerId; fetch the wallets with GET /v2/customers/:id/wallets. To close the loop on a specific claim with the activated wallet IDs, use claim.completed.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "crypto_wallet.completed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field        | Type   | Required | Description                                            |
| ------------ | ------ | -------- | ------------------------------------------------------ |
| `customerId` | string | Yes      | Customer whose crypto wallet onboarding has completed. |

## customer.created

Fired when a customer is created after onboarding approval. Paired with application.approved (applicationType=customer\_onboarding) on the first approval (same applicationId, customerId, clientReferenceId); on idempotent re-approval the customer already exists so the pair is not re-emitted. Dedupe on (applicationId, customerId) if your handler reacts to either.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "customer.created",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "applicationId": "app_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-onboarding-001",
    "type": "business"
  }
}
```

| Field               | Type                             | Required | Description                                                         |
| ------------------- | -------------------------------- | -------- | ------------------------------------------------------------------- |
| `customerId`        | string                           | Yes      | Unique ID of the newly created customer.                            |
| `applicationId`     | string                           | Yes      | Onboarding application that triggered customer creation.            |
| `clientReferenceId` | string                           | No       | Caller-supplied external reference from the onboarding application. |
| `type`              | enum: "business" \| "individual" | Yes      | Whether the customer is an individual or a business.                |

## customer.restricted

Fired when a restriction is placed on a customer. The customer is blocked from initiating the affected money-movement capabilities. The restriction reason and type are internal-only and are never included.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "customer.restricted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "organizationId": "org_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field            | Type   | Required | Description                                  |
| ---------------- | ------ | -------- | -------------------------------------------- |
| `customerId`     | string | Yes      | Customer on whom the restriction was placed. |
| `organizationId` | string | Yes      | Organization the customer belongs to.        |

## idv\_link.created

Fired when a hosted identity-verification link is created for a person on an application — one event per person. Subscribe to this event to deliver the link through your own channels. It is emitted regardless of whether Conduit also emails the person directly; that is a separate account setting and does not affect this event. `url` is a one-time credential: treat it as a secret and do not log it. Person referenceIds are listed on the application (`persons[]`), and a fresh link can be fetched at any time via POST /v2/applications/{applicationId}/persons/{personReferenceId}/idv-link.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "idv_link.created",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "applicationId": "app_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-onboarding-001",
    "personReferenceId": "app_2xKjF9mQb7vN4hL1pR3w8t:a4K",
    "url": "https://verify.example.com/session?token=example",
    "shortUrl": "https://short.example.com/example"
  }
}
```

| Field               | Type   | Required | Description                                                                                                                        |
| ------------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId`     | string | Yes      | Application the person belongs to.                                                                                                 |
| `customerId`        | string | No       | Customer associated with the application, when one exists at inquiry-creation time.                                                |
| `clientReferenceId` | string | No       | Caller-supplied external reference, if provided.                                                                                   |
| `personReferenceId` | string | Yes      | Stable reference of the person this link verifies (ownership.persons\[].referenceId).                                              |
| `url`               | string | Yes      | Hosted identity-verification URL the person opens. A one-time credential — deliver it to the person out-of-band and do not log it. |
| `shortUrl`          | string | Yes      | Short form of `url`, suitable for SMS/chat channels.                                                                               |

## order.cancelled

Fired when a pending order is cancelled — either by the sweep job (reason=expired, when lock\_expires\_at elapses) or by the client (reason=client\_cancelled, via POST /v2/orders/:id/cancel).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "order.cancelled",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "orderId": "ord_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-order-1",
    "reason": "client_cancelled",
    "cancelledAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field               | Type                                   | Required | Description                                                                                                                                                                         |
| ------------------- | -------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `orderId`           | string                                 | Yes      | Unique ID of the cancelled order.                                                                                                                                                   |
| `customerId`        | string                                 | Yes      | Customer who placed this order.                                                                                                                                                     |
| `clientReferenceId` | string                                 | No       | Caller-supplied external reference, if provided.                                                                                                                                    |
| `reason`            | enum: "expired" \| "client\_cancelled" | Yes      | Whether the order was cancelled by the client (`client_cancelled`) or expired due to elapsed lock time (`expired`). Matches the `cancellationReason` field on `GET /v2/orders/:id`. |
| `cancelledAt`       | string                                 | Yes      | ISO-8601 timestamp when the order was cancelled.                                                                                                                                    |

## order.created

Fired when an order is created via POST `/v2/orders`. The order is in `pending` status with the rate locked until `lockExpiresAt`. The order will not move funds until it is executed — either explicitly via POST `/v2/orders/:id/execute`, or automatically by the platform when source funds land (if `autoExecute` is true). If the lock expires while the order is still pending and unclaimed, the expiry sweep cancels it and `order.cancelled` fires with `reason: expired`. When the order was created without an explicit `source`, `depositInstructions` carries the address to fund it at; that order auto-executes once the deposit lands, and the lock expiry is the funding deadline instead of a rate lock.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "order.created",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "orderId": "ord_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-order-1",
    "type": "offramp",
    "sourceAssetAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "10000.000000"
    },
    "destinationAssetAmount": {
      "code": "USD",
      "amount": "9995.00"
    },
    "lockExpiresAt": "2026-01-16T09:30:00.000Z",
    "autoExecute": true,
    "createdAt": "2026-01-15T09:30:00.000Z",
    "depositInstructions": [
      {
        "type": "crypto_address",
        "address": "0x1234567890abcdef1234567890abcdef12345678",
        "chain": "ethereum",
        "asset": "USDC",
        "expiresAt": "2026-01-16T09:30:00.000Z"
      }
    ]
  }
}
```

| Field                           | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                                                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `orderId`                       | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the created order.                                                                                                                                                                                                                                                |
| `customerId`                    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Customer who placed this order.                                                                                                                                                                                                                                                |
| `clientReferenceId`             | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                               |
| `type`                          | enum: "onramp" \| "offramp" \| "conversion"                                                                                                                                                                                                                                                                                                                                                                                                                      | Yes      | Direction of the order (onramp, offramp, or conversion).                                                                                                                                                                                                                       |
| `sourceAssetAmount`             | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Source asset and amount that will be debited from the customer when the order executes.                                                                                                                                                                                        |
| `sourceAssetAmount.code`        | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                   |
| `sourceAssetAmount.chain`       | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                                                                                                                            |
| `sourceAssetAmount.amount`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                                                                                                                        |
| `destinationAssetAmount`        | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Destination asset and amount the customer will receive when the order executes.                                                                                                                                                                                                |
| `destinationAssetAmount.code`   | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                   |
| `destinationAssetAmount.chain`  | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                                                                                                                            |
| `destinationAssetAmount.amount` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                                                                                                                        |
| `lockExpiresAt`                 | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the order's rate lock expires; after this unclaimed pending orders are eligible for auto-cancel with reason `expired`. When `depositInstructions` is present (a deposit-funded order), this is the funding deadline rather than a rate lock.           |
| `autoExecute`                   | boolean                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes      | Whether the order will auto-execute when source funds land (true) or requires an explicit POST `/v2/orders/:id/execute` (false).                                                                                                                                               |
| `createdAt`                     | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the order was created.                                                                                                                                                                                                                                 |
| `depositInstructions`           | array of object                                                                                                                                                                                                                                                                                                                                                                                                                                                  | No       | Where to send funds to fund this order — the same array-of-blocks shape a virtual account's `depositInstructions` uses. Present only when the order was created without an explicit `source`, and then always exactly one `crypto_address` block. Absent on every other order. |

## order.failed

Fired when an order cannot execute or execution reaches a terminal failure. This includes pending auto-execute ONRAMP orders whose fiat source deposit terminates without crediting the customer — frozen, returned, or terminated before credit (e.g. sender-info timeout). `reasonCode` identifies the customer-facing failure category: `insufficient_funds` (source funds insufficient at execution time), `provider_unavailable` (transient rail/provider unavailability — retry may succeed), `provider_rejected` (provider or screening declined the leg, including source-deposit rejection on auto-execute ONRAMP orders; retry will not help — submit with a different recipient or funding source), `internal_error` (Conduit-side failure — contact support), `cancelled` (execution cancelled mid-flight).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "order.failed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "orderId": "ord_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-order-1",
    "reasonCode": "provider_rejected",
    "failedAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field               | Type                                                                                                               | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------- | ------------------------------------------------------------------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `orderId`           | string                                                                                                             | Yes      | Unique ID of the order that failed to execute.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `customerId`        | string                                                                                                             | Yes      | Customer who placed this order.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `clientReferenceId` | string                                                                                                             | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `reasonCode`        | enum: "insufficient\_funds" \| "provider\_unavailable" \| "provider\_rejected" \| "internal\_error" \| "cancelled" | Yes      | Public failure category. `insufficient_funds` (source funds insufficient at execution time), `provider_unavailable` (transient provider/rail unavailability — retry may succeed), `provider_rejected` (provider or screening declined the leg, including source-deposit rejection on auto-execute ONRAMP orders; retry will not help — submit with a different recipient or funding source), `internal_error` (Conduit-side failure — contact support), `cancelled` (execution cancelled mid-flight). |
| `failureMessage`    | string                                                                                                             | No       | Human-readable description of `reasonCode`. Defaults to the public error catalog text for the code. Sandbox simulators (e.g. the `reason` body on `orders/:id/simulate/conversion-failed`) and the counterparty travel-rule channel may pass through the operator/counterparty-supplied reason instead. The counterparty channel applies in both live and sandbox builds; raw provider/compliance text from other vendors is scrubbed at the same boundary that scrubs `reasonCode`.                  |
| `failedAt`          | string                                                                                                             | Yes      | ISO-8601 timestamp when execution failure was recorded.                                                                                                                                                                                                                                                                                                                                                                                                                                               |

## order.succeeded

Fired when an order completes successfully — the source amount has been debited from the customer and the destination amount has been credited and is available to spend. Carries the spawned `transactionId` (and `txHash` when a chain leg ran) so integrators can reconcile and link back to the underlying transaction without a GET round-trip.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "order.succeeded",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "orderId": "ord_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-order-1",
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "txHash": "0x7e0fb8d288a8d0058c6940f9327592f543415065a9180728688b51e0da44481c",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "status": "succeeded",
    "sourceAssetAmount": {
      "code": "USD",
      "amount": "10000.00"
    },
    "destinationAssetAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "9995.000000"
    },
    "totalDebit": {
      "code": "USD",
      "amount": "10010.00"
    },
    "payoutAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "9995.000000"
    },
    "fees": [
      {
        "type": "fixed",
        "assetAmount": {
          "code": "USD",
          "amount": "10.00"
        }
      }
    ],
    "succeededAt": "2026-01-15T09:30:00.000Z",
    "executionTrigger": "client"
  }
}
```

| Field                           | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                   |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `orderId`                       | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the succeeded order.                                                                                                                                             |
| `clientReferenceId`             | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                                              |
| `transactionId`                 | string \| null                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Yes      | ID of the `transactions` row this order spawned. Use to GET the underlying transaction for per-leg detail.                                                                    |
| `txHash`                        | string \| null                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Yes      | On-chain transaction hash from the order's chain leg (destination leg for ONRAMP, source leg for OFFRAMP). Null when the order has no chain leg or the hash is not yet known. |
| `customerId`                    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Customer who placed this order.                                                                                                                                               |
| `status`                        | "succeeded"                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Yes      | Terminal status. Always `succeeded` on this event; failures fire `order.failed` instead.                                                                                      |
| `sourceAssetAmount`             | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Conversion principal in source-asset terms (excludes the fee). `totalDebit = sourceAssetAmount + fees` is what's actually debited from the customer.                          |
| `sourceAssetAmount.code`        | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                  |
| `sourceAssetAmount.chain`       | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                           |
| `sourceAssetAmount.amount`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                       |
| `destinationAssetAmount`        | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Destination asset and amount credited to the customer (equals `sourceAssetAmount × rate`).                                                                                    |
| `destinationAssetAmount.code`   | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                  |
| `destinationAssetAmount.chain`  | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                           |
| `destinationAssetAmount.amount` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                       |
| `totalDebit`                    | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Total amount debited from the customer in source-asset terms (`sourceAssetAmount + fees`).                                                                                    |
| `totalDebit.code`               | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                  |
| `totalDebit.chain`              | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                           |
| `totalDebit.amount`             | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                       |
| `payoutAmount`                  | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Alias for `destinationAssetAmount`; kept for reconciliation tooling that pre-dates the symmetric amount semantics.                                                            |
| `payoutAmount.code`             | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                  |
| `payoutAmount.chain`            | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                           |
| `payoutAmount.amount`           | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                       |
| `fees`                          | array of object                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Yes      | Fee components applied to this order.                                                                                                                                         |
| `succeededAt`                   | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the order finished executing.                                                                                                                         |
| `executionTrigger`              | enum: "client" \| "auto"                                                                                                                                                                                                                                                                                                                                                                                                                                         | Yes      | Whether execution was triggered by the client or automatically by the platform.                                                                                               |

## organization.activated

Fired when an organization is activated

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "organization.activated",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "organizationName": "Acme Corp"
  }
}
```

| Field              | Type   | Required | Description                                          |
| ------------------ | ------ | -------- | ---------------------------------------------------- |
| `organizationName` | string | Yes      | Display name of the organization that was activated. |

## organization.restricted

Fired when a restriction is placed on an organization. Every customer under the org is blocked from the affected capabilities. The reason and type are internal-only.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "organization.restricted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "organizationId": "org_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field            | Type   | Required | Description                                                                                  |
| ---------------- | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `organizationId` | string | Yes      | Organization on which the restriction was placed. Every customer under this org is affected. |

## rfi.cancelled

Fired when a published request for information is cancelled. Fetch details via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.cancelled",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## rfi.deadline\_extended

Fired when compliance extends the response deadline on an open request for information. Fetch the new due date via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.deadline_extended",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## rfi.more\_info\_requested

Fired when compliance requests more information on an already-responded request for information, opening a new round. Fetch details via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.more_info_requested",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## rfi.published

Fired when a request for information is published to your organization. Fetch details via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.published",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## rfi.resolved

Fired when a request for information is resolved. Fetch details via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.resolved",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## rfi.response\_submitted

Fired when a client response to a request for information is stored. Fetch details via GET /v2/rfis/{id}.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "rfi.response_submitted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "rfiId": "rfi_2xKjF9mQb7vN4hL1pR3w8t"
  }
}
```

| Field   | Type   | Required | Description                                                                    |
| ------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `rfiId` | string | Yes      | Unique ID of the request for information. Fetch details via GET /v2/rfis/{id}. |

## transaction.awaiting\_sender\_information

Fired when a deposit is parked waiting for sender information for the source address. Payload carries the sourceAddress (null when no on-chain sender could be attributed) and an expiresAt deadline — after which the deposit auto-rejects. Chain is on assetAmount.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.awaiting_sender_information",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-deposit-1",
    "sourceAddress": "0x742d35cc6634c0532925a3b844bc9e7595f0beb1",
    "assetAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "1000.000000"
    },
    "detectedAt": "2026-01-15T09:30:00.000Z",
    "occurredAt": "2026-01-15T09:30:00.000Z",
    "expiresAt": "2026-02-14T09:30:00.000Z",
    "daysRemaining": 30,
    "deadlineAt": "2026-02-14T09:30:00.000Z"
  }
}
```

| Field                | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the parked deposit transaction.                                                                                                                                                                                                                                                                                                                                                                                                        |
| `customerId`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Customer who received the deposit.                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `clientReferenceId`  | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                                                                                                                                                                                    |
| `sourceAddress`      | string \| null                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Yes      | Normalized sender address the fintech must register. Null when Conduit could not attribute an on-chain sender to the deposit — submit the originator's identity via POST /v2/transactions/{id}/sender-information exactly as you would otherwise; only the pre-registration shortcut is unavailable.                                                                                                                                                |
| `assetAmount`        | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Amount and asset of the parked deposit.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `assetAmount.code`   | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `assetAmount.chain`  | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                                                                                                                                                                                                                                                                                                 |
| `assetAmount.amount` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                                                                                                                                                                                                                                                                                             |
| `detectedAt`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the deposit was first detected on-chain.                                                                                                                                                                                                                                                                                                                                                                                    |
| `occurredAt`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the deposit was parked because the source address was not registered.                                                                                                                                                                                                                                                                                                                                                       |
| `expiresAt`          | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 deadline — deposit auto-freezes if address is not registered by this time.                                                                                                                                                                                                                                                                                                                                                                 |
| `daysRemaining`      | integer \| null                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Yes      | Days remaining before the sender-info deadline. Re-emitted as the deadline approaches with the updated value; null on the final terminal-reached emission.                                                                                                                                                                                                                                                                                          |
| `deadlineAt`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp of the customer-facing deadline for providing sender information. Once exceeded, the deposit is terminated with failureCode sender\_info\_timeout. In live builds this is the real 30-day deadline. In sandbox the server-side timeout is compressed so the failure path is testable quickly, but this field still reflects the live-equivalent 30-day deadline so SDK consumers see the contract a live customer would receive. |

## transaction.awaiting\_signature

Fired when the customer's signing roster must approve before broadcast — on a payout, or on the source transfer of a conversion from a non-custodial wallet. The payload is discriminated by `signingMode`. `passkey_required` carries the shared `verificationUrl` (Conduit-hosted approval page the fintech distributes to its human signers). `programmatic` / `programmatic_unattended` carry a `signingRequestId` — a machine integration discovers the signing details with `GET /v2/signing-requests/{id}` and approves via `POST /v2/signing-requests/{id}/approve` or rejects via `POST /v2/signing-requests/{id}/reject`. A programmatic payload ALSO carries an optional `verificationUrl` when the wallet's roster has an active passkey signer: that human signer is a member of the signing quorum and may approve the payout on the verify page alongside the machine signers. The `verificationUrl` is omitted for a machine-only roster. If a signing window expires before quorum, Conduit rebuilds the request (fresh nonce/fees) and re-fires this event with an incremented `attempt`; treat the latest `attempt` as authoritative. After the final attempt expires the payout fails with `user_signature_expired` (a conversion fails via `order.failed`).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.awaiting_signature",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "signingMode": "passkey_required",
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "assetAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "1000.000000"
    },
    "destinationAddress": "0x742d35cc6634c0532925a3b844bc9e7595f0beb1",
    "verificationUrl": "https://app.conduit.financial/verify/vtok_2xKjF9mQb7vN4hL1pR3w8t",
    "requiredApprovals": 2,
    "occurredAt": "2026-01-15T09:30:00.000Z",
    "expiresAt": "2026-01-15T09:45:00.000Z",
    "attempt": 1
  }
}
```

| Field                | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required                                                             | Description                                                                                                                                                                                                                                                                                    |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | Unique ID of the parked payout transaction.                                                                                                                                                                                                                                                    |
| `customerId`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | Customer initiating the payout.                                                                                                                                                                                                                                                                |
| `clientReferenceId`  | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No                                                                   | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                               |
| `assetAmount`        | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | Amount and asset of the pending payout.                                                                                                                                                                                                                                                        |
| `assetAmount.code`   | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes                                                                  | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                                   |
| `assetAmount.chain`  | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No                                                                   | Chain when the asset is on-chain; omitted for fiat.                                                                                                                                                                                                                                            |
| `assetAmount.amount` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | Decimal string, asset-precision rounded                                                                                                                                                                                                                                                        |
| `destinationAddress` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | On-chain destination address for the payout.                                                                                                                                                                                                                                                   |
| `requiredApprovals`  | integer                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes                                                                  | M — signer stamps required to authorize, frozen at prepare time.                                                                                                                                                                                                                               |
| `occurredAt`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | ISO-8601 timestamp when the payout was parked awaiting signature.                                                                                                                                                                                                                              |
| `expiresAt`          | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes                                                                  | ISO-8601 deadline for THIS signing attempt. If the roster does not sign by this time the payout is automatically re-offered (a new event with an incremented `attempt`); it only fails after the final attempt's window elapses.                                                               |
| `attempt`            | integer                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes                                                                  | Signing-attempt counter for this payout. 1 on the first request; the event re-fires with an incrementing `attempt` each time the prior window expires and a fresh request is issued. Treat the latest `attempt` as authoritative and dedupe redeliveries on (transactionId, attempt).          |
| `signingMode`        | enum: "passkey\_required" \| "programmatic" \| "programmatic\_unattended"                                                                                                                                                                                                                                                                                                                                                                                        | Yes                                                                  | Discriminates the payload variant (one of `passkey_required`, `programmatic`, `programmatic_unattended`). See the per-variant fields below.                                                                                                                                                    |
| `verificationUrl`    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes when `signingMode` = `passkey_required`; optional otherwise      | Conduit-hosted URL the fintech routes its human signers to for approval.                                                                                                                                                                                                                       |
| `signingRequestId`   | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes when `signingMode` = `programmatic` or `programmatic_unattended` | Signing-request id. Your server discovers the signing details with GET /v2/signing-requests/{id} and approves via POST /v2/signing-requests/{id}/approve or rejects via POST /v2/signing-requests/{id}/reject. Present only when `signingMode` is `programmatic` or `programmatic_unattended`. |

## transaction.awaiting\_user\_signature

Deprecated — superseded by `transaction.awaiting_signature`; still delivered during a compatibility window and removed in a future release. Fired when the customer's signing roster must approve before broadcast — on a payout, or on the source transfer of a conversion from a non-custodial wallet. Payload carries the single shared verificationUrl (Conduit-hosted approval page distributed by the fintech to its signers), expiresAt, and attempt. If a signing window expires before quorum, Conduit rebuilds the request (fresh nonce/fees, a new verificationUrl) and re-fires this event with an incremented attempt; clients should always treat the latest verificationUrl as authoritative and discard prior links. After the final attempt expires the payout fails with `user_signature_expired` (a conversion fails via `order.failed`).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.awaiting_user_signature",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "assetAmount": {
      "code": "USDC",
      "chain": "ethereum",
      "amount": "1000.000000"
    },
    "destinationAddress": "0x742d35cc6634c0532925a3b844bc9e7595f0beb1",
    "verificationUrl": "https://app.conduit.financial/verify/vtok_2xKjF9mQb7vN4hL1pR3w8t",
    "requiredApprovals": 2,
    "occurredAt": "2026-01-15T09:30:00.000Z",
    "expiresAt": "2026-01-15T09:45:00.000Z",
    "attempt": 1
  }
}
```

| Field                | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                                                                                                                           |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the parked payout transaction.                                                                                                                                                                                                                                           |
| `customerId`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Customer initiating the payout.                                                                                                                                                                                                                                                       |
| `clientReferenceId`  | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                      |
| `assetAmount`        | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Amount and asset of the pending payout.                                                                                                                                                                                                                                               |
| `assetAmount.code`   | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                                                                                                                                                                                                                                                          |
| `assetAmount.chain`  | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat.                                                                                                                                                                                                                                   |
| `assetAmount.amount` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Decimal string, asset-precision rounded                                                                                                                                                                                                                                               |
| `destinationAddress` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | On-chain destination address for the payout.                                                                                                                                                                                                                                          |
| `requiredApprovals`  | integer                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes      | M — signer stamps required to authorize, frozen at prepare time.                                                                                                                                                                                                                      |
| `occurredAt`         | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the payout was parked awaiting signature.                                                                                                                                                                                                                     |
| `expiresAt`          | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 deadline for THIS signing attempt. If the roster does not sign by this time the payout is automatically re-offered (a new event with an incremented `attempt`); it only fails after the final attempt's window elapses.                                                      |
| `attempt`            | integer                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes      | Signing-attempt counter for this payout. 1 on the first request; the event re-fires with an incrementing `attempt` each time the prior window expires and a fresh request is issued. Treat the latest `attempt` as authoritative and dedupe redeliveries on (transactionId, attempt). |
| `verificationUrl`    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Conduit-hosted URL the fintech routes the user to for approval.                                                                                                                                                                                                                       |

## transaction.cancelled

Fired when a transaction is cancelled before reaching its terminal-completed state. Distinct from `transaction.failed`: a cancelled transaction is not a failure; the client (or, in the future, an expiry sweep) terminated it intentionally. `cancellationReason` is `client_cancelled` when the client called `POST /v2/payouts/:id/cancel`. Reserved value `expired` is published when the underlying lock window elapses (future). The payload intentionally has no `failureCode`/`failureMessage`. Shares the cancellation semantics and `cancellationReason` vocabulary with `order.cancelled` (the payload itself is transaction-shaped: `transactionId` + nested `source`/`destination`).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.cancelled",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "type": "withdrawal",
    "source": {
      "type": "virtual_account",
      "virtualAccountId": "vac_2xKjF9mQb7vN4hL1pR3w8t",
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      }
    },
    "destination": {
      "type": "external_bank",
      "recipient": {
        "rail": "us",
        "type": "individual",
        "firstName": "Jane",
        "lastName": "Doe",
        "accountNumber": "0123456789",
        "routingNumber": "021000021",
        "accountType": "checking",
        "bankAddress": {
          "addressLine1": "1 Main St",
          "city": "NYC",
          "country": "USA"
        },
        "phone": "+15551234",
        "postalAddress": {
          "addressLine1": "1 Main St",
          "city": "NYC",
          "postalCode": "10001",
          "country": "USA"
        }
      },
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      }
    },
    "cancellationReason": "client_cancelled",
    "cancelledAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field                | Type                                                                                                                                                          | Required | Description                                                                                                                                                                                                                                                                          |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `transactionId`      | string                                                                                                                                                        | Yes      | Unique ID of the cancelled transaction.                                                                                                                                                                                                                                              |
| `customerId`         | string                                                                                                                                                        | Yes      | Customer associated with this transaction.                                                                                                                                                                                                                                           |
| `clientReferenceId`  | string                                                                                                                                                        | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                     |
| `type`               | enum: "deposit" \| "onramp" \| "offramp" \| "withdrawal" \| "conversion" \| "deposit\_return"                                                                 | Yes      | Transaction type. Same value as on `transaction.created`.                                                                                                                                                                                                                            |
| `source`             | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Source side of the cancelled transaction — same nested shape as GET /v2/transactions/:id.                                                                                                                                                                                            |
| `destination`        | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Destination side of the cancelled transaction.                                                                                                                                                                                                                                       |
| `cancellationReason` | enum: "expired" \| "client\_cancelled"                                                                                                                        | Yes      | Whether the transaction was cancelled by the client (`client_cancelled`) — today the only path that publishes this event — or, in the future, expired (`expired`). Matches the `cancellationReason` field on `GET /v2/transactions/:id`. Mirrors `order.cancelled`'s `reason` field. |
| `cancelledAt`        | string                                                                                                                                                        | Yes      | ISO-8601 timestamp when the transaction was cancelled.                                                                                                                                                                                                                               |
| `linkedOrderId`      | string                                                                                                                                                        | No       | The Order this transaction belongs to: present on the Conversion an Order executes and on a Withdrawal chained from that Order's autoPayout. Absent on transactions with no Order (deposits, standalone payouts, deposit returns).                                                   |

## transaction.completed

Fired when a transaction completes successfully. `source` and `destination` carry the same nested shape as `GET /v2/transactions/:id`. The settlement reference lives inside the relevant side variant: `external_crypto.txHash` for crypto rails, and on `external_bank` the real wire references as typed fields — `swiftUetr`, `fedwireImad`, `fedwireOmad`, `achTraceNumber`, `rtpTransactionId`, `fedNowMessageId` — each present only when the network exposes it (on-us transfers carry none). Fiat payout events include the selected rail for reconciliation on `payout.rail`.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.completed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "type": "withdrawal",
    "status": "completed",
    "source": {
      "type": "virtual_account",
      "virtualAccountId": "vac_2xKjF9mQb7vN4hL1pR3w8t",
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      }
    },
    "destination": {
      "type": "external_bank",
      "recipient": {
        "rail": "us",
        "type": "individual",
        "firstName": "Jane",
        "lastName": "Doe",
        "accountNumber": "0123456789",
        "routingNumber": "021000021",
        "accountType": "checking",
        "bankAddress": {
          "addressLine1": "1 Main St",
          "city": "NYC",
          "country": "USA"
        },
        "phone": "+15551234",
        "postalAddress": {
          "addressLine1": "1 Main St",
          "city": "NYC",
          "postalCode": "10001",
          "country": "USA"
        }
      },
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      },
      "fedwireImad": "20260616MMQFMP9C000123"
    },
    "payout": {
      "rail": "fedwire"
    },
    "completedAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field                      | Type                                                                                                                                                          | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`            | string                                                                                                                                                        | Yes      | Unique ID of the completed transaction.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `customerId`               | string                                                                                                                                                        | Yes      | Customer associated with this transaction.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `clientReferenceId`        | string                                                                                                                                                        | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `type`                     | enum: "deposit" \| "onramp" \| "offramp" \| "withdrawal" \| "conversion" \| "deposit\_return"                                                                 | Yes      | Transaction type.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `status`                   | "completed"                                                                                                                                                   | Yes      | Terminal status. Always `completed` on this event; failures fire `transaction.failed` instead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `source`                   | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Source side of the transaction — same nested shape as GET /v2/transactions/:id. On crypto rails the on-chain settlement hash lives inside the matching `external_crypto.txHash`; on fiat rails the real wire references are typed fields on the matching `external_bank` (`swiftUetr`, `fedwireImad`, `fedwireOmad`, `achTraceNumber`, `rtpTransactionId`, `fedNowMessageId`), present only when the network exposes one. Inbound fiat (`external_bank_inbound`) carries the same typed reference fields plus a `sender` block (`name`, `country`, `accountNumber`, `routingNumber`, `iban`, `bic`) with what the sending bank transmitted. Each reference is independent: an incoming wire reports whichever of `fedwireImad`, `fedwireOmad` and `swiftUetr` the sending bank supplied, and any of them may be absent. Do NOT infer the rail from which field is present — `swiftUetr` is the ISO 20022 UETR, which a Fedwire message carries too, so its presence does not mean the payment travelled on SWIFT. An incoming ACH reports `achTraceNumber`. A deposit delivered on-us from another account in your own organization carries no wire references at all — its source is `internal_transfer` with `originatingTransactionId` pointing at the withdrawal that sent it. |
| `destination`              | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Destination side of the transaction. See `source` for the settlement-reference placement rule.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `payout`                   | object                                                                                                                                                        | No       | Payout rail metadata. Present only for outbound transactions.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `payout.rail`              | enum: "fedwire" \| "rtp" \| "fednow" \| "swift" \| null                                                                                                       | Yes      | Fiat payment rail used, if applicable. Null for crypto payouts.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `completedAt`              | string                                                                                                                                                        | Yes      | ISO-8601 timestamp when the transaction completed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `linkedOrderId`            | string                                                                                                                                                        | No       | The Order this transaction belongs to: present on the Conversion an Order executes and on a Withdrawal chained from that Order's autoPayout. Absent on transactions with no Order (deposits, standalone payouts, deposit returns).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `matchableOrders`          | array of object                                                                                                                                               | No       | Pending orders that can execute against the deposited funds. Only populated for inbound DEPOSIT transactions.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `matchableOrdersTruncated` | boolean                                                                                                                                                       | No       | True when the matchable orders list was truncated due to size limits.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

## transaction.created

Fired when a new transaction is initiated. `type` identifies the direction: `deposit`, `onramp`, `offramp`, `withdrawal`, `conversion` (a crypto-to-crypto swap or bridge between two of the customer's wallets), or `deposit_return` (funds sent back from an order's funding address to the address they came from). `source` and `destination` carry the same nested shape as `GET /v2/transactions/:id` — discriminated by `type` (wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) and each variant carries its own `assetAmount`. `stage` is the same client-safe progress signal as the GET response — see that endpoint's field docs for the vocabulary and lifecycle. Transactions belonging to an order carry `linkedOrderId` referencing it — both the conversion the order executes and a withdrawal chained from its `autoPayout`; absent on transactions with no order.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.created",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "type": "deposit",
    "stage": "settling",
    "source": {
      "type": "external_bank_inbound",
      "sender": {
        "name": "Acme Trading LLC",
        "country": "US",
        "accountNumber": "0123456789",
        "routingNumber": "021000021"
      },
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      }
    },
    "destination": {
      "type": "virtual_account",
      "virtualAccountId": "vac_2xKjF9mQb7vN4hL1pR3w8t",
      "wireReceive": {
        "rail": "us",
        "bankName": "First Example Bank",
        "accountLast4": "4321",
        "routingNumber": "021000089"
      },
      "assetAmount": {
        "code": "USD",
        "amount": "1000.00"
      }
    },
    "createdAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field               | Type                                                                                                                                                          | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`     | string                                                                                                                                                        | Yes      | Unique ID of the transaction.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `customerId`        | string                                                                                                                                                        | Yes      | Customer who initiated or received this transaction.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `clientReferenceId` | string                                                                                                                                                        | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `type`              | enum: "deposit" \| "onramp" \| "offramp" \| "withdrawal" \| "conversion" \| "deposit\_return"                                                                 | Yes      | Transaction type.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `stage`             | enum: "awaiting\_signature" \| "awaiting\_customer\_action" \| "under\_review" \| "settling"                                                                  | No       | Progress signal, same vocabulary and lifecycle as the `stage` field on GET /v2/transactions/:id — see that field's description for the values and what each does/doesn't imply. Informational only; does not replace `requiresUserSignature`, `hasRfi`, or `failureCode` for action decisions. Always non-terminal at creation time.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `source`            | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Source side of the transaction — the variant matches the GET /v2/transactions/:id shape (wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown). Includes `assetAmount` (amount + asset code/chain); amounts always live per-side — transaction objects never carry a top-level `assetAmount`. The `external_bank_inbound` variant adds a `sender` block with what the sending bank transmitted: `name`, `country` (ISO 3166-1 alpha-2), `accountNumber`, `routingNumber`, `iban`, `bic` — each present only when provided. The `internal_transfer` variant — a deposit that arrived from another account in your own organization, carrying `originatingTransactionId` — is not yet resolved at first detection: the link resolves as the deposit is detected, which happens after creation. Do not narrow this field on `transaction.created`; `transaction.completed` and every read carry the resolved source. |
| `destination`       | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown) | Yes      | Destination side of the transaction — same shape as `source`. The variant determines which counterparty details are populated (wallet, Conduit-provided deposit\_address, virtual account with optional wireReceive, external crypto address, external bank recipient).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `linkedOrderId`     | string                                                                                                                                                        | No       | The Order this transaction belongs to: present on the Conversion an Order executes and on a Withdrawal chained from that Order's autoPayout. Absent on transactions with no Order (deposits, standalone payouts, deposit returns).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `createdAt`         | string                                                                                                                                                        | Yes      | ISO-8601 timestamp when the transaction was created.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

## transaction.failed

Fired when a transaction reaches a terminal failed state. `source` and `destination` carry the same nested shape as `GET /v2/transactions/:id`. The payload carries a `failureCode` your integration can branch on:

* `user_signature_*` — recoverable: submit a new transaction.
* `chain_broadcast_failed` — the on-chain broadcast or signing did not reach finality and no funds left the wallet; recoverable, submit a new payout.
* `crypto_wallet_misconfigured` — the wallet's signing configuration prevents Conduit from moving funds and the wallet has been frozen; NOT recoverable by retrying, contact support.
* `provider_rejected` — chain RPC or sandbox-scenario declined the broadcast; `failureMessage` carries the operator/scenario-supplied reason when the underlying message was marked for public surfacing (sandbox/scenario paths). Live provider diagnostics are gated off the public surface. Adjust inputs (e.g. destination address, amount) and retry.
* `travel_rule_rejected` — counterparty VASP rejected the travel-rule transfer; `failureMessage` carries the counterparty's reason when supplied. Not retryable without coordinating with the receiving institution.
* `compliance_hold` / `compliance_review_rejected` — compliance review required; not retryable without investigation.
* `returned_by_sender` — fiat sender reversed the inbound transfer, or compliance marked the deposit returned before credit. A transfer sent back from a funding address carries no `failureCode` at all — see the [RETURNED\_BY\_SENDER page](/errors/returned-by-sender) for how to reconcile that case.
* `rail_policy_rejected` / `insufficient_funds_at_settle` / `rail_unavailable` — payment-rail failure; adjust amount, recipient, or rail and retry.
* `sender_info_timeout` — sender-info gate timed out; submit with sender details included.
  When `failureCode` is absent the failure has no actionable code — contact support. Order-level failures (including conversion provider unavailability) surface on `order.failed` with a `reasonCode`, not here.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.failed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "type": "withdrawal",
    "source": {
      "type": "wallet",
      "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
      "address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18",
      "assetAmount": {
        "code": "USDC",
        "chain": "ethereum",
        "amount": "100.000000"
      }
    },
    "destination": {
      "type": "external_crypto",
      "address": "0x9abc456789defabcdef0123456789abcdef01234",
      "assetAmount": {
        "code": "USDC",
        "chain": "ethereum",
        "amount": "100.000000"
      }
    },
    "failureCode": "user_signature_declined",
    "failureMessage": "The customer declined the payout from the approval page. No funds were moved.",
    "failedAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field               | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Required | Description                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`     | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Yes      | Unique ID of the failed transaction.                                                                                                                                                                                                                                                                                                                                                        |
| `customerId`        | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Yes      | Customer associated with this transaction.                                                                                                                                                                                                                                                                                                                                                  |
| `clientReferenceId` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                                                                                                                                                                            |
| `type`              | enum: "deposit" \| "onramp" \| "offramp" \| "withdrawal" \| "conversion" \| "deposit\_return"                                                                                                                                                                                                                                                                                                                                                                                                                                                | Yes      | Transaction type. Same value as on `transaction.created`.                                                                                                                                                                                                                                                                                                                                   |
| `source`            | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown)                                                                                                                                                                                                                                                                                                                                                                                | Yes      | Source side of the failed transaction — same nested shape as GET /v2/transactions/:id. Populated even on terminal failures so the payload is self-contained.                                                                                                                                                                                                                                |
| `destination`       | object (one of: wallet, deposit\_address, virtual\_account, external\_crypto, external\_bank, external\_bank\_inbound, internal\_transfer, external\_unknown)                                                                                                                                                                                                                                                                                                                                                                                | Yes      | Destination side of the failed transaction. May surface as `external_unknown` when failure occurred before counterparty resolution.                                                                                                                                                                                                                                                         |
| `failureCode`       | enum: "user\_signature\_timeout" \| "user\_signature\_expired" \| "user\_signature\_declined" \| "user\_signature\_rejected\_by\_provider" \| "crypto\_wallet\_misconfigured" \| "compliance\_hold" \| "compliance\_review\_rejected" \| "compliance\_rejected" \| "returned\_by\_sender" \| "rail\_policy\_rejected" \| "insufficient\_funds" \| "insufficient\_funds\_at\_settle" \| "rail\_unavailable" \| "sender\_info\_timeout" \| "travel\_rule\_rejected" \| "provider\_rejected" \| "chain\_broadcast\_failed" \| "roster\_changed" | No       | Machine-readable failure code identifying the cause (e.g. user\_signature\_timeout, provider\_rejected, travel\_rule\_rejected). Present when the failure has a recoverable cause the integration can act on. When absent, the payout cannot be completed and retrying will not help — contact support if recovery is needed.                                                               |
| `failureMessage`    | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | No       | Human-readable description of `failureCode`. Defaults to the public error catalog text for the code. Sandbox simulators and the counterparty travel-rule channel may pass through the operator/counterparty-supplied reason instead (the counterparty channel applies in both live and sandbox builds; raw provider/compliance text from other vendors is scrubbed at the public boundary). |
| `payout`            | object                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | No       | Payout rail metadata. Present only for outbound transactions.                                                                                                                                                                                                                                                                                                                               |
| `payout.rail`       | enum: "fedwire" \| "rtp" \| "fednow" \| "swift" \| null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Yes      | Fiat payment rail used, if applicable. Null for crypto payouts.                                                                                                                                                                                                                                                                                                                             |
| `failedAt`          | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Yes      | ISO-8601 timestamp when the transaction failed.                                                                                                                                                                                                                                                                                                                                             |
| `linkedOrderId`     | string                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | No       | The Order this transaction belongs to: present on the Conversion an Order executes and on a Withdrawal chained from that Order's autoPayout. Absent on transactions with no Order (deposits, standalone payouts, deposit returns).                                                                                                                                                          |

## transaction.processing

Fired when a payout clears compliance and moves into active processing (signature collection, co-stamp, broadcast). The public status transitions from `pending` to `processing` at the same moment. On a multi-signer non-custodial payout this fires once, before `transaction.awaiting_signature`; the payout may still carry a `queuePosition` while it waits for its per-wallet signing turn.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.processing",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1"
  }
}
```

| Field               | Type   | Required | Description                                      |
| ------------------- | ------ | -------- | ------------------------------------------------ |
| `transactionId`     | string | Yes      | ID of the transaction that entered processing.   |
| `customerId`        | string | Yes      | Customer associated with the transaction.        |
| `clientReferenceId` | string | No       | Caller-supplied external reference, if provided. |

## transaction.quorum\_met

Fired when all required signer stamps are in (`collected >= required`). Compliance already cleared before signing began, so Conduit now co-signs and broadcasts — no further review gate stands between quorum and broadcast.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.quorum_met",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1"
  }
}
```

| Field               | Type   | Required | Description                                       |
| ------------------- | ------ | -------- | ------------------------------------------------- |
| `transactionId`     | string | Yes      | ID of the transaction that reached signer quorum. |
| `customerId`        | string | Yes      | Customer associated with the transaction.         |
| `clientReferenceId` | string | No       | Caller-supplied external reference, if provided.  |

## transaction.rejected

Fired when a compliance reviewer rejects the supporting document on an accepted payout, before execution. Terminal: funds are returned to the available balance. Resubmit a new payout with an acceptable document (see acceptedDocumentTypes) and a fresh idempotency key.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.rejected",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "type": "withdrawal",
    "status": "failed",
    "reasonCategory": "document_inadequate",
    "acceptedDocumentTypes": [
      "bank_verification_letter",
      "invoice",
      "contract",
      "payroll_register",
      "investment_agreement",
      "other"
    ],
    "rejectedAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field                   | Type                                                                                                                                | Required | Description                                                                                                                                                                                                                        |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactionId`         | string                                                                                                                              | Yes      | Unique ID of the rejected payout.                                                                                                                                                                                                  |
| `customerId`            | string                                                                                                                              | Yes      | Customer who initiated this payout.                                                                                                                                                                                                |
| `clientReferenceId`     | string                                                                                                                              | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                   |
| `type`                  | "withdrawal"                                                                                                                        | Yes      | Always `withdrawal` — only payouts are subject to document review.                                                                                                                                                                 |
| `status`                | "failed"                                                                                                                            | Yes      | Public terminal status. Always `failed` on this event; the payout is terminal and funds are returned.                                                                                                                              |
| `reasonCategory`        | enum: "document\_inadequate"                                                                                                        | Yes      | Machine-readable rejection category. `document_inadequate` — the submitted document could not satisfy the compliance requirement.                                                                                                  |
| `acceptedDocumentTypes` | array of enum: "bank\_verification\_letter" \| "invoice" \| "contract" \| "payroll\_register" \| "investment\_agreement" \| "other" | Yes      | Supporting-document types accepted as evidence on a resubmitted payout. Attach a document of one of these types and resubmit with a fresh idempotency key.                                                                         |
| `rejectedAt`            | string                                                                                                                              | Yes      | ISO-8601 timestamp when the document review rejection was recorded.                                                                                                                                                                |
| `linkedOrderId`         | string                                                                                                                              | No       | The Order this transaction belongs to: present on the Conversion an Order executes and on a Withdrawal chained from that Order's autoPayout. Absent on transactions with no Order (deposits, standalone payouts, deposit returns). |

## transaction.signature\_collected

Fired once per signer stamp collected on a multi-signer payout. Track `collected` / `required` to drive a progress UI; once `collected >= required`, `transaction.quorum_met` follows.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "transaction.signature_collected",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "transactionId": "txn_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "clientReferenceId": "ext-payout-1",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "collected": 1,
    "required": 2
  }
}
```

| Field               | Type    | Required | Description                                        |
| ------------------- | ------- | -------- | -------------------------------------------------- |
| `transactionId`     | string  | Yes      | ID of the transaction being signed.                |
| `customerId`        | string  | Yes      | Customer associated with the transaction.          |
| `clientReferenceId` | string  | No       | Caller-supplied external reference, if provided.   |
| `walletSignerId`    | string  | Yes      | ID of the signer whose stamp was just collected.   |
| `collected`         | integer | Yes      | Count of distinct signer stamps gathered so far.   |
| `required`          | integer | Yes      | Total signer stamps required (`signingThreshold`). |

## virtual\_account.activated

Fired when a virtual account is activated

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "virtual_account.activated",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "virtualAccountId": "vac_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "asset": {
      "code": "USD"
    },
    "activatedAt": "2026-01-15T09:30:00.000Z"
  }
}
```

| Field              | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Required | Description                                                |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------- |
| `virtualAccountId` | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Unique ID of the now-active virtual account.               |
| `customerId`       | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Customer who owns this virtual account.                    |
| `asset`            | object                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | Asset this virtual account holds.                          |
| `asset.code`       | enum: "USD" \| "EUR" \| "GBP" \| "CHF" \| "JPY" \| "CAD" \| "AUD" \| "NZD" \| "SGD" \| "HKD" \| "CNY" \| "KRW" \| "INR" \| "BRL" \| "MXN" \| "ARS" \| "CLP" \| "COP" \| "PEN" \| "ZAR" \| "NGN" \| "KES" \| "GHS" \| "EGP" \| "AED" \| "SAR" \| "ILS" \| "TRY" \| "PLN" \| "CZK" \| "HUF" \| "SEK" \| "NOK" \| "DKK" \| "THB" \| "IDR" \| "MYR" \| "PHP" \| "VND" \| "TWD" \| "USDC" \| "USDT" \| "DAI" \| "EURC" \| "PYUSD" \| "BTC" \| "ETH" \| "SOL" \| "TRX" | Yes      | Asset code (USDC, USD, etc.)                               |
| `asset.chain`      | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin"                                                                                                                                                                                                                                                                                                                      | No       | Chain when the asset is on-chain; omitted for fiat         |
| `activatedAt`      | string                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Yes      | ISO-8601 timestamp when the virtual account became active. |

## wallet\_ceremony.awaiting\_admin\_approval

Fired when a non-custodial wallet ceremony (roster add/remove, quorum change) is waiting for a customer admin's passkey co-stamp to reach quorum. Carries `adminVerificationUrl` — the Conduit-hosted approval page to route the admin to — and `expiresAt`, after which the ceremony auto-fails and must be resubmitted. For promote/remove ceremonies this webhook is the only channel that delivers the approval URL. (A passkey signer added to a live roster parks on a separate `wallet_signer.awaiting_admin_approval` event instead.)

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_ceremony.awaiting_admin_approval",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "ceremonyId": "wcy_2xKjF9mQb7vN4hL1pR3w8t",
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "type": "signing_quorum_change",
    "adminVerificationUrl": "https://app.conduit.financial/verify/vtok_2xKjF9mQb7vN4hL1pR3w8t",
    "expiresAt": "2026-01-15T10:30:00.000Z"
  }
}
```

| Field                  | Type                                                                                                                             | Required | Description                                                                                                                                                                                        |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ceremonyId`           | string                                                                                                                           | Yes      | Unique ID of the ceremony awaiting admin approval.                                                                                                                                                 |
| `walletId`             | string                                                                                                                           | Yes      | Wallet associated with this ceremony.                                                                                                                                                              |
| `customerId`           | string                                                                                                                           | Yes      | Customer who owns this wallet.                                                                                                                                                                     |
| `type`                 | enum: "wallet\_create" \| "signing\_quorum\_change" \| "root\_quorum\_update" \| "recovery" \| "roster\_add" \| "roster\_remove" | Yes      | Type of ceremony requiring admin approval.                                                                                                                                                         |
| `adminVerificationUrl` | string \| null                                                                                                                   | Yes      | Conduit-hosted URL to route a customer admin to for the co-stamp. The only delivery channel for promote/remove ceremonies (whose API response carries no URL). Null when a URL cannot be resolved. |
| `expiresAt`            | string                                                                                                                           | Yes      | ISO-8601 deadline — ceremony auto-fails if quorum is not reached by this time.                                                                                                                     |

## wallet\_ceremony.completed

Fired when a non-custodial wallet ceremony completes successfully. All roster or quorum changes requested by the ceremony are now in effect.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_ceremony.completed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "ceremonyId": "wcy_2xKjF9mQb7vN4hL1pR3w8t",
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "type": "signing_quorum_change",
    "status": "completed"
  }
}
```

| Field        | Type                                                                                                                             | Required | Description                                        |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------- |
| `ceremonyId` | string                                                                                                                           | Yes      | Unique ID of the completed ceremony.               |
| `walletId`   | string                                                                                                                           | Yes      | Wallet associated with this ceremony.              |
| `customerId` | string                                                                                                                           | Yes      | Customer who owns this wallet.                     |
| `type`       | enum: "wallet\_create" \| "signing\_quorum\_change" \| "root\_quorum\_update" \| "recovery" \| "roster\_add" \| "roster\_remove" | Yes      | Type of ceremony.                                  |
| `status`     | enum: "completed"                                                                                                                | Yes      | Terminal status. Always `completed` on this event. |

## wallet\_ceremony.failed

Fired when a non-custodial wallet ceremony expires or fails. Any reserved resources have been released. `status` is `failed` on expiry or unrecoverable error; `cancelled` when the ceremony was explicitly cancelled.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_ceremony.failed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "ceremonyId": "wcy_2xKjF9mQb7vN4hL1pR3w8t",
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "type": "signing_quorum_change",
    "status": "failed"
  }
}
```

| Field        | Type                                                                                                                             | Required | Description                                                                                                                                      |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ceremonyId` | string                                                                                                                           | Yes      | Unique ID of the failed ceremony.                                                                                                                |
| `walletId`   | string                                                                                                                           | Yes      | Wallet associated with this ceremony.                                                                                                            |
| `customerId` | string                                                                                                                           | Yes      | Customer who owns this wallet.                                                                                                                   |
| `type`       | enum: "wallet\_create" \| "signing\_quorum\_change" \| "root\_quorum\_update" \| "recovery" \| "roster\_add" \| "roster\_remove" | Yes      | Type of ceremony.                                                                                                                                |
| `status`     | enum: "failed" \| "cancelled"                                                                                                    | Yes      | Terminal failure status. `failed` when the ceremony expired or encountered an unrecoverable error; `cancelled` when it was explicitly cancelled. |

## wallet\_signer.added

Fired when a wallet signer row is created on the roster (immediately at invite time, status pending\_activation) — co-emitted with `wallet_signer.invited` from the same outbox transaction. Distinct from `wallet_signer.invited` (which carries the verification URL) and `wallet_signer.enrolled` (sent later when the signer completes credential enrollment).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.added",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "role": "signer",
    "credentialType": "passkey",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                          | Required | Description                                      |
| ------------------- | ----------------------------- | -------- | ------------------------------------------------ |
| `customerId`        | string                        | Yes      | Customer the signer belongs to.                  |
| `walletSignerId`    | string                        | Yes      | Unique ID of the wallet signer.                  |
| `email`             | string                        | Yes      | Email address of the signer.                     |
| `role`              | enum: "admin" \| "signer"     | Yes      | Roster role of the signer.                       |
| `clientReferenceId` | string                        | No       | Caller-supplied external reference, if provided. |
| `credentialType`    | enum: "passkey" \| "api\_key" | Yes      | Credential type the signer enrolled.             |

## wallet\_signer.awaiting\_admin\_approval

Fired when a passkey signer added to a live roster has enrolled their passkey and now parks for a customer admin's co-stamp. Carries `signerId` + `customerId` (the signer's identity — no walletId, since a signer's roster can back several wallets), `adminVerificationUrl` — the Conduit-hosted approval page to route an admin to — and `expiresAt`, after which the pending add auto-fails. This is the only channel that delivers this admin link; if it is lost, recover it with POST /v2/customers/:customerId/wallet-signers/:signerId/reissue-admin-approval. (A ceremony-backed roster/quorum change instead uses `wallet_ceremony.awaiting_admin_approval`.)

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.awaiting_admin_approval",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "signerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "adminVerificationUrl": "https://app.conduit.financial/verify/vtok_2xKjF9mQb7vN4hL1pR3w8t",
    "expiresAt": "2026-01-15T10:30:00.000Z"
  }
}
```

| Field                  | Type           | Required | Description                                                                                                                                                                                           |
| ---------------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signerId`             | string         | Yes      | The signer whose passkey add to a live roster is awaiting a customer admin's co-stamp. Pass it to POST /v2/customers/:customerId/wallet-signers/:signerId/reissue-admin-approval to recover the link. |
| `customerId`           | string         | Yes      | Customer who owns the signer. The signer is identified by `signerId` + `customerId`; this topic carries no walletId — a signer's roster can back several wallets, so no single wallet applies.        |
| `adminVerificationUrl` | string \| null | Yes      | Conduit-hosted URL to route a customer admin to for the co-stamp. Null when a URL cannot be resolved.                                                                                                 |
| `expiresAt`            | string         | Yes      | ISO-8601 deadline — the pending approval auto-fails if it is not co-stamped by this time.                                                                                                             |

## wallet\_signer.demoted

Fired when an admin is demoted to signer via the two-step demote ceremony (root-quorum update + tag update). Validates min-2-admins floor before starting.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.demoted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "role": "signer",
    "previousRole": "admin",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                      | Required | Description                                      |
| ------------------- | ------------------------- | -------- | ------------------------------------------------ |
| `customerId`        | string                    | Yes      | Customer the signer belongs to.                  |
| `walletSignerId`    | string                    | Yes      | Unique ID of the wallet signer.                  |
| `email`             | string                    | Yes      | Email address of the signer.                     |
| `role`              | enum: "admin" \| "signer" | Yes      | Roster role of the signer.                       |
| `clientReferenceId` | string                    | No       | Caller-supplied external reference, if provided. |
| `previousRole`      | "admin"                   | Yes      | Role the signer held before demotion.            |

## wallet\_signer.enrolled

Fired when a wallet signer completes credential enrollment via the verification URL. `passkeyCount` reflects the number of passkeys registered for passkey signers.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.enrolled",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "role": "signer",
    "passkeyCount": 1,
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                      | Required | Description                                                                             |
| ------------------- | ------------------------- | -------- | --------------------------------------------------------------------------------------- |
| `customerId`        | string                    | Yes      | Customer the signer belongs to.                                                         |
| `walletSignerId`    | string                    | Yes      | Unique ID of the wallet signer.                                                         |
| `email`             | string                    | Yes      | Email address of the signer.                                                            |
| `role`              | enum: "admin" \| "signer" | Yes      | Roster role of the signer.                                                              |
| `clientReferenceId` | string                    | No       | Caller-supplied external reference, if provided.                                        |
| `passkeyCount`      | integer                   | No       | Number of passkeys the signer has enrolled. Present when `credentialType` is `passkey`. |

## wallet\_signer.enrollment\_approved

Fired when a customer admin's co-stamp approves a signer's credential ceremony — a newcomer's first passkey, or an existing signer adding a device. The post-approval counterpart to `wallet_ceremony.awaiting_admin_approval`. Carries `approvedByWalletSignerId` (the approving admin) and `approvedAt`. Distinct from `wallet_signer.enrolled`, which fires when the signer submits their credential; this fires only once the admin approves it.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.enrollment_approved",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "role": "signer",
    "credentialType": "passkey",
    "approvedByWalletSignerId": "wsg_9aLmN2pQr5sT8uV1wX4yZ7",
    "approvedAt": "2026-01-15T10:32:00.000Z",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field                      | Type                          | Required | Description                                                                                                                   |
| -------------------------- | ----------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `customerId`               | string                        | Yes      | Customer the signer belongs to.                                                                                               |
| `walletSignerId`           | string                        | Yes      | Unique ID of the wallet signer.                                                                                               |
| `email`                    | string                        | Yes      | Email address of the signer.                                                                                                  |
| `role`                     | enum: "admin" \| "signer"     | Yes      | Roster role of the signer.                                                                                                    |
| `clientReferenceId`        | string                        | No       | Caller-supplied external reference, if provided.                                                                              |
| `credentialType`           | enum: "passkey" \| "api\_key" | Yes      | Credential type the newcomer enrolled.                                                                                        |
| `approvedByWalletSignerId` | string \| null                | Yes      | Wallet-signer ID of the admin whose co-stamp approved the newcomer's credential. Null when attribution could not be resolved. |
| `approvedAt`               | string                        | Yes      | ISO-8601 timestamp when the admin approved the credential.                                                                    |

## wallet\_signer.invited

Fired when a wallet signer is invited to enroll their credential. Payload carries the per-signer enrollment verificationUrl the fintech distributes out-of-band, plus expiresAt — after which the invitation auto-expires.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.invited",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "name": "Jane Doe",
    "role": "signer",
    "credentialType": "passkey",
    "verificationUrl": "https://app.conduit.financial/verify/vtok_3yLkG0nRc8wO5iM2qS4x9u",
    "expiresAt": "2026-01-22T09:30:00.000Z",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                          | Required | Description                                                                                                          |
| ------------------- | ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `customerId`        | string                        | Yes      | Customer the signer belongs to.                                                                                      |
| `walletSignerId`    | string                        | Yes      | Unique ID of the wallet signer.                                                                                      |
| `email`             | string                        | Yes      | Email address of the signer.                                                                                         |
| `role`              | enum: "admin" \| "signer"     | Yes      | Roster role of the signer.                                                                                           |
| `clientReferenceId` | string                        | No       | Caller-supplied external reference, if provided.                                                                     |
| `name`              | string                        | No       | Display name of the signer, if provided at invite time.                                                              |
| `credentialType`    | enum: "passkey" \| "api\_key" | Yes      | Credential type the signer will enroll.                                                                              |
| `verificationUrl`   | string                        | Yes      | Conduit-hosted enrollment URL the fintech routes the signer to. One URL per invited signer, distributed out-of-band. |
| `expiresAt`         | string                        | Yes      | ISO-8601 deadline — the invitation auto-expires if the signer has not enrolled by this time.                         |

## wallet\_signer.promoted

Fired when a wallet signer is promoted to admin via the two-step promote ceremony (tag update + root-quorum update). A passkey admin must have at least 2 passkeys enrolled; a machine (api\_key) admin needs none and is allowed only in the fully-automated signing mode.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.promoted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "admin@example.com",
    "role": "admin",
    "previousRole": "signer",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                      | Required | Description                                      |
| ------------------- | ------------------------- | -------- | ------------------------------------------------ |
| `customerId`        | string                    | Yes      | Customer the signer belongs to.                  |
| `walletSignerId`    | string                    | Yes      | Unique ID of the wallet signer.                  |
| `email`             | string                    | Yes      | Email address of the signer.                     |
| `role`              | enum: "admin" \| "signer" | Yes      | Roster role of the signer.                       |
| `clientReferenceId` | string                    | No       | Caller-supplied external reference, if provided. |
| `previousRole`      | "signer"                  | Yes      | Role the signer held before promotion.           |

## wallet\_signer.removed

Fired when a wallet signer is removed from the roster. `reason` discriminates between customer-initiated removal (`customer_removed`) and internal ops removal (`ops_removed`). Pending payouts carrying the removed signer's stamp are voided with failureCode roster\_changed.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet_signer.removed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "walletSignerId": "wsg_2xKjF9mQb7vN4hL1pR3w8t",
    "email": "signer@example.com",
    "role": "signer",
    "reason": "customer_removed",
    "clientReferenceId": "ext-signer-001"
  }
}
```

| Field               | Type                                                          | Required | Description                                                                                                                                                                                                                                 |
| ------------------- | ------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customerId`        | string                                                        | Yes      | Customer the signer belongs to.                                                                                                                                                                                                             |
| `walletSignerId`    | string                                                        | Yes      | Unique ID of the wallet signer.                                                                                                                                                                                                             |
| `email`             | string                                                        | Yes      | Email address of the signer.                                                                                                                                                                                                                |
| `role`              | enum: "admin" \| "signer"                                     | Yes      | Roster role of the signer.                                                                                                                                                                                                                  |
| `clientReferenceId` | string                                                        | No       | Caller-supplied external reference, if provided.                                                                                                                                                                                            |
| `reason`            | enum: "customer\_removed" \| "ops\_removed" \| "claim\_reset" | Yes      | Why the signer was removed: `customer_removed` — a customer admin removed them via a roster ceremony; `ops_removed` — an internal ops action; `claim_reset` — the customer's entire crypto-wallet claim was reset, tearing down the roster. |

## wallet.created

Fired when a crypto wallet is created. Not delivered for the Conduit-managed funding address behind a deposit-funded order — that address is not a wallet resource, and the order's `depositInstructions` publishes it instead.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet.created",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "chain": "ethereum",
    "address": "0x742d35cc6634c0532925a3b8d4c9c2c7a3b3d7e1",
    "custodyModel": "custodial",
    "clientReferenceId": "ext-wallet-001"
  }
}
```

| Field               | Type                                                                                                                                        | Required | Description                                                                                                                                                                                                                 |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `walletId`          | string                                                                                                                                      | Yes      | Unique ID of the newly created wallet.                                                                                                                                                                                      |
| `customerId`        | string                                                                                                                                      | Yes      | Customer who owns this wallet.                                                                                                                                                                                              |
| `chain`             | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin" | Yes      | Blockchain network this wallet operates on.                                                                                                                                                                                 |
| `address`           | string                                                                                                                                      | Yes      | On-chain address of the wallet.                                                                                                                                                                                             |
| `custodyModel`      | enum: "non\_custodial" \| "custodial"                                                                                                       | No       | Which side holds the signing key. `custodial` — Conduit signs on the customer's behalf; `non_custodial` — the customer co-signs each payout via the verify URL. Omitted when the custody model has not yet been determined. |
| `clientReferenceId` | string                                                                                                                                      | No       | Caller-supplied external reference, if provided.                                                                                                                                                                            |

## wallet.deleted

Fired when a crypto wallet is deleted (currently only via a crypto-wallet claim reset). Integrators mirroring wallet state must remove the corresponding record. Not delivered for a Conduit-managed deposit address, whose creation was never announced either.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet.deleted",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "chain": "ethereum",
    "address": "0x742d35cc6634c0532925a3b8d4c9c2c7a3b3d7e1",
    "reason": "claim_reset",
    "clientReferenceId": "ext-wallet-001"
  }
}
```

| Field               | Type                                                                                                                                        | Required | Description                                                                                                                                                                                        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `walletId`          | string                                                                                                                                      | Yes      | Unique ID of the deleted wallet.                                                                                                                                                                   |
| `customerId`        | string                                                                                                                                      | Yes      | Customer who owned this wallet.                                                                                                                                                                    |
| `chain`             | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin" | Yes      | Blockchain network this wallet operated on.                                                                                                                                                        |
| `address`           | string                                                                                                                                      | Yes      | On-chain address of the deleted wallet.                                                                                                                                                            |
| `reason`            | enum: "claim\_reset"                                                                                                                        | Yes      | Why the wallet was deleted. `claim_reset` — the customer's crypto-wallet claim was reset, removing every wallet and signer. Integrators mirroring wallet state must drop the corresponding record. |
| `clientReferenceId` | string                                                                                                                                      | No       | Caller-supplied external reference, if provided.                                                                                                                                                   |

## wallet.rotated

Fired when a crypto wallet is rotated. Not delivered for the Conduit-managed funding address behind a deposit-funded order: Conduit may replace that address at any time without notice, so read it off each order rather than tracking it per customer.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet.rotated",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "replacedByWalletId": "wlt_3yLkG0nRc8wO5iM2qS4x9u",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "chain": "ethereum",
    "custodyModel": "non_custodial",
    "rotatedAt": "2026-01-15T09:30:00.000Z",
    "clientReferenceId": "ext-wallet-001"
  }
}
```

| Field                | Type                                                                                                                                        | Required | Description                                                                                                                                                                                |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `walletId`           | string                                                                                                                                      | Yes      | Unique ID of the wallet that was rotated (now inactive).                                                                                                                                   |
| `replacedByWalletId` | string                                                                                                                                      | Yes      | Unique ID of the new wallet that replaced this one.                                                                                                                                        |
| `customerId`         | string                                                                                                                                      | Yes      | Customer who owns this wallet.                                                                                                                                                             |
| `chain`              | enum: "ethereum" \| "base" \| "solana" \| "polygon" \| "arbitrum" \| "optimism" \| "avalanche" \| "tron" \| "stellar" \| "bsc" \| "bitcoin" | Yes      | Blockchain network this wallet operates on.                                                                                                                                                |
| `custodyModel`       | enum: "non\_custodial" \| "custodial"                                                                                                       | No       | Which side holds the signing key on the replacement wallet (`replacedByWalletId`). `custodial` — Conduit signs; `non_custodial` — the customer co-signs each payout. Omitted when unknown. |
| `rotatedAt`          | string                                                                                                                                      | Yes      | ISO-8601 timestamp when the wallet was rotated.                                                                                                                                            |
| `clientReferenceId`  | string                                                                                                                                      | No       | Caller-supplied external reference, if provided.                                                                                                                                           |

## wallet.threshold\_changed

Fired when a wallet's signing threshold changes — the number of admin stamps required to authorize a payout. Triggered by a completed SIGNING\_QUORUM\_CHANGE ceremony or an operator quorum override.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "wallet.threshold_changed",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "walletId": "wlt_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "threshold": 2
  }
}
```

| Field        | Type    | Required | Description                                                                    |
| ------------ | ------- | -------- | ------------------------------------------------------------------------------ |
| `walletId`   | string  | Yes      | Wallet whose signing threshold changed.                                        |
| `customerId` | string  | Yes      | Customer who owns this wallet.                                                 |
| `threshold`  | integer | Yes      | New signing threshold (number of admin stamps required to authorize a payout). |

## whitelist\_recipient.registered

Fired when compliance approves a pending intercompany whitelist registration. The recipient can now receive purpose=intercompany payouts for this customer.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "whitelist_recipient.registered",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "whitelistRecipientId": "wlr_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "rail": "us",
    "relationship": "group_entity",
    "status": "registered",
    "holderName": "Acme Treasury Inc",
    "label": "acme-us-treasury"
  }
}
```

| Field                  | Type                                                                              | Required | Description                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `whitelistRecipientId` | string                                                                            | Yes      | Unique ID of the whitelist recipient entry.                                                                                    |
| `customerId`           | string                                                                            | Yes      | Customer who owns this whitelist entry.                                                                                        |
| `rail`                 | enum: "us" \| "swift"                                                             | Yes      | Payment rail for this whitelist entry (us or swift).                                                                           |
| `relationship`         | enum: "self" \| "group\_entity"                                                   | Yes      | Intercompany relationship between the customer and the recipient.                                                              |
| `status`               | enum: "pending\_review" \| "registered" \| "suspended" \| "revoked" \| "rejected" | Yes      | Current status of the whitelist entry. Matches the `status` field on `GET /v2/customers/:customerId/whitelist-recipients/:id`. |
| `holderName`           | string                                                                            | Yes      | Legal name of the account holder.                                                                                              |
| `label`                | string \| null                                                                    | Yes      | Optional caller-assigned label for this entry.                                                                                 |

## whitelist\_recipient.rejected

Fired when compliance rejects a pending registration.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "whitelist_recipient.rejected",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "whitelistRecipientId": "wlr_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "rail": "us",
    "relationship": "group_entity",
    "status": "rejected",
    "holderName": "Acme Treasury Inc",
    "label": "acme-us-treasury"
  }
}
```

| Field                  | Type                                                                              | Required | Description                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `whitelistRecipientId` | string                                                                            | Yes      | Unique ID of the whitelist recipient entry.                                                                                    |
| `customerId`           | string                                                                            | Yes      | Customer who owns this whitelist entry.                                                                                        |
| `rail`                 | enum: "us" \| "swift"                                                             | Yes      | Payment rail for this whitelist entry (us or swift).                                                                           |
| `relationship`         | enum: "self" \| "group\_entity"                                                   | Yes      | Intercompany relationship between the customer and the recipient.                                                              |
| `status`               | enum: "pending\_review" \| "registered" \| "suspended" \| "revoked" \| "rejected" | Yes      | Current status of the whitelist entry. Matches the `status` field on `GET /v2/customers/:customerId/whitelist-recipients/:id`. |
| `holderName`           | string                                                                            | Yes      | Legal name of the account holder.                                                                                              |
| `label`                | string \| null                                                                    | Yes      | Optional caller-assigned label for this entry.                                                                                 |

## whitelist\_recipient.revoked

Fired when an entry is revoked (terminal; client-initiated or compliance action).

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "whitelist_recipient.revoked",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "whitelistRecipientId": "wlr_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "rail": "us",
    "relationship": "group_entity",
    "status": "revoked",
    "holderName": "Acme Treasury Inc",
    "label": "acme-us-treasury"
  }
}
```

| Field                  | Type                                                                              | Required | Description                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `whitelistRecipientId` | string                                                                            | Yes      | Unique ID of the whitelist recipient entry.                                                                                    |
| `customerId`           | string                                                                            | Yes      | Customer who owns this whitelist entry.                                                                                        |
| `rail`                 | enum: "us" \| "swift"                                                             | Yes      | Payment rail for this whitelist entry (us or swift).                                                                           |
| `relationship`         | enum: "self" \| "group\_entity"                                                   | Yes      | Intercompany relationship between the customer and the recipient.                                                              |
| `status`               | enum: "pending\_review" \| "registered" \| "suspended" \| "revoked" \| "rejected" | Yes      | Current status of the whitelist entry. Matches the `status` field on `GET /v2/customers/:customerId/whitelist-recipients/:id`. |
| `holderName`           | string                                                                            | Yes      | Legal name of the account holder.                                                                                              |
| `label`                | string \| null                                                                    | Yes      | Optional caller-assigned label for this entry.                                                                                 |

## whitelist\_recipient.suspended

Fired when an active entry is suspended — it no longer satisfies intercompany payouts.

```json theme={null}
{
  "id": "evt_2xKjF9mQb7vN4hL1pR3w8t",
  "type": "whitelist_recipient.suspended",
  "createdAt": "2026-01-15T09:30:00.000Z",
  "apiVersion": "2",
  "mode": "live",
  "data": {
    "whitelistRecipientId": "wlr_2xKjF9mQb7vN4hL1pR3w8t",
    "customerId": "cus_2xKjF9mQb7vN4hL1pR3w8t",
    "rail": "us",
    "relationship": "group_entity",
    "status": "suspended",
    "holderName": "Acme Treasury Inc",
    "label": "acme-us-treasury"
  }
}
```

| Field                  | Type                                                                              | Required | Description                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `whitelistRecipientId` | string                                                                            | Yes      | Unique ID of the whitelist recipient entry.                                                                                    |
| `customerId`           | string                                                                            | Yes      | Customer who owns this whitelist entry.                                                                                        |
| `rail`                 | enum: "us" \| "swift"                                                             | Yes      | Payment rail for this whitelist entry (us or swift).                                                                           |
| `relationship`         | enum: "self" \| "group\_entity"                                                   | Yes      | Intercompany relationship between the customer and the recipient.                                                              |
| `status`               | enum: "pending\_review" \| "registered" \| "suspended" \| "revoked" \| "rejected" | Yes      | Current status of the whitelist entry. Matches the `status` field on `GET /v2/customers/:customerId/whitelist-recipients/:id`. |
| `holderName`           | string                                                                            | Yes      | Legal name of the account holder.                                                                                              |
| `label`                | string \| null                                                                    | Yes      | Optional caller-assigned label for this entry.                                                                                 |
