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

# Meow webhook event types and payload reference

> Reference for every Meow webhook event type, including transfer, card, invoice, and bill notifications with their payload schemas and status values.

Every event Meow sends has the same envelope. The `data` object is the
resource snapshot (or `{id, object}` in `thin` mode). The lifecycle stage
lives on `data.status` — dispatch on that, not the event name.

```json Envelope theme={null}
{
  "type": "ach_transfer.updated",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": { "...": "..." },
  "sequence": 4
}
```

**`sequence`** is a per-resource counter for discarding stale deliveries —
see [Handle out-of-order deliveries](/guides/webhooks#5-handle-out-of-order-deliveries).
It rides resource events and is absent on `webhook.test`,
`message.attempt.exhausted`, and partner `application.*` events.

**ID shapes.**

* Meow-managed IDs (`entity_id`, `account_id`, `counterparty_id`,
  `virtual_account_id`, `subscription_id`, `delivery_id`) are UUIDs.
* Resource IDs (`ach_transfer.id`, `wire_transfer.id`, inbound transaction
  `id`, `check_deposit.id`, `global_account_transfer.id`) are **opaque
  strings whose format varies by the underlying bank**:

  * CRB / FirstBank: `deposit_inach_11mn5s777xgveb9`, `withdrawal_txc_15wp3bd309xenf6p`, `book_11n0b3vs9vy0ypw`, `interest_txc_15wp2ghq09qm3141`.
  * Bridge global accounts: `bridge_va_inach_<uuid>` (incoming ACH), `bridge_va_iw_<uuid>` (incoming wire), `bridge_wallet_ext_ach_<uuid>` (external ACH off-ramp), `bridge_wallet_ext_wire_<uuid>` (external wire), `wallet_transfer_group_<uuid>` / `wallet_deposit_group_<uuid>` (wallet send / receive).
  * Treasury Prime: TP's own external IDs.

  Treat resource IDs as tokens; don't parse them.

| Event                             | When it fires                                                             |
| --------------------------------- | ------------------------------------------------------------------------- |
| `ach_transfer.created`            | A new outbound ACH transfer was created.                                  |
| `ach_transfer.updated`            | An outbound ACH transfer changed state.                                   |
| `wire_transfer.created`           | A new outbound wire was created.                                          |
| `wire_transfer.updated`           | An outbound wire changed state.                                           |
| `inbound_ach_transfer.created`    | An ACH credit or debit hit your account.                                  |
| `inbound_ach_transfer.updated`    | An inbound ACH changed state.                                             |
| `inbound_wire_transfer.created`   | A wire arrived at your account.                                           |
| `inbound_wire_transfer.updated`   | An inbound wire changed state.                                            |
| `check_deposit.created`           | A check deposit was submitted.                                            |
| `check_deposit.updated`           | A check deposit changed state.                                            |
| `global_account_transfer.created` | Activity on a global (virtual) account. Single-emission.                  |
| `webhook.test`                    | A test event you triggered.                                               |
| `message.attempt.exhausted`       | A delivery hit 10 failed attempts and the subscription was auto-disabled. |

**Partner subscriptions** (`partner:webhooks:*`) receive a separate catalog —
the `application.*` onboarding events below. The two catalogs don't overlap:
an entity subscription can't subscribe to `application.*`, and a partner
subscription can't subscribe to the rail events above. Listing the wrong
catalog's events in `event_types` returns a 400.

| Event                      | When it fires                                        |
| -------------------------- | ---------------------------------------------------- |
| `application.created`      | A partner created an onboarding application.         |
| `application.under_review` | KYB review is pending.                               |
| `application.submitted`    | KYB approved; the banking account is not yet active. |
| `application.approved`     | Onboarding finished — the account is active.         |
| `application.rejected`     | The application was rejected.                        |

## ach\_transfer

`status` values: `pending`, `processing`, `sent`, `returned`, `canceled`, `error`.

Optional fields not shown in the sample: `operation_request_id`.

```json theme={null}
{
  "type": "ach_transfer.updated",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "id": "withdrawal_txc_15wp3bd309xenf6p",
    "object": "ach_transfer",
    "created": "2026-04-28T07:59:50Z",
    "updated": "2026-04-28T08:00:00Z",
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "status": "sent",
    "amount": "1500.00",
    "counterparty_id": "5dada3c2-7f3a-4f2e-8a91-3d6f1c9b9e22",
    "counterparty_name": "Acme Corp",
    "counterparty_account_number": "****1234",
    "counterparty_routing_number": "021000021",
    "description": "April invoice",
    "error": null
  }
}
```

## wire\_transfer

Same `status` values as `ach_transfer`. Extra wire-only fields: `counterparty_bank_name`, `purpose`, `imad` (Fed reference), `instructions`.

```json theme={null}
{
  "type": "wire_transfer.updated",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "id": "wire_dom_a8e9c7d24b1f4a3e8a91d9e87c5b9001",
    "object": "wire_transfer",
    "created": "2026-04-28T07:59:50Z",
    "updated": "2026-04-28T08:00:00Z",
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "status": "sent",
    "amount": "10000.00",
    "counterparty_id": "5dada3c2-7f3a-4f2e-8a91-3d6f1c9b9e22",
    "counterparty_name": "Acme Corp",
    "counterparty_bank_name": "JPMorgan Chase",
    "purpose": "Q2 settlement",
    "imad": "20260428B1QGC07C012345"
  }
}
```

## inbound\_ach\_transfer

`status` values: `pending`, `posted`, `scheduled`, `failed`, `canceled`, `returned`. Casing matches outbound (lowercase on the wire).

```json theme={null}
{
  "type": "inbound_ach_transfer.updated",
  "timestamp": "2026-04-28T14:00:00Z",
  "data": {
    "id": "deposit_inach_11mn5s777xgveb9",
    "object": "inbound_ach_transfer",
    "created": "2026-04-28T13:59:00Z",
    "updated": "2026-04-28T14:00:00Z",
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "account_id": "a8e9c7d2-4b1f-4a3e-8a91-d9e87c5b9001",
    "amount": "250.00",
    "currency": "USD",
    "status": "posted",
    "originator_name": "Stripe Connect"
  }
}
```

## inbound\_wire\_transfer

Same shape as inbound ACH; `object` is `inbound_wire_transfer`.

## check\_deposit

Same shape as inbound ACH; `object` is `check_deposit`.

## global\_account\_transfer

Activity on a global (virtual) account. Each activity is one-shot — `funds_scheduled` and `funds_received` for the same deposit share `deposit_id` but arrive as two separate events with different `id`s.

`activity_type` values: `funds_scheduled`, `funds_received`, `payment_submitted`, `payment_processed`, `refund_in_flight`, `refunded`, `refund_failed`.

`currency` is lowercase: `usd`, `usdc`, `usdt`, `usdb`, `usdg`, `pyusd`, `dai`, `cash`.

```json theme={null}
{
  "type": "global_account_transfer.created",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "id": "bridge_va_inach_f5140b06-814e-4f4b-810b-217859d7b721",
    "object": "global_account_transfer",
    "created": "2026-04-28T08:00:00Z",
    "updated": null,
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "virtual_account_id": "9b3a7c5e-1d20-4a6f-8c1d-e7b34f25a8e9",
    "activity_type": "funds_received",
    "amount": "5000.00",
    "currency": "usdc",
    "payment_rail": null
  }
}
```

## webhook.test

Triggered manually via `POST /webhooks/subscriptions/{id}/test`. Always sent in full (the `thin` mode falls through because there's no `id` to GET).

```json theme={null}
{
  "type": "webhook.test",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "subscription_id": "7b9e8a5f-3c2d-4d11-9a8c-1e6c4f2a5b30",
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "generated_at": "2026-04-28T08:00:00Z"
  }
}
```

## message.attempt.exhausted

Fires when a delivery hits 10 failed attempts. The subscription is auto-disabled (`disabled_reason=retry_exhausted`). Use this to page an on-call. `last_response_status` is null if every attempt failed before getting an HTTP response (timeout, DNS, TLS).

```json theme={null}
{
  "type": "message.attempt.exhausted",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "delivery_id": "0c5b4a3e-9d2c-4f1a-b7e0-21b1d8c4a9f1",
    "subscription_id": "7b9e8a5f-3c2d-4d11-9a8c-1e6c4f2a5b30",
    "event_type": "ach_transfer.updated",
    "attempt_count": 10,
    "last_response_status": 504,
    "last_error_message": "Your endpoint did not respond within the timeout."
  }
}
```

## application

Delivered to **partner subscriptions** only. Each event reports an onboarding
application reaching a new status; the event name and `data.status` always
match. `application_id` is the application identifier (the KYB info public id);
`entity_id` is the onboarded business, present on every event including
`application.created`. `previous_status` is `null` only on `application.created`.

`status` values: `pending_document_upload`, `pending_user_action`,
`under_review`, `submitted`, `approved`, `rejected`. Note `submitted` sits
*later* in the lifecycle than `under_review` — `under_review` means KYB review
is pending, `submitted` means KYB approved but the account is not yet active.

Unlike the rail events, `application.*` events carry **no `sequence`** and are
always delivered as a full snapshot (partner subscriptions don't support
`thin` mode).

```json theme={null}
{
  "type": "application.approved",
  "timestamp": "2026-04-28T08:00:00Z",
  "data": {
    "application_id": "8f2a1c4d-3b9e-4a7c-9d18-2e6c4f0a5b31",
    "entity_id": "6f3b1d7c-aa90-4f0c-a5d2-9c8b1d3e2c10",
    "partner_reference_id": "your-internal-ref-001",
    "status": "approved",
    "previous_status": "submitted",
    "business_name": "Acme Corp"
  }
}
```
