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

# Payloads

> Webhook payload schema and sample events for every transaction type

## Payload structure

Every webhook has the same envelope. Transaction details live under `data`. The envelope below shows every field that *can* appear — only the fields applicable to a given transaction are actually present (see the note).

```json theme={null}
{
  "event": "transaction.completed",
  "event_id": "8f2a1c44-9b3e-5d61-a2f7-1e9c0b4d6a55",
  "created_at": "2026-06-10T12:00:05.000Z",
  "data": {
    "transaction_id": "…",
    "reference": "…",
    "type": "deposit | payout",
    "status": "pending | processing | sent | completed | failed | rejected | refunded",
    "rail": "fiat | stablecoin",
    "currency": "…",
    "amount": 0,
    "source_amount": 0,
    "source_currency": "…",
    "destination_amount": 0,
    "destination_currency": "…",
    "exchange_rate": 0,
    "fee_amount": 0,
    "fee_transaction_id": "…",
    "fee_reference": "…",
    "description": "…",
    "timestamp": "…",
    "beneficiary": { },
    "network": { },
    "metadata": { }
  }
}
```

<Info>
  The payload carries **only the fields relevant to the transaction** — inapplicable fields are **omitted entirely, not returned as `null`**. This applies at every level: a fiat bank payout has no `network`, `exchange_rate`, `wallet_address` or `wallet_chain`; a crypto payout has no bank fields; a deposit has no `beneficiary`. So a field's **absence** simply means it doesn't apply. The only exception is `metadata`, which is passed through exactly as you supplied it. Match transactions by `transaction_id` (or `reference`), and treat any missing field as not applicable.
</Info>

### Field reference

| Field                                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`                                                 | Event type — see [Events](/api-reference/webhooks/events)                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `event_id`                                              | Stable id for the logical event (use to deduplicate)                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `created_at`                                            | When the event was generated (ISO 8601)                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `data.transaction_id`                                   | Rolla transaction id                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `data.reference`                                        | Transaction reference (the external reference)                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `data.type`                                             | `deposit` or `payout`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `data.status`                                           | The transaction status this event represents — one of `pending`, `processing`, `sent`, `completed`, `failed`, `rejected`, `refunded` (matches the `event` type). See [Events](/api-reference/webhooks/events)                                                                                                                                                                                                                                                                                              |
| `data.rail`                                             | `fiat` or `stablecoin`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `data.amount` / `data.currency`                         | The **net** amount the counterparty receives (in **minor units** — see [Amount format](#amount-format)), and its currency — a deposit's credited amount, or a payout's amount to the beneficiary. Equals `destination_amount`.                                                                                                                                                                                                                                                                             |
| `data.source_amount` / `data.source_currency`           | The debit leg, in **minor units**; for FX it's the source-currency amount. For a **payout** this is normally the **gross** amount, i.e. `amount` **+ fee** — but **not** when the fee is charged to a separate account rather than deducted from the payout (see [Fees paid by another account](#fees-paid-by-another-account)), in which case `source_amount` equals `amount` and the fee sits on its own transaction. **Never derive the fee as `source_amount − amount`** — read `fee_amount` directly. |
| `data.destination_amount` / `data.destination_currency` | The credit leg, in **minor units** — what the beneficiary/wallet actually receives.                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `data.exchange_rate`                                    | The effective rate for the conversion, computed as `destination_amount / source_amount` (destination per source, in minor units) — the same convention as the external [transactions API](/api-reference/endpoint/transactions). Present only for **FX** transactions (source and destination currencies differ); **omitted** otherwise.                                                                                                                                                                   |
| `data.fee_amount`                                       | Fee applied, in **minor units**. Always the authoritative fee for the transaction, whichever account pays it.                                                                                                                                                                                                                                                                                                                                                                                              |
| `data.fee_transaction_id` / `data.fee_reference`        | The id and reference (`FEE-XXXXXXXX`) of the separate transaction the fee was booked as, when the fee is charged to another account rather than deducted from this one. **Both omitted** when no separate fee transaction exists, which is the ordinary case — treat them as optional. See [Fees paid by another account](#fees-paid-by-another-account).                                                                                                                                                  |
| `data.beneficiary`                                      | Beneficiary details — present for **payouts**, **omitted** otherwise (see below). Only fields relevant to the payout are included.                                                                                                                                                                                                                                                                                                                                                                         |
| `data.virtual_account`                                  | The destination virtual account a **deposit** was paid into — present for **deposits**, **omitted** for payouts. Lets you reconcile the deposit to a specific account. Same shape as the [`account.virtual_account.created`](/api-reference/webhooks/events) payload (see below).                                                                                                                                                                                                                          |
| `data.payer`                                            | The sender/originator of a **deposit** — present for **deposits** when the provider supplies sender details, **omitted** for payouts. See below for availability by rail.                                                                                                                                                                                                                                                                                                                                  |
| `data.network`                                          | On-chain details — present only for genuinely **on-chain** transactions (a real chain and/or wallet address). `chain` is the full network name (`Solana`); `tx_hash` is the on-chain transaction hash. **Omitted** for transactions with no on-chain leg — including stablecoin-funded payouts that settle to a fiat bank (e.g. a USDT → USD wire).                                                                                                                                                        |
| `data.customer_identifier`                              | Present **only** for deposits into a **customer** (per-end-user) virtual account — the identifier you set when creating the account via [Generate Customer Virtual Account](/api-reference/endpoint/wallet/virtual-accounts-generate-customer). Use it to attribute the deposit to the specific end-user the account belongs to. **Omitted** for every other transaction (regular deposits and all payouts).                                                                                               |
| `data.metadata`                                         | Any metadata you supplied when creating the transaction                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

### Amount format

All monetary fields — **`amount`**, **`source_amount`**, **`destination_amount`**, and **`fee_amount`** — are integers equal to the **major-currency value × 100** (two implied decimal places). This is the same scale for **every currency**, fiat and stablecoin alike — to get the human-readable amount, always **divide by 100**.

| Currency | Minor unit    | Major → minor        |
| -------- | ------------- | -------------------- |
| NGN      | kobo (1/100)  | ₦100 → `10000`       |
| USD      | cents (1/100) | \$100 → `10000`      |
| XAF      | 1/100         | 1,000 XAF → `100000` |
| USDC     | 1/100         | 100 USDC → `10000`   |
| USDT     | 1/100         | 100 USDT → `10000`   |

To display a value, divide by 100 (e.g. `amount / 100`) for any currency.

<Warning>
  These values are **not** major units. An `amount` of `10000` on an NGN transaction means **₦100.00**, not ₦10,000, and `10000` on a USDC transaction means **100.00 USDC**. Treating the integer as a major amount will overstate it by 100×.
</Warning>

<Note>
  **Webhook amounts differ from the REST transaction endpoints.** Webhook payloads report amounts as **major × 100** (e.g. `1000` = $10.00). The REST transaction responses — `GET /wallet/transactions`, `GET /wallet/transaction/{id}`, and the `withdraw` / `transfer` / `swap` responses — report transaction amounts in **major units** (e.g. `10` = $10.00). So the same transaction shows `1000` in its webhook and `10` over REST. Match a webhook to a REST record by **`transaction_id`** (or `reference`), not by comparing raw amounts, and apply the right scale for each source.
</Note>

<Tip>
  For a payout, **`amount`** is what you asked to send (the beneficiary's amount). **`source_amount`** is what's debited from the paying wallet. Where the fee is deducted from the payout itself, that means `source_amount = amount + fee_amount`. Where the fee is charged to a different account, `source_amount = amount` and the fee is debited separately — see below. Either way, **`fee_amount` is the fee**; don't compute it from the other two. All scaled by 100.
</Tip>

### Fees paid by another account

Your account can be configured so that fees on transactions are charged to a different account of yours rather than deducted from each transaction. When that applies, the fee is booked as its **own transaction** on the paying account, and the payout carries a link to it:

| Field                     | Meaning                                   |
| ------------------------- | ----------------------------------------- |
| `data.fee_transaction_id` | Id of the fee transaction                 |
| `data.fee_reference`      | Its reference, in the form `FEE-XXXXXXXX` |

```json theme={null}
{
  "amount": 10,
  "source_amount": 10,
  "fee_amount": 200,
  "fee_transaction_id": "358f2c4a-4b86-4806-a502-c2b98866b831",
  "fee_reference": "FEE-9J76UADV"
}
```

Three things to know when reconciling:

* **The fee does not arrive as its own webhook.** Only deposits and payouts emit webhooks — fee transactions never do. The link above is the only notification you receive.
* **`source_amount` excludes the fee here**, because the fee never touched this transaction. It equals `amount`.
* **On the fee transaction itself, `fee_amount` is `0`** and the fee value is carried as its `source_amount` / `destination_amount`. This keeps the fee from being counted twice when totalling `fee_amount` across transactions. Read the fee from the payout's `fee_amount`.

Looking the fee transaction up over REST (`GET /wallet/transactions`) returns it with `related_transaction_id` and `related_reference` pointing back at the payout, so you can reconcile from either direction.

<Note>
  Both fields are **omitted entirely** — not `null` — when no separate fee transaction exists. Branch on their presence. They were introduced on **18 August 2026**; webhooks you captured before then do not carry them even where a fee transaction exists.
</Note>

### The `beneficiary` object (payouts)

Drawn from this whitelisted set — but only the fields **relevant to the payout** are returned. Empty/`null` fields are omitted, so a fiat bank payout returns bank-account fields (no wallet fields), while a crypto payout returns wallet fields (no bank fields). Internal fields (your `business_id`, row timestamps) are never included.

`id` · `account_name` · `account_number` · `bank_name` · `bank_code` · `bank_address` · `currency` · `withdrawal_method` · `routing_number` · `swift_code` · `iban` · `bic` · `sort_code` · `intermediary_bank_name` · `intermediary_bank_routing_number` · `wallet_address` · `wallet_chain` · `email` · `contact_person` · `label` · `beneficiary_address`

<Note>
  `wallet_chain` is the full network name (`Solana`). Inside `bank_address` / `beneficiary_address`, `country` is the full country name (e.g. `Côte d'Ivoire`, not `CI`). **A present `id` means the payout went to a saved beneficiary** (it's the beneficiary's UUID). One-time (inline) beneficiaries have **no `id` field at all** — use its absence to detect them.
</Note>

### The `virtual_account` object (deposits)

The destination account a deposit was received into. For a bank (fiat) deposit: `id` (the virtual account's Rolla id), `currency`, `method` (`bank_transfer`), `provider`, `bank_name`, `account_number`, `account_name`, and — when the account has them — `routing_number` / `swift_code`. For a stablecoin deposit: `id`, `currency`, `method` (`crypto`), `provider`, `wallet_address`, `network`. Empty fields are omitted.

### The `payer` object (deposits)

Who sent the deposit, as reported by the provider. Fields: `name`, `account_number`, `bank_name`, `country` — only the ones the provider supplies are included, so availability varies by rail:

* **USD** — always `name` and `account_number`; `bank_name` and `country` are included when the
  sending rail reports them.

`payer` is **omitted** when the provider sends no sender details. Crypto deposits expose the sender via the `network.source_address` field instead of `payer`.

***

## Sample: Fiat deposit completed

```json theme={null}
{
  "event": "transaction.completed",
  "event_id": "0a7b5e21-3c44-5f88-9a1d-77c2e6b0f312",
  "created_at": "2026-06-10T12:00:05.000Z",
  "data": {
    "transaction_id": "866b7abd-6cac-40f2-a04f-d6e58bf47d04",
    "reference": "NG-DEP-9F2K1A",
    "type": "deposit",
    "status": "completed",
    "rail": "fiat",
    "currency": "NGN",
    "amount": 500000,
    "source_amount": 500000,
    "source_currency": "NGN",
    "destination_amount": 500000,
    "destination_currency": "NGN",
    "fee_amount": 0,
    "description": "Deposit from John Doe",
    "timestamp": "2026-06-10T12:00:04.812Z",
    "virtual_account": {
      "id": "2b0f3d84-8c1a-4c7e-9f0b-1a2b3c4d5e6f",
      "currency": "NGN",
      "method": "bank_transfer",
      "bank_name": "GTBank",
      "account_number": "0123456789",
      "account_name": "Acme Ltd / Rolla"
    },
    "payer": {
      "name": "John Doe",
      "account_number": "1234567890",
      "bank_name": "Access Bank"
    }
  }
}
```

***

## Sample: Deposit into a customer virtual account

Same shape as a fiat deposit, plus **`customer_identifier`** — the identifier you set when creating the account, so you can credit the right end-user. Only deposits into a [customer virtual account](/api-reference/endpoint/wallet/virtual-accounts-generate-customer) include it.

```json theme={null}
{
  "event": "transaction.completed",
  "event_id": "1b8c6f32-4d55-6a99-8b2e-88d3f7c1a423",
  "created_at": "2026-06-10T12:05:07.000Z",
  "data": {
    "transaction_id": "9a2f3c40-7b1d-42e8-9c04-e1f6a2b58c19",
    "reference": "API-VACT_TRA-2DC75-4499d21f",
    "type": "deposit",
    "status": "completed",
    "rail": "fiat",
    "currency": "NGN",
    "amount": 49000,
    "source_amount": 50000,
    "source_currency": "NGN",
    "destination_amount": 49000,
    "destination_currency": "NGN",
    "fee_amount": 1000,
    "description": "Deposit from John Doe",
    "timestamp": "2026-06-10T12:05:06.500Z",
    "virtual_account": {
      "id": "7d1e9a52-3f44-4b88-a0c2-9e8f7d6c5b4a",
      "currency": "NGN",
      "method": "bank_transfer",
      "bank_name": "GTBank",
      "account_number": "9988776655",
      "account_name": "End User / Rolla"
    },
    "payer": {
      "name": "John Doe",
      "account_number": "1234567890",
      "bank_name": "Access Bank"
    },
    "customer_identifier": "user-12345"
  }
}
```

***

## Sample: Fiat payout completed

```json theme={null}
{
  "event": "transaction.completed",
  "event_id": "1b8c6f32-4d55-5a99-8b2e-88d3f7c1a423",
  "created_at": "2026-06-10T12:01:10.000Z",
  "data": {
    "transaction_id": "a1f2e3d4-5b6c-7d8e-9f01-23456789abcd",
    "reference": "NG-NFNUJTUW",
    "type": "payout",
    "status": "completed",
    "rail": "fiat",
    "currency": "NGN",
    "amount": 100000,
    "source_amount": 102500,
    "source_currency": "NGN",
    "destination_amount": 100000,
    "destination_currency": "NGN",
    "fee_amount": 2500,
    "description": "Vendor payment",
    "timestamp": "2026-06-10T12:01:09.500Z",
    "beneficiary": {
      "id": "b9f1c2d3-4e5a-6b7c-8d9e-0f1a2b3c4d5e",
      "account_name": "Jane Smith",
      "account_number": "0123456789",
      "bank_name": "Access Bank",
      "bank_code": "000014",
      "currency": "NGN",
      "withdrawal_method": "local_transfer"
    },
    "metadata": { "invoice_id": "INV-2026-042" }
  }
}
```

***

## Sample: FX payout (NGN → USD) pending

A cross-currency payout. `exchange_rate` is populated (the quoted rate for the pair), and the wire beneficiary's `bank_address.country` is the full country name. Only the bank-relevant beneficiary fields are present.

```json theme={null}
{
  "event": "transaction.pending",
  "event_id": "07c97239-a8b0-5579-bd5e-e3221f614173",
  "created_at": "2026-06-10T12:05:00.000Z",
  "data": {
    "transaction_id": "9a56d01f-dc72-4ace-bbbc-a237bdb1c599",
    "reference": "NG-D7NUAS9Q",
    "type": "payout",
    "status": "pending",
    "rail": "fiat",
    "currency": "USD",
    "amount": 100000,
    "source_amount": 160000000,
    "source_currency": "NGN",
    "destination_amount": 100000,
    "destination_currency": "USD",
    "exchange_rate": 0.000625,
    "fee_amount": 250000,
    "description": "FX Payout",
    "timestamp": "2026-06-10T12:04:59.500Z",
    "beneficiary": {
      "id": "79ee09c0-1518-4a5c-86c7-d880a78ec6e5",
      "account_name": "Fatunde Tee",
      "account_number": "0711348929",
      "bank_name": "Bank Of America",
      "routing_number": "026009593",
      "currency": "USD",
      "withdrawal_method": "domestic_wire",
      "bank_address": {
        "street": "17 Akintunde Close",
        "city": "New York",
        "state": "New York",
        "postalCode": "12222",
        "country": "United States"
      }
    }
  }
}
```

<Note>
  Here `exchange_rate` is `destination_amount / source_amount` = `100000 / 160000000` = `0.000625` (USD minor units per NGN minor unit). Use `source_amount` and `destination_amount` for exact reconciliation — they are the authoritative debit and credit legs in minor units.
</Note>

***

## Sample: Stablecoin deposit completed

```json theme={null}
{
  "event": "transaction.completed",
  "event_id": "2c9d7a43-5e66-5baa-9c3f-99e4a8d2b534",
  "created_at": "2026-06-10T12:02:30.000Z",
  "data": {
    "transaction_id": "b2c3d4e5-6f70-8192-a3b4-c5d6e7f80912",
    "reference": "5h2k...onchain-signature",
    "type": "deposit",
    "status": "completed",
    "rail": "stablecoin",
    "currency": "USDC",
    "amount": 100000,
    "source_amount": 100000,
    "source_currency": "USDC",
    "destination_amount": 100000,
    "destination_currency": "USDC",
    "fee_amount": 0,
    "description": "USDC deposit",
    "timestamp": "2026-06-10T12:02:29.100Z",
    "network": {
      "chain": "Solana",
      "tx_hash": "5h2k...onchain-signature",
      "source_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
      "destination_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
    }
  }
}
```

***

## Sample: Stablecoin payout pending (one-time beneficiary)

```json theme={null}
{
  "event": "transaction.pending",
  "event_id": "3da08b54-6f77-5cbb-ad40-aaf5b9e3c645",
  "created_at": "2026-06-10T12:03:00.000Z",
  "data": {
    "transaction_id": "c3d4e5f6-7081-9203-b4c5-d6e7f8091234",
    "reference": "USD-WD-7H3M2B",
    "type": "payout",
    "status": "pending",
    "rail": "stablecoin",
    "currency": "USDC",
    "amount": 10000,
    "source_amount": 10000,
    "source_currency": "USDC",
    "destination_amount": 10000,
    "destination_currency": "USDC",
    "fee_amount": 0,
    "description": "Supplier settlement",
    "timestamp": "2026-06-10T12:02:59.700Z",
    "beneficiary": {
      "account_name": "My USDC Wallet",
      "currency": "USDC",
      "withdrawal_method": "crypto_usdc",
      "wallet_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
      "wallet_chain": "Solana"
    },
    "network": {
      "chain": "Solana",
      "tx_hash": "USD-WD-7H3M2B",
      "destination_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
    },
    "metadata": { "po_number": "PO-99812" }
  }
}
```

## Account event payloads

Account events (`account.onboarded`, `account.submitted`, `account.approved`, `account.rejected`, `account.changes_requested`, `account.virtual_account.created`, `account.verification.completed`) describe an **account** rather than a transaction, so `data` carries the account fields. `transaction_id` is not present.

| Field                    | Type           | Description                                                                                                                           |
| ------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `data.account_id`        | string         | The account (business or individual) the event is about.                                                                              |
| `data.name`              | string         | Account name. Omitted if not available.                                                                                               |
| `data.email`             | string         | Account email. Omitted if not available.                                                                                              |
| `data.entity_type`       | string         | `business` or `individual`. Omitted if not available.                                                                                 |
| `data.status`            | string         | The application status (`draft`, `submitted`, `approved`, `rejected`, `changes_requested`, ...). Omitted if not available.            |
| `data.review`            | object         | Present on `account.rejected` and `account.changes_requested` when the reviewer recorded a note. Omitted otherwise.                   |
| `data.review.reason`     | string         | The reviewer's note, verbatim. Safe to show your customer.                                                                            |
| `data.review.decided_at` | string         | ISO 8601 timestamp of the decision. Earlier than `created_at`, which is when the event was emitted.                                   |
| `data.virtual_account`   | object         | Present on `account.virtual_account.created` — the provisioned deposit account. Omitted otherwise.                                    |
| `data.verification`      | string         | Present on `account.verification.completed` — `verified` or `failed`.                                                                 |
| `data.related_person_id` | string \| null | Present on `account.verification.completed` — the beneficial owner the check was for, or `null` when it was the account holder's own. |
| `data.ready_to_submit`   | boolean        | Present on `account.verification.completed` — whether the account can now be submitted.                                               |

### Sample: Account approved

```json theme={null}
{
  "event": "account.approved",
  "event_id": "9b1c2d3e-4f50-5a61-b273-c8d9e0f1a2b3",
  "created_at": "2026-06-13T10:15:00.000Z",
  "data": {
    "account_id": "a1b2c3d4-e5f6-7081-9203-b4c5d6e7f809",
    "name": "Acme Logistics Ltd",
    "email": "ops@acmelogistics.com",
    "entity_type": "business",
    "status": "approved"
  }
}
```

### Sample: Account rejected

`review.reason` is the reviewer's own wording — there is no separate email, so this payload is the only notification carrying it.

```json theme={null}
{
  "event": "account.rejected",
  "event_id": "91cf07aa-1ad7-54d8-a458-a0e437677b23",
  "created_at": "2026-06-13T10:20:14.055Z",
  "data": {
    "account_id": "a1b2c3d4-e5f6-7081-9203-b4c5d6e7f809",
    "name": "Acme Logistics Ltd",
    "email": "ops@acmelogistics.com",
    "entity_type": "business",
    "status": "rejected",
    "review": {
      "reason": "Business registration document is illegible and the shareholder register is out of date.",
      "decided_at": "2026-06-13T10:19:48.043Z"
    }
  }
}
```

### Sample: Changes requested

The account reopens for editing. Fix what `review.reason` describes and resubmit — the account then emits `account.submitted` again.

```json theme={null}
{
  "event": "account.changes_requested",
  "event_id": "56a1f159-1def-54cd-b7ca-3dc2effdf483",
  "created_at": "2026-06-13T10:21:15.363Z",
  "data": {
    "account_id": "b2c3d4e5-f607-8192-a3b4-c5d6e7f80912",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "entity_type": "individual",
    "status": "changes_requested",
    "review": {
      "reason": "Proof of address is older than 3 months — please upload a recent one.",
      "decided_at": "2026-06-13T10:20:49.390Z"
    }
  }
}
```

<Info>
  `review` is omitted entirely when a decision was recorded without a note, so treat it as optional.
</Info>

### Sample: Virtual account created

```json theme={null}
{
  "event": "account.virtual_account.created",
  "event_id": "7c8d9e0f-1a2b-5c3d-9e4f-5a6b7c8d9e0f",
  "created_at": "2026-06-13T10:16:30.000Z",
  "data": {
    "account_id": "a1b2c3d4-e5f6-7081-9203-b4c5d6e7f809",
    "name": "Acme Logistics Ltd",
    "email": "ops@acmelogistics.com",
    "entity_type": "business",
    "status": "approved",
    "virtual_account": {
      "id": "f0e1d2c3-b4a5-6978-8a9b-0c1d2e3f4a5b",
      "currency": "NGN",
      "method": "bank_transfer",
      "provider": "rolla",
      "bank_name": "Guaranty Trust Bank",
      "account_number": "1234567890",
      "account_name": "Acme Logistics Ltd",
      "status": "active"
    }
  }
}
```

### Sample: Verification completed

Sent when an identity check finishes, so you learn the result instead of polling [Get Requirements](/api-reference/endpoint/accounts/requirements).

```json theme={null}
{
  "event": "account.verification.completed",
  "event_id": "2acd66b4-9681-5d20-bdc6-38e248db1e50",
  "created_at": "2026-06-13T10:20:04.000Z",
  "data": {
    "account_id": "a1b2c3d4-e5f6-7081-9203-b4c5d6e7f809",
    "verification": "verified",
    "related_person_id": null,
    "ready_to_submit": false
  }
}
```

<Info>
  A passed check does not mean the account is submittable — `ready_to_submit` above is `false` because the application is still missing data. Call [Get Requirements](/api-reference/endpoint/accounts/requirements) and read `submitBlocker` for what remains.
</Info>

On a business, one event is sent per beneficial owner, with `related_person_id` naming who cleared. `ready_to_submit` stays `false` until the last of them is done.
