Compare status values case-insensitively rather than matching exact strings. Each table below shows the values as they arrive.
Sub-client
Branch on this field.
verification_status reports the result of the identity check — see Sub-client verification.
A document rejected on its own is not in this table: it moves verification_status to needs_action and leaves status where it was. User values has the set.
Virtual account
Which set comes back depends on the version you are pinned to; the values are on Virtual account values, where both sets are listed side by side.
Nothing but the active state can receive money. Wait for
virtual_account.activated rather than for the account to merely exist — Account opening follows the whole sequence.
Deposit
A fiat deposit arrives
COMPLETED, with no settlement step to wait through.
KYT_REJECTED is deliberately not FAILED: a failure is technical, this one is a compliance decision, and keeping them apart is what makes the audit trail readable.
Only FAILED and REFUNDED are terminal. A COMPLETED deposit can still be held or clawed back, so code that treats it as final is treating a state as an ending it does not have.
Payout
IN_REVIEW and KYT_PENDING only ever arrive on payout.status_changed. No dedicated event carries either.
Only FAILED, CANCELLED and EXPIRED are terminal. A bank return moves a COMPLETED payout to FAILED; Payout has when and why.
RFI
An RFI has items, and each is answered separately. One item being returned does not undo the others.
The states you cannot read back
Two pieces of information exist only on the event that carried them, and no read ever returns them:
Capture both when they arrive. There is no going back for them.