HomeGuidesAPI ReferenceChangelog
Home
Guides

KYCaaS Integration Guide

Purpose: Onboard individual cardholders into the Reap platform using a single guided workflow that consolidates entity registration, webhook subscription, SumSub WebSDK token generation, identity and liveness verification, decision retrieval, and signed payload issuance for downstream card creation.


When to Use This

Use this guide when you need Reap to host and run the identity verification experience for individual cardholders through SumSub's WebSDK:


Choose between:

  • WebSDK (this guide) — use when Reap hosts and handles the cardholder verification experience. Reap issues an SDK token and your frontend embeds SumSub's WebSDK to capture identity documents and liveness.
  • API-based flow (see Universal KYC ) — use when your system collects and submits KYC data directly to Reap as a structured payload instead of using a hosted SDK.

Overview

KYCaaS brings the full cardholder identity verification journey into a single guided workflow under the Reap Compliance API. Instead of orchestrating verification providers directly, integrators register the cardholder as an individual entity, request a SumSub WebSDK token from Reap, and launch the hosted verification experience on the frontend. Reap manages the backend verification, provider orchestration, and decision lifecycle on behalf of the integrator.

Every onboarding case must be linked to a single individual entity created through the Entity resource with type: INDIVIDUAL. The SDK token returned by Reap is the authoritative artefact used to initialise SumSub's WebSDK and stream the verification result back to Reap for review.

The SDK token request also powers Reap's jurisdiction-specific rule engine orchestration, enabling conditional verification flows such as:

  • Jurisdiction-specific verification when binCountry is set to a code with jurisdiction-specific requirements (currently MEX)
  • Default verification when binCountry is excluded or set to a code that uses the default flow
  • Verification flow selection via verificationFlow (EMPLOYEE or CUSTOMER)

Prerequisites

  1. An active Reap Card Issuance account with KYCaaS enabled for the program
  2. A sandbox API key generated from the Reap Card Issuance Dashboard and, once provisioned, a production API key linked to a Business UUID (BUUID)
  3. A publicly reachable HTTPS webhook endpoint capable of returning a 200 OK response within 5 seconds
  4. Reap's RSA public key configured for webhook signature verification
  5. A frontend application ready to embed SumSub's WebSDK for the cardholder verification experience
  6. The externalId value to be used as the integrator's correlation reference for the cardholder

💬

Please contact your account manager if you have any questions about KYCaaS provisioning, BUUID assignment, or production API key issuance.

⚠️

All KYCaaS API requests must be authenticated using the API key issued for the relevant environment. The BUUID derived from the API key scopes every request to the integrator's business.


Key Concepts

API Key and Business UUID (BUUID)

  • Sandbox and production API keys are generated from the Reap Card Issuance Dashboard under Settings → Product Settings → KYC API Keys
  • Each API key is linked to a Business UUID (BUUID) that scopes all activity to the integrator's business
  • The API key is passed as x-reap-api-key on every Compliance API request

Individual Entity

  • The anchor record for all KYCaaS submissions
  • Created via POST /entity with type: INDIVIDUAL
  • Returns an entityId for use in all subsequent calls and includes the provided externalId in the response.

Webhook Subscription

  • Registered against Reap's Compliance API at the /notification endpoint
  • Subscribes to the account_status_change event type to receive asynchronous KYC decision updates
  • Signed using Reap's RSA private key and verifiable on the integrator side using the provided public key

SumSub WebSDK Token

  • Provider-specific SDK token returned by Reap to initialise the identity verification UI on the integrator's frontend
  • Generated via POST /entity/entityId/kyc
  • Driven by the verificationFlow and optional binCountry inputs

Verification Flow

  • Manual selection of the SumSub verification flow applied to the cardholder
  • Allowed values are EMPLOYEE and CUSTOMER

BIN Country

  • binCountry is the ISO 3166-1 alpha-3 country code of the issuing BIN
  • binCountry determines the jurisdiction-specific KYC requirements applied to the cardholder flow (verification level, required documents, and required data fields)
  • binCountry must be supplied when the issuing BIN belongs to a jurisdiction with jurisdiction-specific requirements and may be excluded when the issuing BIN is in a jurisdiction that uses the default flow
  • MEX is currently the supported jurisdiction-specific code and all other BIN countries follow the default flow

Signed Payload

  • Portable and tamper-proof JWT representation of an approved KYC application
  • Retrieved via GET /entity/entityId/signed-payload once the case is approved
  • Serves as the authorisation evidence for proceeding with card issuance through the Reap CaaS API

External ID

  • Unique identifier for the cardholder within the integrator's system
  • Used to correlate the Reap entity with the integrator's internal record

Flow Overview

  1. Generate sandbox and production API keys via the Reap Card Issuance Dashboard
  2. Register a webhook endpoint and subscribe to the account_status_change event type
  3. Create the individual entity via POST /entity with type: INDIVIDUAL
  4. Generate a SumSub WebSDK token via POST /entity/entityId/kyc including binCountry only when the issuing BIN belongs to a jurisdiction with jurisdiction-specific KYC requirements (currently MEX)
  5. Launch SumSub's WebSDK on the frontend so the cardholder completes identity document and liveness verification
  6. Receive the KYC decision via webhook notification (APPROVED or REJECTED)
  7. Fetch the signed payload via GET /entity/entityId/signed-payload once the case is approved
  8. Pass the signed payload into POST /cards with customerType = "Consumer" to create the card

API Summary

ActionEndpointMethodUse Case
Subscribe to webhook/notificationPOSTSubscribe a webhook endpoint to the account_status_change event type.
Create individual entity/entityPOSTRegister an individual-type entity to anchor all subsequent KYCaaS submissions
Generate KYC SDK token/entity/entityId/kycPOSTGenerate a SumSub WebSDK token using verificationFlow and, when applicable, binCountry
Fetch signed payload/entity/entityId/signed-payloadGETRetrieve the signed JWT payload after KYC approval
Create card/cardsPOSTCreate a card by passing the signed KYC payload into the Card Issuance API

KYCaaS Onboarding

Step 1: Generate an API Key

Generate the API keys used to authenticate every KYCaaS request from the Reap Card Issuance Dashboard.


Generate the API Key

Navigate to Settings → Product Settings → KYC API Keys in the Reap Card Issuance Dashboard to generate a sandbox API key. A production API key is issued once the business is provisioned.

ℹ️

Use the sandbox API key throughout the integration and switch to the production API key only after the integration has been validated end to end.


Step 2: Set Up Webhooks

Register a webhook endpoint with Reap's Compliance API to receive asynchronous KYC decision updates.


Subscribe to Webhook

Use POST /notification to subscribe a webhook endpoint to receive account_status_change events


Sample Request (cURL)

curl --request POST \
  --url https://sandbox-compliance.api.reap.global/notification \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-reap-api-key: ********' \
  --data '{
    "webhookUrl": "https://api.example.com",
    "notificationChannel": "WEBHOOK",
    "notificationTypes": ["account_status_change"]
  }'

Key Input

Parameter NameTypeDescription
notificationTypesarray of stringList of notification event types to subscribe to (for example, account_status_change)

Sample Response

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "channel": "WEBHOOK",
  "types": [
    "account_status_change"
  ],
  "config": {
    "webhook": {
      "url": "https://api.example.com"
    }
  },
  "createdAt": "2024-03-20T10:00:00Z"
}

Key Output

Parameter NameTypeDescription
idstringUnique identifier for the notification subscription
channelstringNotification delivery channel configured for the subscription (e.g. WEBHOOK)
typesarray of stringList of notification event types subscribed to
configobjectConfiguration details for the notification channel
config.webhook.urlstringWebhook endpoint URL where notification events will be delivered
createdAtstringTimestamp indicating when the notification subscription was created in (Format: ISO 8601)

Webhook Endpoint Requirements

RequirementDetail
ProtocolHTTPS is required for all webhook endpoints
Response timeThe endpoint must return a 200 OK response within 5 seconds
Signature verificationVerify the webhook signature using Reap's RSA public key
Environment validationValidate the endpoint in the sandbox environment before enabling the webhook subscription in production
ℹ️

Refer to the Webhook Setup Guide for payload examples and signature verification code snippets in Node.js and Python.


Step 3: Create an Individual Entity

Create an individual-type entity where the returned id is used as the entityId for all subsequent KYCaaS requests.


Call the Create Entity Endpoint

Use POST /entity to register the cardholder and obtain the anchor entity record.


Sample Request (cURL)

curl --request POST \
  --url https://sandbox-compliance.api.reap.global/entity \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-reap-api-key: ********' \
  --data '{
    "externalId": "CUSTOMER-DEMO-10001",
    "type": "INDIVIDUAL"
  }'

Key Input

Parameter NameTypeDescription
typestringSet the entity type to INDIVIDUAL for KYCaaS onboarding

Sample Response

{
  "id": "5f54bcf9-5a21-4f76-a819-6a65a8c238b8",
  "externalId": "CUSTOMER-DEMO-10001",
  "businessId": "e10e9f95-f256-4c47-bcf6-a6029e09c3aa",
  "type": "INDIVIDUAL"
}
Parameter NameTypeDescription
idstringUnique identifier generated by Reap for the created entity. Used as entityId in all subsequent calls
externalIdstringThe external reference ID provided during entity creation
businessIdstringUnique identifier for the associated Reap business account
typestringType of entity created

Step 4: Generate the KYC SDK Token

Generate a SumSub WebSDK token to launch identity document and liveness verification on the integrator's frontend including binCountry when the issuing BIN belongs to a jurisdiction that requires jurisdiction-specific KYC handling currently MEX and excluding the field for all other jurisdictions.


Call the Generate KYC SDK Token Endpoint

Use POST /entity/entityId/kyc to generate a SumSub WebSDK token against the individual entity created in the previous step.

⚠️

Pass binCountry only for cardholders issued under a BIN whose jurisdiction requires jurisdiction-specific KYC handling and exclude the field for BINs in jurisdictions that use the default flow.


Sample Request (cURL) — Jurisdiction-specific BIN (MEX example)

The payload must include binCountry: "MEX" when issuing under a MEX BIN.

curl --request POST \
  --url https://sandbox-compliance.api.reap.global/entity/entityId/kyc \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-reap-api-key: ********' \
  --data '{
    "verificationFlow": "EMPLOYEE",
    "binCountry": "MEX"
  }'

Sample Request (cURL) — Default BIN jurisdiction

The binCountry field is not required when the cardholder is issued under any country other than MEX. The field is excluded from the payload and the SDK token is generated using the selected verificationFlow.

curl --request POST \
  --url https://sandbox-compliance.api.reap.global/entity/entityId/kyc \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-reap-api-key: ********' \
  --data '{
    "verificationFlow": "EMPLOYEE"
  }'

Key Input

Parameter NameTypeDescription
verificationFlowstringManual verification flow applied to the cardholder with allowed values EMPLOYEE and CUSTOMER
binCountrystringISO 3166-1 alpha-3 code of the issuing BIN that drives jurisdiction-specific KYC requirements and is required when the issuing BIN belongs to a jurisdiction with jurisdiction-specific rules currently MEX and excluded for all other BIN countries.

Sample Response

{
  "provider": "sumsub",
  "sdkToken": "sbx:uY0CgwELmgUAEAEADQATACIAHQAOABcADwAMAA...",
  "expiresAt": "2024-12-31T23:59:59.000Z",
  "verificationFlow": "EMPLOYEE"
}

Key Output

Parameter NameTypeDescription
providerstringIdentity verification provider name returned by Reap (e.g. sumsub)
sdkTokenstringProvider-specific SDK token used to initialise the identity verification SDK
expiresAtdate-timeTimestamp when the SDK token expires
verificationFlowstringVerification flow used to generate the SDK token (Format: ISO 8601)

Step 5: Complete Identity Verification

Use the SDK token returned in Step 4 to initialise SumSub's WebSDK on the integrator's frontend so the cardholder can complete identity document and liveness verification. Reap handles the backend verification, provider orchestration, and decision lifecycle on behalf of the integrator.


Launch the SumSub WebSDK

Initialise the SumSub WebSDK using the sdkToken returned by Reap and embed the verification experience in the integrator's frontend.


Cardholder Verification Steps

StepDescription
Identity document verificationCapture a government-issued identification document (e.g. passport, ID card, driver's licence)
Liveness checkCapture a live selfie to confirm the cardholder is physically present
ℹ️

Refer to the SumSub WebSDK Integration Doc for frontend embedding instructions, event handling, and theming options.


Step 6: KYC Decision

The application enters final KYC review after the cardholder completes identity document and liveness verification. The decision result is sent asynchronously to the registered webhook endpoint.

⚠️

Only applications with an APPROVED status can proceed to Step 7 (Fetch the Signed Payload) and Step 8 (Create Card).


Sample Decision Webhook

The KYC decision is communicated via webhook notification.

{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "938c65f7-2aad-494d-b488-5256c4cfc370",
    "message": "User profile approved - card generation enabled",
    "entityId": "6ac28264-c21b-4757-b141-1efce00adce6",
    "timestamp": "2026-01-27T13:27:51.027Z",
    "status": "APPROVED"
  }
}
{
  "eventName": "card_issuance_api_access_updated",
  "eventType": "account_status_change",
  "data": {
    "eventId": "fc7b8d1d-9e08-4c61-bef2-3ce4e6162dcf",
    "message": "KYC verification rejected",
    "entityId": "6c539925-f00c-4b11-bbc8-7edec5bb69b1",
    "status": "REJECTED",
    "moderationComment": "Identity document could not be verified",
    "rejectLabels": ["ID_VERIFICATION_FAILED"],
    "reviewRejectType": "FINAL",
    "timestamp": "2026-01-27T13:29:58.336Z"
  }
}

Webhook Outcomes

Webhook DecisionNotes
APPROVEDCardholder has passed KYC checks and can proceed to fetch the signed payload and create a card
REJECTEDCardholder has not passed KYC checks and is not allowed to create a card. Regenerate the SDK token and resubmit verification to try again

Step 7: Fetch the Signed Payload

The signed payload is a portable and tamper-proof JWT representation of an approved KYC application. It serves as the authorisation evidence for proceeding with card issuance through the Reap CaaS API.


Call the Fetch Signed Payload Endpoint

Use GET /entity/entityId/signed-payload to retrieve the signed payload associated with the approved KYC application.


Sample Request (cURL)

curl --request GET \
  --url https://sandbox-compliance.api.reap.global/entity/entityId/signed-payload \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-reap-api-key: ********'

Sample Response

{
  "firstName": "Jack",
  "lastName": "Sam Ong",
  "dob": "1994-06-18",
  "idDocumentType": "Passport",
  "idDocumentNumber": "K1234567",
  "residentialAddress": {
    "line1": "Flat 1208, 350, TIFF Bell Lightbox, King Street West",
    "line2": "Downtown",
    "city": "Toronto",
    "country": "CAN",
    "postalCode": "M5V 3L9"
  },
  "expiresAt": "2026-03-10T09:18:51.998Z",
  "signature": "bd6565bfb621f6321095e7dc574ea52b3829e29a732440170794fabfc8dec..."
}

Key Output

Parameter NameTypeDescription
firstNamestringVerified first name from the approved KYC record
lastNamestringVerified last name from the approved KYC record
dobstringDate of birth (Format: YYYY-MM-DD)
idDocumentTypestringType of government-issued ID used for verification
idDocumentNumberstringVerified ID document number
residentialAddressobjectVerified residential address (line1, line2, city, country, postalCode)
expiresAtstringExpiry timestamp of the signed payload (Format: ISO 8601)
signaturestringCryptographic signature ensuring payload integrity and authenticity

residentialAddress (object)

Parameter NameTypeDescription
line1stringPrimary address line
line2stringSecondary address line
citystringCity of residence
countrystringISO 3166-1 alpha-3 country code
postalCodestringPostal or ZIP code

Step 8: Create Card

The signed payload returned in Step 7 must be passed into the Create Card endpoint with customerType = "Consumer" when creating a card for the verified cardholder.


Call the Create Card Endpoint

Use POST /cards to create the card with the signed payload included in the kyc object of the request body.


Sample Request (cURL)

curl --request POST \
  --url https://sandbox.api.reap.global/cards \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Accept-Version: v2.0' \
  --header 'x-reap-api-key: ********' \
  --data '{
    "customerType": "Consumer",
    "kyc": {
      "firstName": "Jack",
      "lastName": "Sam Ong",
      "dob": "1994-06-18",
      "idDocumentType": "Passport",
      "idDocumentNumber": "K1234567",
      "residentialAddress": {
        "line1": "Flat 1208, 350, TIFF Bell Lightbox, King Street West",
        "line2": "Downtown",
        "city": "Toronto",
        "country": "CAN",
        "postalCode": "M5V 3L9"
      },
      "expiresAt": "2026-03-10T09:18:51.998Z",
      "signature": "bd6565bfb621f6321095e7dc574ea52b3829e29a732440170794fabfc8dec..."
    },
    "...": "..."
  }'

Key Input

Parameter NameTypeDescription
customerTypestringCustomer type for the card set to Consumer for individual cardholders verified through KYCaaS

kyc (object)

Parameter NameTypeDescription
signaturestringSigned JWT returned from the signed-payload endpoint ensuring payload integrity and KYC approval

Sample Response

{
  "id": "fa1bcdae-c101-4986-b385-8083fb43a7ab"
}

Key Output

Parameter NameTypeDescription
idstringUnique identifier of the successfully created card

Scenarios

Scenario: Standard Onboarding

  • Create the individual entity with POST /entity using type: INDIVIDUAL
  • Generate the SumSub WebSDK token via POST /entity/entityId/kyc with verificationFlow only and without including binCountry
  • Launch the SumSub WebSDK on the frontend so the cardholder completes identity document and liveness verification
  • Receive the APPROVED decision via the registered webhook
  • Fetch the signed payload via GET /entity/entityId/signed-payload
  • Pass the signed payload into POST /cards with customerType = "Consumer" to create the card

Scenario: Jurisdiction-Specific BIN Onboarding (MEX example)

  • Create the individual entity with POST /entity using type: INDIVIDUAL
  • Generate the SumSub WebSDK token via POST /entity/entityId/kyc with verificationFlow and binCountry = "MEX"
  • Launch the SumSub WebSDK on the frontend so the cardholder completes identity document and liveness verification
  • Receive the APPROVED decision via the registered webhook
  • Fetch the signed payload via GET /entity/entityId/signed-payload
  • Pass the signed payload into POST /cards with customerType = "Consumer" to create the card

Common Errors

ErrorCauseResolution
401 UnauthorizedMissing or invalid API keyCheck x-reap-api-key and confirm the API key matches the environment
Entity not foundentityId is unknown, deleted, or belongs to a different businessConfirm the entityId returned from POST /entity and re-issue the request
Invalid verificationFlowValue submitted is not EMPLOYEE or CUSTOMERSubmit a supported verificationFlow value
Signed payload unavailableKYC application is not yet APPROVEDWait for the APPROVED webhook before calling the signed payload endpoint

TL;DR

  • KYCaaS is a single guided workflow for end-to-end cardholder identity verification under the Reap Compliance API
  • Generate sandbox and production API keys from the Reap Card Issuance Dashboard and register a webhook subscription for the account_status_change event type
  • Create the individual entity first with POST /entity and type: INDIVIDUAL and use the returned id as the entityId for all subsequent calls
  • Generate the SumSub WebSDK token via POST /entity/entityId/kyc using verificationFlow (EMPLOYEE or CUSTOMER)
  • Additionally include binCountry for cardholders issued under a BIN that requires jurisdiction-specific KYC handling currently MEX and exclude the field for all other countries
  • Launch the SumSub WebSDK on the frontend so the cardholder completes identity document and liveness verification
  • Fetch the signed payload via GET /entity/entityId/signed-payload on the APPROVED webhook and pass it into POST /cards with customerType = "Consumer" to create the card