Universal KYC
Purpose: Onboard individual cardholders into the Reap platform using one canonical workflow that consolidates entity identification, identity attributes, residential address, liveness outcome, provider verification result, jurisdiction-specific data where required, and supporting documentation against typed requirement slugs.
When to Use This
Use this guide when you need to:
- Onboard a new individual cardholder to Reap as an
INDIVIDUALentity - Submit a canonical KYC Pack covering identity, identification document, residential address, liveness result, and the configured KYC provider's verification outcome
- Submit jurisdiction-specific data for cardholders issued under a MEX BIN (
binCountry = MEX) - Upload supporting KYC documents (ID Document, Proof of Address, and the CURP Document for MEX) against typed requirement slugs
- Retrieve the signed KYC payload after approval for downstream card issuance under Reap's non-BIN sponsorship model
- Correct or update an earlier KYC submission by appending a new full payload
Overview
Universal KYC brings the full cardholder onboarding journey into a single structured workflow under the Reap Compliance API. Instead of managing multiple independent requirement submissions, integrators submit one canonical payload for the case. This payload, known as the KYC Pack includes identity information, identification documents, residential address details, and liveness results. Integrators also upload supporting documents using KYC specific requirement slugs. The payload is then completed with the verification outcome from the configured provider.
Every submission must be linked to a single individual entity created through the existing Entity resource with type: INDIVIDUAL. Each submission is stored as a typed record and serves as the authoritative audit ready source of truth throughout the entire case lifecycle.
The submission payload also powers Reap’s jurisdiction specific rule engine orchestration, enabling conditional compliance flows such as:
- MEX specific CURP validation requirements
- mandatory
jurisdictionDatahandling for applicable regions - country dependent onboarding and verification flows
The signed payload becomes a portable and tamper evident authorisation artefact that supports downstream card issuance and related provisioning workflows for non BIN sponsorship programs after approval.
Prerequisites
- Compliance approval from Reap for the use of Universal KYC for the program
- An established KYC provider already in place
- Agreement that Reap retains the final approval authority for card issuance under its non-reliance model
- A valid Reap API key is required to authenticate all Universal KYC requests
- The
externalIdvalue to be used as the integrator's correlation reference for the cardholder
Please contact your account manager if you have any questions about the Universal KYC approval process.
This guide contains two post-approval paths:
- Non-BIN sponsorship clients: must complete Step 5 (Fetch the Signed Payload) and Step 6 (Create Card).
- BIN sponsorship clients (e.g. Bybit): do not need to complete Steps 5 and 6. They may use the verified KYC information directly in their own downstream card issuance flow after KYC is approved.
Key Concepts
Individual Entity
- The anchor record for all Universal KYC submissions
- Created via
POST /entitywithtype: INDIVIDUAL - Returns an
id(used asentityIdin all subsequent calls) and echoes back the integrator-suppliedexternalId
KYC Pack
- Canonical typed payload capturing the cardholder's identity, identification document, residential address, liveness result, and the configured KYC provider's verification outcome
- Submitted via
POST /entity/entityId/ukyc
BIN Country and Jurisdiction Data
binCountrydeclares the ISO 3166-1 alpha-3 country code of the issuing BINbinCountrydetermines the jurisdiction-specific KYC flow applied to the cardholder (verification rules and the structure ofjurisdictionData)binCountryand a matchingjurisdictionData.<COUNTRY>block are required when the issuing BIN belongs to a jurisdiction with jurisdiction-specific requirements currentlyMEXand both fields are excluded for all other BIN countriesbinCountryis independent of the cardholder'sidentity.nationality. Document requirements that are tied to nationality (such as the CURP document for Mexican nationals) are driven byidentity.nationality, not bybinCountry.
Nationality-driven Requirements
identity.nationalitydeclares the ISO 3166-1 alpha-3 nationality of the cardholder- Some supporting documents are required by nationality rather than by BIN and currently
ukyc-curp-documentis required whenidentity.nationality = "MEX"for Mexican nationals - These requirements are independent of
binCountrywhere a Mexican national issued on a non-MEX BIN still uploads the CURP document and a non-Mexican national issued on a MEX BIN does not
Provider Verification
- Verification result block submitted alongside the KYC Pack capturing the configured KYC provider's overall outcome
- Carries the provider name, an overall verification status, and a free-form
datapayload that retains the provider's own correlation evidence
Signed Payload
- Portable, tamper-proof representation of an approved KYC application
- Retrieved via
GET /entity/entityId/signed-payloadonce the case is approved - Serves as the authorisation evidence for proceeding with card issuance under Reap's non-BIN sponsorship model
Requirement Slug
- Typed identifier for each supporting document category (
ukyc-id-document,ukyc-proof-of-address-document,ukyc-curp-document) - Drives document association and compliance review routing
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
- Create the individual entity via
POST /entitywithtype: INDIVIDUAL - Submit the KYC Pack via
POST /entity/entityId/ukycand includebinCountryandjurisdictionDataonly whenbinCountry = MEX - Upload supporting KYC documents via
POST /entity/entityId/requirement-slug/requirementSlug/upload:ukyc-id-document: required for all cardholdersukyc-proof-of-address-document: required for all cardholdersukyc-curp-document: required only whenidentity.nationality = "MEX"for Mexican nationals and independent ofbinCountry
- Receive the KYC decision via webhook notification (
APPROVEDorREJECTED) - Fetch the signed payload via
GET /entity/entityId/signed-payloadonly for non-BIN sponsorship programs - Create the card via
POST /cardsusing the signed payload only for non-BIN sponsorship programs
API Summary
| Action | Endpoint | Method | Use Case |
|---|---|---|---|
| Create individual entity | /entity | POST | Register an individual-type entity to anchor all subsequent KYC submissions |
| Submit KYC Pack | /entity/entityId/ukyc | POST | Submit the canonical identity, document, address, liveness, provider verification result, and (for MEX) jurisdiction data |
| Upload KYC supporting documents | /entity/entityId/requirement-slug/requirementSlug/upload | POST | Upload the ID Document, Proof of Address, and (for MEX) the CURP Document to a typed slug |
| Fetch signed payload | /entity/entityId/signed-payload | GET | Retrieve the portable, signed authorisation payload after KYC approval (non-BIN sponsorship) |
| Create card | /cards | POST | Create a card by passing the signed KYC payload to the card issuance API (non-BIN sponsorship) |
Universal KYC Onboarding
Step 1: Register and Create Individual Entity
Create an individual-type entity to anchor the subsequent KYC submissions. The id returned by this call is used as entityId in all subsequent Universal KYC 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 Name | Type | Description |
|---|---|---|
type | string | Set the entity type to INDIVIDUAL for KYC verification |
Sample Response
{
"id": "5f54bcf9-5a21-4f76-a819-6a65a8c238b8",
"externalId": "CUSTOMER-DEMO-10001",
"businessId": "e10e9f95-f256-4c47-bcf6-a6029e09c3aa",
"type": "INDIVIDUAL"
}Key Output
| Parameter Name | Type | Description |
|---|---|---|
id | string | Unique identifier generated by Reap for the created entity. Used as entityId in all subsequent calls |
externalId | string | The external reference ID provided during entity creation |
businessId | string | Unique identifier for the associated Reap business account |
type | string | Type of entity created |
Step 2: Submit the KYC Pack
Submit the canonical KYC payload containing identity, identification document, residential address, liveness result, and the configured provider's verification outcome in a structured, typed JSON body. The request must additionally include binCountry: MEX and jurisdictionData.MEX for cardholders issued under a MEX BIN. Both fields are excluded for all other countries.
Call the Submit KYC Pack Endpoint
Use POST /entity/entityId/ukyc to submit the KYC Pack against the individual entity created in the previous step.
cardProcessorPublicTokenis only required when the client is under BIN sponsorship.
Sample Request (cURL) — MEX BIN Country (MEX national)
The payload must include jurisdictionData.MEX when binCountry = MEX.
curl --request POST \
--url https://sandbox-compliance.api.reap.global/entity/entityId/ukyc \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-UKYC-Version: 1' \
--header 'x-reap-api-key: ********' \
--data '{
"externalUserId": "user_12345",
"cardProcessorPublicToken": "processor_public_token_123",
"binCountry": "MEX",
"provider": {
"name": "SUMSUB",
"status": "APPROVED",
"data": [
{ "key": "sumsubApplicantId", "value": "65b1f3e1c4d2b5a6f7e8d9c0" }
]
},
"identity": {
"firstName": "Jorge",
"middleName": "Luis",
"lastName": "Hernández",
"fullName": "Jorge Luis Hernández",
"dob": "1990-04-12",
"nationality": "MEX"
},
"document": [
{
"documentCategory": "IDV",
"type": "PASSPORT",
"number": "A12345678",
"country": "MEX",
"issuingDate": "2020-01-01",
"expiryDate": "2030-01-01"
},
{
"documentCategory": "POA",
"type": "UTILITY_BILL",
"number": "UB-2024-987654",
"country": "MEX",
"issuingDate": "2024-09-15"
}
],
"address": {
"street": "Av. Paseo de la Reforma 123",
"town": "Ciudad de México",
"state": "CDMX",
"postCode": "06600",
"country": "MEX"
},
"liveness": {
"result": "APPROVED",
"checkedAt": "2026-05-09T10:00:00Z"
},
"jurisdictionData": {
"MEX": {
"countryOfBirth": "MEX",
"economicActivity": "Retail trade",
"phone": "+525512345678",
"email": "[email protected]",
"authorityIdIssuer": "INE",
"taxId": "XAXX010101000",
"curp": "XAXX010101HDFXXX00",
"uboAttestation": true
}
}
}'When
binCountry = "MEX"andidentity.nationality = "MEX", a CURP document upload requirement is automatically created inPENDINGstatus and must be fulfilled viaPOST /entity/entityId/requirement-slug/ukyc-curp-document/upload.
Inside
jurisdictionData.MEX, the fieldsphone,taxId, andcurpare required only whenidentity.nationality = "MEX"and should be excluded for non-Mexican nationals issued under a MEX BIN.
Sample Request (cURL) (Other Country)
The binCountry field is not required and jurisdictionData is not required when binCountry is not MEX. Both fields are excluded from the payload.
curl --request POST \
--url https://sandbox-compliance.api.reap.global/entity/entityId/ukyc \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-UKYC-Version: 1' \
--header 'x-reap-api-key: ********' \
--data '{
"externalUserId": "user_12345",
"cardProcessorPublicToken": "processor_public_token_123",
"provider": {
"name": "SUMSUB",
"status": "APPROVED",
"data": [
{ "key": "sumsubApplicantId", "value": "65b1f3e1c4d2b5a6f7e8d9c0" }
]
},
"identity": {
"firstName": "Jack",
"middleName": "Sam",
"lastName": "Ong",
"fullName": "Jack Sam Ong",
"dob": "1994-06-18",
"nationality": "USA"
},
"document": [
{
"documentCategory": "IDV",
"type": "PASSPORT",
"number": "123456789",
"country": "USA",
"issuingDate": "2020-01-01",
"expiryDate": "2030-01-01"
},
{
"documentCategory": "POA",
"type": "UTILITY_BILL",
"number": "UB-2024-123456",
"country": "USA",
"issuingDate": "2024-09-15"
}
],
"address": {
"street": "123 Main Street",
"town": "New York",
"state": "NY",
"postCode": "10001",
"country": "USA"
},
"liveness": {
"result": "APPROVED",
"checkedAt": "2026-05-09T10:00:00Z"
}
}'Key Input
| Parameter Name | Type | Description |
|---|---|---|
cardProcessorPublicToken | string | Card processor public token required only for clients operating under BIN sponsorship. This is the 9-digit numeric public token for the card processor account and not the 16-digit tokenised PAN. |
binCountry | string | ISO 3166-1 alpha-3 BIN country code required only when issuing under a Mexico BIN (MEX) and excluded for all other BIN countries to drive jurisdiction-specific rule engine branching |
provider | object | Configured KYC provider verification outcome based on the selected provider below |
jurisdictionData | object | Jurisdiction-specific block keyed by ISO 3166-1 alpha-3 country code that is required when binCountry is set (currently MEX) and should be excluded for all other countries |
provider (object)
provider (object)| Parameter Name | Type | Description |
|---|---|---|
name | string | Configured KYC provider name such as SUMSUB or JUMIO |
status | string | Overall verification status with enum values APPROVED, REJECTED, WARNING, and NOT_EXECUTED |
jurisdictionData (object)
jurisdictionData (object)| Parameter Name | Type | Description |
|---|---|---|
MEX | object | Jurisdiction block required when binCountry is MEX and reserved for jurisdiction-specific extensions with support for an empty object () submission today |
Sample Response
{}Step 3: Upload KYC Documents
Upload supporting documents for KYC requirement slugs using the shared file upload endpoint to retain verifiable evidence for audit and compliance reviews.
Call the File Upload Endpoint
Use POST /entity/entityId/requirement-slug/requirementSlug/upload to upload a file for a KYC document slug.
Sample Request (cURL) (ID Document)
curl --request POST \
--url https://sandbox-compliance.api.reap.global/entity/entityId/requirement-slug/ukyc-id-document/upload \
--header 'Accept: application/json' \
--header 'Content-Type: multipart/form-data' \
--header 'x-reap-api-key: ********' \
--form 'file=@"passport.jpg"'Sample Request (cURL) (Optional memberId)
memberId)curl --request POST \
--url 'https://sandbox-compliance.api.reap.global/entity/entityId/requirement-slug/ukyc-id-document/upload?memberId=member_456' \
--header 'Accept: application/json' \
--header 'Content-Type: multipart/form-data' \
--header 'x-reap-api-key: ********' \
--form 'file=@"passport.jpg"'Key Input
| Parameter Name | Type | Description |
|---|---|---|
requirementSlug | string | Path parameter specifying the KYC document type the file is uploaded against: ukyc-id-document and ukyc-proof-of-address-document for all cardholders, and ukyc-curp-document only when identity.nationality = "MEX" |
memberId | string | Optional query parameter specifying the member record to associate the uploaded document with |
file | file | The file to upload as multipart/form-data |
Use repeated POST calls with the appropriate
requirementSlug:
ukyc-id-documentandukyc-proof-of-address-documentfor every cardholderukyc-curp-documentonly when the cardholder'sidentity.nationalityis"MEX"- This requirement is driven by nationality and not by
binCountry
Sample Response
{}KYC Document Slugs
The requirementSlug path parameter accepts the values listed below. Each slug routes the uploaded file to a specific document category for compliance review.
| Slug | Category | Description |
|---|---|---|
ukyc-id-document | Mandatory KYC | Government-issued identification document (e.g. passport, ID card, or driver's licence) |
ukyc-proof-of-address-document | Mandatory KYC | Proof of residential address (e.g. utility bill or bank statement) |
ukyc-curp-document | Conditional (nationality) | CURP (Clave Única de Registro de Población) document required only when identity.nationality = "MEX" for Mexican nationals and independent of binCountry |
File Upload Constraints
| Constraint | Limit |
|---|---|
| Allowed extensions | Supported file formats are .jpg, .jpeg, .png and .pdf while all other extensions are rejected with HTTP 400 |
| Maximum file size | Up to 10 MB per file is accepted and uploads exceeding this limit are rejected |
Step 4: KYC Decision
The application enters final KYC review after the KYC Pack and required documents are submitted with the decision result sent asynchronously via webhook.
Only applications with an
APPROVEDstatus can proceed to Step 5 (Signed Payload Retrieval) and Step 6 (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": "Universal KYC requirement rejected",
"entityId": "6c539925-f00c-4b11-bbc8-7edec5bb69b1",
"status": "REJECTED",
"moderationComment": "Country of residence (IND) is prohibited",
"rejectLabels": ["PROHIBITED_RESIDENCE"],
"reviewRejectType": "FINAL",
"timestamp": "2026-01-27T13:29:58.336Z"
}
}Webhook Outcomes
| Webhook Decision | Notes |
|---|---|
APPROVED | Cardholder has passed KYC checks and can proceed to create a card |
REJECTED | Cardholder failed KYC checks and is not eligible to create a card but requirements and documents may be resubmitted for future review |
Step 5: Fetch the Signed Payload
The signed payload is a portable and tamper-proof representation of an approved KYC application. It serves as the authorisation evidence for proceeding with card issuance under Reap's non-BIN sponsorship model.
BIN sponsorship clients (e.g. Bybit) are not required to complete this step. Verified KYC information can be used directly in the downstream card issuance flow once KYC approval is obtained.
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?featureSlug=universal-kyc-card-issuance-kyc-api' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-reap-api-key: ********'Key Input
| Parameter Name | Type | Description |
|---|---|---|
featureSlug | string | Query parameter specifying the featureSlug value universal-kyc-card-issuance-kyc-api |
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 Name | Type | Description |
|---|---|---|
firstName | string | Verified first name from the approved KYC record |
lastName | string | Verified last name from the approved KYC record |
dob | string | Date of birth (Format: YYYY-MM-DD) |
idDocumentType | string | Type of government-issued ID used for verification |
idDocumentNumber | string | Verified ID document number |
residentialAddress | object | Verified residential address (line1, line2, city, country, postalCode) |
expiresAt | string | Expiry timestamp of the signed payload (Format: ISO 8601) |
signature | string | Cryptographic signature ensuring payload integrity and authenticity |
residentialAddress (object)
residentialAddress (object)| Parameter Name | Type | Description |
|---|---|---|
line1 | string | Primary address line |
line2 | string | Secondary address line |
city | string | City of residence |
country | string | ISO 3166-1 alpha-3 country code |
postalCode | string | Postal or ZIP code |
Step 6: Create Card
The signed payload returned in Step 5 must be passed into the Create Card endpoint when creating a card.
BIN sponsorship clients (e.g. Bybit) do not need to complete this step and may use the verified KYC information directly in the downstream card issuance flow after KYC approval.
Call the Create Card Endpoint
Use POST /cards to create the card and include the signed payload in the request body.
Sample Request (cURL)
curl --request POST \
--url https://sandbox-compliance.api.reap.global/cards \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Accept-Version: v2.0' \
--header 'x-reap-api-key: ********' \
--data '{
"...": "...",
"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
kyc (object)
kyc (object)| Parameter Name | Type | Description |
|---|---|---|
kyc.signature | string | Signed JWT returned from the signed-payload endpoint ensuring payload integrity and KYC approval |
Sample Response
{
"id": "fa1bcdae-c101-4986-b385-8083fb43a7ab"
}Key Output
| Parameter Name | Type | Description |
|---|---|---|
id | string | Unique identifier of the successfully created card |
Scenarios
Scenario: Standard Onboarding
- Create the individual entity with
POST /entityusingtype: INDIVIDUAL - Submit the KYC Pack via
POST /entity/entityId/ukycwithout includingbinCountryorjurisdictionData - Upload the ID Document (
ukyc-id-document) and Proof of Address (ukyc-proof-of-address-document) - Fetch the signed payload via
GET /entity/entityId/signed-payloadon theAPPROVEDwebhook - Pass the signed payload to
POST /cardsto create the card
Scenario: BIN Sponsorship Onboarding (MEX BIN, MEX National)
- Create the individual entity with
POST /entityusingtype: INDIVIDUAL - Submit the KYC Pack via
POST /entity/entityId/ukycincluding thecardProcessorPublicToken,binCountry = "MEX",jurisdictionData.MEX, andidentity.nationality = "MEX" - Upload
ukyc-id-documentandukyc-proof-of-address-document(required for every cardholder) - Upload
ukyc-curp-document(required becauseidentity.nationality = "MEX") - Use the verified KYC information directly in the BIN sponsor's downstream card issuance flow without requiring steps 5 and 6
Common Errors
| Error | Cause | Resolution |
|---|---|---|
| 401 Unauthorized | Missing or invalid API key | Check x-reap-api-key |
| Entity not found | entityId is unknown, deleted, or belongs to a different business | Confirm the entityId returned from POST /entity and re-issue the request |
| Unsupported file extension | Uploaded file extension is not .jpg, .jpeg, .png, or .pdf | Re-upload using a supported file format |
TL;DR
- Universal KYC is a single canonical workflow for end-to-end cardholder onboarding under the Reap Compliance API
- Create the individual entity first with
POST /entityandtype: INDIVIDUALand use the returnedidas theentityIdfor all subsequent calls - Submit the KYC Pack via
POST /entity/entityId/ukyc(identity, document, address, liveness, and provider verification result) - Additionally include
binCountry: "MEX"andjurisdictionData.MEXfor MEX BIN cardholders while excluding both fields for all other countries - Upload supporting documents via
POST /entity/entityId/requirement-slug/requirementSlug/upload:ukyc-id-documentandukyc-proof-of-address-documentfor all cardholders plusukyc-curp-documentonly whenidentity.nationality = "MEX" - Non-BIN sponsorship clients fetch the signed payload via
GET /entity/entityId/signed-payloadon theAPPROVEDwebhook and pass it intoPOST /cardswhile BIN sponsorship clients use the verified KYC information directly in the downstream card issuance flow
Demo
For a fully interactive demo, see below:
Updated 2 days ago
