Skip to main content
All events are delivered in the standard webhook envelope. The payloads below show the data field contents for each event type.

Quick Reference


Persons

person.created

JSON

person.updated

JSON

Offboarding

Offboarding events track a person’s lifecycle from active employment through exit and potential reinstatement. See Offboard Workers for the full guide.

person.offboarding.scheduled

JSON

person.offboarding.cancelled

JSON

person.offboarding.completed

JSON

person.reinstated

JSON
To get full offboarding details (compensation, payroll inclusion), query GET /v1/persons/{personId} after receiving the event.

Users

user.created

JSON

user.updated

The payload includes a type field indicating what was updated.
JSON

user.profile.updated

JSON

user.kyc.updated

Fired on every KYC status change. The type field indicates which verification component changed.
JSON

user.kyc.expiry

Fired when a user’s identity document is approaching expiry or has expired.
JSON

Payroll

The payroll.status.updated event fires for the values below. The webhook uses its own status vocabulary — the third column shows the corresponding status on GET /v1/payrolls/{id}. See Payroll Lifecycle for the full lifecycle.
Awaiting Funds is the status a payroll holds between the approved and scheduled events — receiving approved with no scheduled following shortly means the payroll is waiting on funds; it proceeds automatically once the business balance covers it. No webhook fires for Rejected or Deleted; poll GET /v1/payrolls/{id} to detect those.

payroll.created

JSON

payroll.status.updated

JSON

Transactions

Every transaction.* event carries a type field identifying the kind of transaction: And a recipientType field identifying what kind of entity recipientId refers to:

transaction.initiated

JSON

transaction.processing

Fires once per transaction, when it passes compliance checks and is being processed. Most transactions pass checks automatically within seconds of transaction.initiated; transactions held for manual review can stay in the initiated state for longer before this event fires.
JSON
Instantly-settling transactions (for example PAYROLL_FEE wallet debits) can move straight from transaction.initiated to transaction.succeeded without a transaction.processing event, so treat this event as optional in the lifecycle. It is delivered at most once per transaction.

transaction.rfi.updated

Fires when additional information is needed for a transaction under review, and again when that information has been provided. While a request for information is open, the transaction stays in the initiated state; once review completes, the transaction continues its normal lifecycle (transaction.processing on approval, transaction.failed otherwise). status is RFI_REQUESTED when information is being requested — actionRequired describes what is needed — and RFI_PROVIDED once it has been submitted (the actionRequired field is omitted).
JSON
Use this event to surface “action needed” states in your UI — a transaction with an open request for information will otherwise look like a long-running initiated transaction.

transaction.succeeded

JSON

transaction.failed

JSON
Returned transactions are delivered as transaction.failed with isReturned: true:
JSON
The type field tells you the kind of transaction. reference is a stable identifier from the source system: payrollId for PAYROLL, the deposit reference for DEPOSIT, the business payout reference for PAYOUT. recipientId is the ID of whoever is receiving funds — use recipientType to interpret it (a userId when recipientType: "USER", a businessId when BUSINESS, a personId when EMPLOYEE or CONTRACTOR).

Instant Pay

instant-pay.succeeded

JSON

Contracts

contract.created

JSON

contract.signed

JSON

contract.status.updated

JSON

Invoices

These events cover the contractor self-submitted invoice lifecycle: a contractor raises an invoice billed to your business, you review it, and it is paid. invoice.contractor.submitted is your cue to review — call POST /v1/invoices/{invoiceId}/review to approve or reject it. Only invoices with source of CONTRACTOR_SUBMITTED fire these events. reason is present only on invoice.contractor.rejected.
JSON

Reimbursements

These events cover the reimbursement lifecycle: a worker submits a reimbursement — or you create one via POST /v1/reimbursements — you review it, and it is paid out. reimbursement.submitted is your cue to review — call POST /v1/reimbursements/{reimbursementId}/review to approve or reject it. Approving disburses the reimbursement from the sourceCurrency wallet, and reimbursement.paid follows once it settles. reason is present only on reimbursement.rejected; amount is the reimbursed (destination) amount.
JSON

Virtual Accounts

A virtual account can belong to either a user or a business. Exactly one of userId or businessId will be present.

virtual-account.requested

JSON

virtual-account.submitted

JSON

virtual-account.created

JSON

Business

business.kyb.reviewed

Sent when a KYB submission has been reviewed. May indicate approval or that additional information is needed.
JSON
See KYB Requirements for handling needs-additional-info responses.

business.kyb.rejected

Sent when a KYB submission has been permanently rejected. This is a terminal state — the business cannot resubmit.
JSON

business.kyb.completed

JSON

business.basicinfo.updated

JSON

External Accounts

external-account.added

Ready to use for deposits straight away.
status is active for instantly verified accounts, or needs_confirmation for accounts still awaiting micro-deposit verification. This event fires as soon as the account is submitted, so it is the signal to move a customer off your “set up direct debit” prompt. microdepositInfo is present only while an account is awaiting verification. type is descriptor_code (a code on the statement) or amounts (two small deposits to read back), and arrivalDate is a Unix timestamp for when the deposit is expected — enough to render your interim copy without a follow-up API call. To collect the code or amounts, send the account holder to the link from Generate External Account Link with mode set to verification. Poll Get External Accounts if you need to reliably detect the needs_confirmationactive transition: the follow-up event carries a different id for the same account, so the two cannot be correlated by id alone.

external-account.removed

JSON

Statutory Compliance

Filing, remittance, and requirement events share a common structure. The resourceType and resourceId fields identify the affected resource.

filing.created

JSON

filing.blocked

JSON

filing.approved

JSON

filing.accepted

JSON

remittance.completed

JSON

requirement.satisfied

JSON