event names what happened, data carries it — so the objects below are what arrives in data.
Every payload carries an event_id. Use it to make your handler idempotent: record what you have already processed and ignore a repeat.
Sub-client
user.created
user.created
user.status_changed
user.status_changed
user.verification.accepted
user.verification.accepted
user.verification.failed
user.verification.failed
reasons exists only here. No read of the sub-client returns it.user.liveness_completed
user.liveness_completed
person_reference_id is null when the check was for the sub-client rather than one of its people.Virtual account and deposits
virtual_account.activated
virtual_account.activated
virtual_account.deposit_funds_received
virtual_account.deposit_funds_received
virtual_account.deposit_funds_refunded
virtual_account.deposit_funds_refunded
Payouts
payout.status_changed
payout.status_changed
IN_REVIEW and KYT_PENDING arrive here and nowhere else.payout.completed
payout.completed
amount and recipient_amount differ by the fees and any conversion.Requests for information
These reach a URL with no event filter, or one whose filter names them.rfi.raised
rfi.raised
rfi.item_returned
rfi.item_returned
to_status here is the item’s, not the request’s.rfi.not_resolved
rfi.not_resolved
resolution_reason rides along only on this one — it is the difference between a deadline that ran out and an answer that was refused.Every payload carries
to_status read off the row that moved, rather than inferred from the event name. A handler that stores the event can reconstruct state without knowing which events existed on the day it was written.