Simulating Onboarding Decisions
When integrating with Hubpay's onboarding API, you need to verify that your system reacts correctly to the events fired as an account moves through review — account approvals, account rejections, and the per-document approve / decline that drives status transitions on KYB documents.
In sandbox you can drive those decisions yourself with a single API call per event, so the webhooks and resource state changes match what your production integration will see.
This page covers KYB onboarding decisions only. For raising and resolving an RFI in sandbox — including approving or declining RFI-attached documents — see Testing in sandbox under Responding to RFI.
Prerequisites
Before you begin, make sure you have:
- A sandbox API key and the ability to authenticate (see Authentication)
- A webhook endpoint registered to receive events (see Webhooks overview)
- An account in onboarding — to drive the document or account events, you need at least:
- For account approve: an account in
APPLICATION_SUBMITTEDstatus — you must have completed confirm submission first. See the rules below. - For account reject: any account past creation — there are no gating requirements.
- For document approve / decline: a KYB document that has been uploaded against your account — its current
statusmust allow review (i.e.PENDING_REVIEW).
- For account approve: an account in
All endpoints on this page are gated to non-production environments. They return 404 in production.
What you can simulate
| Endpoint | What it does | Webhook fired |
|---|---|---|
POST /v1/account/approve | Transitions the account to APPLICATION_APPROVED | v1.onboarding.account.approved |
POST /v1/account/reject | Transitions the account to DECLINED | v1.onboarding.account.rejected |
POST /v1/account/documents/{documentId}/approve | Transitions the document to APPROVED | v1.onboarding.document.approved |
POST /v1/account/documents/{documentId}/decline | Transitions the document to DECLINED | v1.onboarding.document.declined |
Account approve / reject
Approve an account
Once an account has been signed up and submitted (you may also have uploaded documents and added related parties), call:
curl -X POST https://sandbox-api.hubpay.io/v1/account/approve \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "AccountId: <ACCOUNT_ID>"
On success the response returns the updated account summary and v1.onboarding.account.approved is dispatched to your webhook endpoint. See the Account approve endpoint reference.
Approve rules (different from production)
In sandbox the compliance review checks that normally precede approval are skipped, so you can fire the webhook quickly. The only requirement is that the account is in APPLICATION_SUBMITTED status — call confirm submission first.
Reject an account
curl -X POST https://sandbox-api.hubpay.io/v1/account/reject \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "AccountId: <ACCOUNT_ID>"
On success the response returns the updated account summary with status: DECLINED and v1.onboarding.account.rejected is dispatched. See the Account reject endpoint reference.
Document approve / decline
Once a document has been uploaded and reached PENDING_REVIEW, drive a decision on it:
Approve a document
curl -X POST https://sandbox-api.hubpay.io/v1/account/documents/{documentId}/approve \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "AccountId: <ACCOUNT_ID>"
The {documentId} is the document id from the List account documents endpoint. See the Document approve endpoint reference.
Decline a document
curl -X POST https://sandbox-api.hubpay.io/v1/account/documents/{documentId}/decline \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "AccountId: <ACCOUNT_ID>"
See the Document decline endpoint reference.
A document decline triggers a customer-facing rejection email, just like in production. In sandbox this is routed to the non-prod email sink rather than to real customer inboxes, but it does fire. If you are testing decline flows against an account whose email maps to a real shared inbox, expect a message there.
A typical end-to-end test
A common sandbox loop for an onboarding integration looks like:
- Create the account → receive
v1.onboarding.account.created - Update the business profile → receive
v1.onboarding.account.signed_up(orrejectedif ineligible) - Upload business documents and add related parties
- Confirm submission → receive
v1.onboarding.account.submitted - Drive document decisions:
POST /v1/account/documents/{documentId}/decline→ receivev1.onboarding.document.declined, exercise your re-upload UX, then re-uploadPOST /v1/account/documents/{documentId}/approve→ receivev1.onboarding.document.approved
POST /v1/account/approve→ receivev1.onboarding.account.approved
To test the rejection path instead of approval, swap step 6 for POST /v1/account/reject (you can do this at any point after step 1).
Rules summary
| Rule | Detail |
|---|---|
| Non-production only | All four endpoints return 404 in production |
| Ownership enforced | The account or document must belong to the calling partner — cross-ownership returns 403 |
| Account approve precondition | The account must be in APPLICATION_SUBMITTED status — i.e. confirm submission must have been called |
| Decline email | The customer rejection email fires in sandbox (routed to the non-prod email sink) |
Next steps
- Account event reference — payload schema for
account.approvedandaccount.rejected - Document event reference — payload schema for
document.approvedanddocument.declined - Document statuses — decline reason values and validation status taxonomy
- Webhooks overview — registering an endpoint, signature verification, retry behaviour
- Testing in sandbox (Responding to RFI) — drive RFI lifecycle and per-RFI-document decisions