Event-Type header and an X-Signature you must verify before parsing — see Validating Webhooks.
Subscribe a webhook to any of them through the
event_hooks field on Create a Webhook.
Delivery headers
Verify
X-Signature before trusting a body — see Validating Webhooks. Failed deliveries are retried; see Delivery Protocol.
bank_account_status
status is the status the account just moved into.
A webhook is queued when the account record is created, so the first delivery you receive after adding a bank account can already be
pending or verified if verification finished first.
Verified:
send_instruction_status
state is the state the instruction just moved into.
Completed:
budget_allocation_status
This event is only delivered for allocations — rows withtransaction_type: in. A row is created when you request a budget allocation, and its status moves pending → approved, or pending → expired.
Deductions are not delivered here. The ledger also holds
transaction_type: out rows (the deduction behind a completed send, status: success) and you can read them from GET /send/send_limits, but they never produce a budget_allocation_status webhook. Reconcile completed payouts from send_instruction_status instead of waiting for a success event here.
Each
approvals_details entry:
Pending approval:
Reading the payloads
statusandstatealways describe the object after the change, so an event is a snapshot rather than a diff. Do not infer the previous state from it.- Intermediate states can be superseded: when an object moves on before an earlier delivery is complete, CHIP suppresses the stale one so you always end at the latest state. Never assume you will receive every step — drive your logic off
state/statusin the body. - Deliveries are retried until your server answers
2xx, so the same state can arrive more than once, and after a retry it can arrive later than a newer state. Treat each body idempotently on the objectidplusstate/status. - Treat the body as the record of that moment. Fetch the object through the API if you need the current state.
- Live bodies are compact JSON — one line, no whitespace between fields. The samples on this page are pretty-printed for reading. Verify and parse the raw bytes you received, never a re-serialised copy.
rejection_reasonis the human-readable reason; it isnullfor successful states.- Amounts are not interchangeable across events: send instruction
amountis a decimal string ("1500.00"), budgetamount,feeandnet_amountare numbers. - Timestamps are UTC in ISO-8601 with milliseconds.
from_settlementis a plain date. - The ids, names, account numbers and amounts in these examples are illustrative.