Goal
This guide walks you through the KYC flow end-to-end. By the end, you will have anAPPROVED user that is ready for account creation.
KYC spans both your backend and your frontend. Your backend handles all Reap API calls and receives webhooks. Your frontend launches the Sumsub SDK using the
sdkToken your backend fetches.Initiate KYC (backend)
Call Initiate application flow with the
userId from Create a user. The response includes an sdkToken. Return this to your frontend to launch the verification SDK.Launch the Sumsub SDK (frontend)
Pass the
sdkToken to the Sumsub WebSDK in your app.
The SDK guides the user through document capture, liveness checks, and submission.Follow the Sumsub WebSDK integration guide for setup.
For mobile apps, refer to the Sumsub iOS or Android SDK docs.Keep your UI in a “verification in progress” state until your backend receives a webhook confirming the outcome.Handle the webhook (backend)
When verification completes, Reap sends a
USER_APPLICATION_STATUS_UPDATED event to your webhook endpoint.
See the USER_APPLICATION_STATUS_UPDATED event reference for the full payload schema.Handle the application.status in the event:APPROVED: user is verified. Proceed to account creation.REJECTED: permanently rejected. Surfaceapplication.rejectionReasonto the user. Do not re-initiate.RETRY_REQUIRED: user can try again. Surfaceapplication.rejectionReasonand go back to Step 1.
Handle retries (backend + frontend)
If
application.status is RETRY_REQUIRED, call Initiate application flow again to get a new token, then pass it to your frontend to relaunch the SDK.Use application.rejectionReason from the webhook to explain what the user needs to correct before they go through the SDK again.Testing in sandbox
In the sandbox environment, use the simulation endpoint to triggerUSER_APPLICATION_STATUS_UPDATED webhooks without running real identity checks.
The update is processed asynchronously. Wait for the webhook rather than polling.
See Simulate user application status in the API reference for the full request schema.
Scenario 1: Happy path
- Create a user
- Initiate application flow
- Simulate user application status with
{ "status": "APPROVED" } - Confirm webhook received with
status: "APPROVED" - Create an account
Scenario 2: Retry required, then approved
- Create a user
- Initiate application flow
- Simulate user application status with
{ "status": "RETRY_REQUIRED" } - Confirm webhook received with
status: "RETRY_REQUIRED", surfacerejectionReasonin your UI - Initiate application flow again
- Simulate user application status with
{ "status": "APPROVED" } - Confirm webhook received with
status: "APPROVED" - Create an account