webhook_url configured for your program. Events fire asynchronously as platform actions occur — onboarding, account issuance, money movement, and card state changes.
The Ingo Banking Platform joined the Ingo Payments family through the acquisition of Deposits Inc. in 2024, expanding Ingo’s money mobility capabilities with bank-grade account creation, ledgering, and card issuance. As part of Ingo Payments’ broader platform integration effort, Banking webhooks are delivered through a purpose-built architecture optimized for account and card lifecycle events — reflected in the envelope structure documented on this page. We are actively working toward a unified developer experience across all Ingo Payments products.
Delivery
- Every event is delivered as an HTTP
POSTto your registeredwebhook_url Content-Type: application/json- Return any
2xxstatus within a few seconds to acknowledge receipt - Non-
2xxresponses are retried with exponential backoff - Receivers must be idempotent — the same event may be delivered more than once under transient failure
Common Envelope
Every event uses the same outer structure. Theevent field and data.event_type always carry the same value.
| Field | Notes |
|---|---|
event | Outer routing key — use this to branch on event type. Example: "account.transfer.completed" |
data.event_id | Platform-generated delivery ID. Format: inn_whe_ followed by 22 alphanumeric characters. Use as your deduplication key. |
data.event_type | Always mirrors event. |
data.event_description | Free-text summary. Meaningful on some events (e.g. account.issue.created uses it to name the account type issued). May be empty on others. |
created_at / updated_at | Outer delivery timestamps. |
Field Conventions
| Field | Type | Notes |
|---|---|---|
entity_id | string | Numeric platform identifier for the entity, passed as a string. Example: "6830" |
entity_type | enum | "user" or "business" |
user_id / business_id | string | Numeric platform identifier for the specific user or business. Example: "9414" |
account_id | string | Numeric platform identifier for the account (except in assignment events, where it is a UUID). Example: "6246" |
wallet_id | string | Numeric platform identifier for the wallet. Example: "3273" |
transfer_id / transaction_id / adjustment_id | string | Platform-generated transfer or transaction identifiers. Example: "DPST_PVCVXAR4KRU2CTOT6026NIGGS" |
card_id (in card block) | string | Prefixed UUID. Example: "rcrd-acc960c0-3a14-413e-a248-74684e52a0f2" |
account.account_id (assignment events) | string | UUID format. Example: "9e30d021-3f39-4fcc-935b-e286d7f52807" |
currency | string | Uppercase currency code. Currently USD only. |
direction | enum | "credit" (funds in) or "debit" (funds out), from the entity’s perspective. |
amount | string | Decimal amount with two decimal places, always as a string. Example: "500.00". Never treat as a float. |
Receiver Best Practices
Deduplicate ondata.event_id. The same event may be redelivered under transient failure. Store processed event IDs and skip duplicates.
Acknowledge fast, process async. Return 2xx quickly; defer heavy work to a background job. Slow responses will cause retries.
Parse defensively. New optional fields may be added to the data block in future platform versions. Do not reject events with unknown fields.
Handle unknown card.status.* values as a no-op. The platform may emit any value from the card status enum. Unknown statuses should not cause errors.
Use event_description to identify account issuance type. account.issue.created and account.issue.failed are emitted for both VBAN and RBA issuance. The event_description field distinguishes them — common values are "Virtual Bank Account" and "Routable Bank Account".
Disambiguate bulk vs. single assignment events. account.assignment.success and account.assignment.failed are emitted in two distinct payload shapes. Branch on the presence of process_id:
- Single-record — includes
entity_id,entity_type, and anaccountblock describing the assigned account - Bulk — includes
process_id,data.event_typeset to the constant"account.assignment.bulk", and abatchblock with run statistics
Platform Notes
The
status field on card lifecycle events (including card.issue.failed) carries the value "completed". This reflects the event-delivery status, not the card outcome. Use the event name itself to determine whether the operation succeeded or failed.Transfer reversal and block events (
account.transfer.reversed, account.transfer.blocked) use a slimmer payload than created/completed/failed events — they omit account_id, account_type, currency, amount, and memo.Event Categories
| Category | Events |
|---|---|
| User Events | user.created, user.kyc.success, user.kyc.failed |
| Business Events | business.created, business.kyb.success, business.kyb.failed |
| Wallet Events | wallet.created, wallet.topup.success, wallet.topup.failed |
| Account Lifecycle | account.created, account.saved, account.link.created, account.link.deleted, account.issue.created, account.issue.failed |
| Account Assignment | account.assignment.success, account.assignment.failed |
| Transfer Events | account.transfer.created, account.transfer.completed, account.transfer.reversed, account.transfer.blocked, account.transfer.failed, account.transfer.returned, account.overdraft.created, account.transfer.exception |
| Card Lifecycle In Development | card.issue.created, card.issue.failed, card.status.active, card.status.frozen, card.status.inactive, card.status.pending, card.status.inreview, card.status.terminated, card.status.reissue |
| Card Authorization In Development | card.auth.created, card.auth.cleared, card.auth.updated, card.auth.reversed, card.auth.refund |
Card Lifecycle and Card Authorization events correspond to the Card Issuance capability, which is currently in development. These events are documented here so you can build and test your handlers in advance. They will not fire until Card Issuance is enabled for your program.