Verified Token Sharing
Reuses an existing Sumsub verification by ingesting a share token, holding the applicant to a Reap-defined Sumsub Partner Level, and returning a signed identity payload once Reap has completed its checks.
Purpose: Onboard an individual already verified in Sumsub by importing a share token, waiting for Reap's verification webhook and retrieving a tamper-evident signed identity payload for downstream card issuance. Reap enforces its own verification standard and issues the final decision.
When to Use This
TThis guide is intended for clients already using the Sumsub system who want to avoid repeating the KYC process for applicants. Verified token sharing lets Reap reuse an applicant's existing Sumsub verification through a share token, so the applicant does not need to complete the KYC process again — provided the verification was performed against a Reap-defined Sumsub Partner Level.
Use this guide when you need to:
- Reuse an applicant's completed Sumsub verification instead of collecting identity data again
- Ingest a single Sumsub share token synchronously and receive an immediate processing result
- Associate one or more card processor public tokens with the entity at ingestion time
- Wait for Reap's asynchronous verification-completed webhook before continuing
- Retrieve the cryptographically signed identity payload for an entity once verification is complete
Overview
Verified Token Sharing allows integrators to share an already-verified applicant with Reap using a SumSub share token, avoiding the need to resubmit identity details and documents.
Reap imports the shared applicant, validates it against a Reap-defined Sumsub Partner Level, and communicates the final outcome asynchronously. The integrator can retrieve a signed identity payload containing the verified identity information once the outcome is APPROVED.
The flow is designed to support clear request tracking, consistent error handling, and secure sharing of verified identity data between systems.
Prerequisites
- Confirmation with Reap Account Manager on using Verified Token Sharing for the program
- A signed Sumsub Reusable KYC Agreement authorising the donor company as the donor and Reap as the recipient
- Reap added as an authorised recipient in the donor Sumsub account using the token provided by the Reap Account Manager
- An applicant already verified in Sumsub, with a share token generated for that applicant specifying Reap as the recipient via
forClientId = reap.global_116803 - A registered webhook endpoint. Reap's decision is delivered by webhook and is not available from any other endpoint
- A valid Reap API key to authenticate every request via the
x-reap-api-keyheader - Use the
externalIdvalue as the correlation reference for the entity.
An ingestion returning
status: "completed"confirms only that the share token was accepted and processed. The final verification decision is delivered separately via webhook, and the signed identity payload can be retrieved only after that decision is complete.
Key Concepts
Share Token
- Short-lived token issued by Sumsub that represents an already-verified applicant
- Must be generated with Reap as the recipient by setting forClientId = reap.global_116803
- Expires 1,200 seconds (20 minutes) after generation and must be shared with Reap before expiry
- Supplied as shareToken in the ingestion request and consumed on first successful use
- A consumed token cannot be reused and a fresh token is required for each new attempt
External ID
- Unique identifier for the applicant within the originating system
- Supplied as externalId and echoed back in every ingestion response
- Correlates the Reap entity with the internal record
- Must remain the same for the same cardholder across every card lifecycle event
Entity ID
- Reap's UUID for the entity created or updated by the ingestion
- Returned as entityId in the ingestion response
- Used as the entityId path parameter when retrieving the signed identity payloadRequest ID
Signed Identity Payload
- Portable, tamper-evident representation of the verified identity for an entity
- Retrieved via
GET /entity/entityId/signed-payloadonce Reap's decision is APPROVED - Carries the verified identity fields, an
expiresAttimestamp, and a cryptographicsignature - Required at card creation for standard card issuance programs where Reap sits in the card creation path. Not used by BIN sponsorship programs
Enforced Verification Level
- Reap enforces its shared Partner Level for every ingested applicant using an exact match on the level name
- The enforced levels are
KYC via APIandKYC via API (with POA) - A share token generated against any other level fails ingestion with the
SHARE_TOKEN_LEVEL_MISMATCHerror - An applicant that does not meet the enforced level is rejected on the verification webhook with the
LEVEL_ENFORCED_MISMATCHlabel and aRETRYreject type
Flow Overview
- Register a webhook endpoint via
POST /notificationto receiveaccount_status_changeevents - Ingest the Sumsub share token via
POST /entity/kyc/import/sync, supplyingexternalIdandshareToken, pluscardProcessorPublicToken, which is mandatory for BIN sponsorship clients - Receive Reap's verification webhook once the decision is made
- Retrieve the signed identity payload via
GET /entity/entityId/signed-payloadusing the entity's ReapentityId - Create the card via POST /cards, passing the signed payload into the kyc object
API Summary
| Action | Endpoint | Method | Use Case |
|---|---|---|---|
| Register webhook notifications | /notification | POST | Subscribe a webhook endpoint to receive account_status_change events |
| Ingest Sumsub share token | /entity/kyc/import/sync | POST | Synchronously import a single verified Sumsub share token against an entity |
| Retrieve signed identity payload | /entity/entityId/signed-payload | GET | Retrieve the portable, signed identity payload once Reap's decision is APPROVED |
| Create card | /cards | POST | Create a card by passing the signed identity payload to the card issuance API |
Verified Token Sharing
Step 1: Set Up Webhooks
Register a webhook endpoint with Reap's Compliance API to receive Reap's KYC decision. Registration is required before any share token is ingested — the decision is delivered by webhook and is not retrievable from another endpoint.
Call the Notification Endpoint
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 Name | Type | Description |
|---|---|---|
notificationTypes | array of string | List 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 Name | Type | Description |
|---|---|---|
id | string | Unique identifier for the notification subscription. |
channel | string | Notification delivery channel configured for the subscription, for example, WEBHOOK. |
types | array of string | List of notification event types subscribed to. |
config | object | Configuration details for the notification channel. |
config.webhook.url | string | Webhook endpoint URL where notification events will be delivered. |
createdAt | string | Timestamp indicating when the notification subscription was created. Format: ISO 8601. |
Step 2: Ingest the Sumsub Share Token
Synchronously ingest a single Sumsub share token for an applicant that has already been verified. The record is processed immediately, and the response returns a completed status alongside a requestId for support correlation. The supplied externalId becomes the correlation reference for the entity and is returned back on every response.
Call the Sync Ingestion Endpoint
Use POST /entity/kyc/import/sync to synchronously ingest a single Sumsub share token against the entity identified by the externalId.
Sample Request (cURL)
curl --request POST \
--url https://sandbox-compliance.api.reap.global/entity/kyc/import/sync \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-reap-api-key: ********' \
--data '{
"externalId": "ef88fd57-26cf-415d-a112-941732c55350",
"shareToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"cardProcessorPublicToken": "123456789|987654321"
}'Key Input
| Parameter Name | Type | Description |
|---|---|---|
externalId | string | Unique identifier for the entity in the integrator’s system returned back in every response |
shareToken | string | Share token generated by Sumsub for the verified applicant consumed on first successful use |
cardProcessorPublicToken | string | Card processor public token to associate with the entity. Mandatory for BIN sponsorship clients |
cardProcessorPublicTokenis mandatory for BIN sponsorship clients. The value must be the 9 digit numeric public token for the card processor account, not the 16 digit tokenised PAN. For BIN sponsorship programs this token serves as linkage between the KYC record and the card
Sample Response
{
"externalId": "ef88fd57-26cf-415d-a112-941732c55350",
"status": "completed",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
"entityId": "b3d7e2f1-4a5c-6d8e-9f0a-1b2c3d4e5f6a"
}Key Output
| Parameter Name | Type | Description |
|---|---|---|
externalId | string | Echoed identifier provided in the request |
status | string | Processing status. completed indicates the share token was ingested successfully, not approved |
requestId | string | Correlation identifier echoed for support and log tracing |
entityId | string | Reap's UUID for the entity, used as the path parameter in Step 4 |
A
completedstatus confirms only that the share token was accepted and processed. It is not an approval. Reap's decision is delivered separately via webhook, and the signed identity payload can be retrieved only after that decision isAPPROVED
Step 3: Receive the Verification Webhook
Reap validates the shared applicant against the enforced Partner Level and notifies the registered webhook endpoint with the decision. Continue to Step 4 only after receiving an APPROVED decision.
Sample Notification 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": "Card Issuance KYC API access updated",
"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": "938c65f7-2aad-494d-b488-5256c4cfc370",
"message": "Card Issuance KYC API access updated",
"entityId": "6ac28264-c21b-4757-b141-1efce00adce6",
"timestamp": "2026-01-27T13:27:51.027Z",
"status": "REJECTED",
"moderationComment": "Sumsub did not approve the applicant.",
"rejectLabels": ["DOCUMENT_QUALITY"],
"reviewRejectType": "FINAL"
}
}Webhook Outcomes
| Webhook Decision | reviewRejectType | Notes |
|---|---|---|
APPROVED | The applicant met Reap's enforced level and its checks. Proceed to Step 4 | |
| REJECTED | RETRY | Correctable. Re-run the cardholder through the correct Partner Level, or correct the underlying issue, then generate a fresh share token and re-ingest |
REJECTED | FINAL | Not correctable by resubmission of the same information |
Rejection Reasons
The webhook payload includes the rejection reason through the moderationComment, rejectLabels, and reviewRejectType fields when the decision is REJECTED.
| Reason | moderationComment | rejectLabels | reviewRejectType |
|---|---|---|---|
| Applicant not approved | Sumsub did not approve the applicant. | Labels depend on Sumsub’s returned reason. | FINAL |
| Applicant not approved and level mismatch | Sumsub did not approve the applicant and the applicant does not meet the Reap enforced level. | Labels depend on Sumsub’s returned reason. | FINAL |
| Level mismatch | Applicant does not meet the Reap enforced level. | ['LEVEL_ENFORCED_MISMATCH'] | RETRY |
| Review incomplete | Sumsub applicant review is incomplete. | ['INCOMPLETE_SUBMISSION'] | RETRY |
| Review status unknown | Sumsub applicant review status is unknown. | ['INCOMPLETE_SUBMISSION'] | RETRY |
| Approved but validation failed | Applicant is approved and meets the enforced level, but validation failed. | ['INCOMPLETE_SUBMISSION'] | RETRY |
| Sumsub copy applicant API error | Failed to copy the Sumsub applicant. | ['INCOMPLETE_SUBMISSION'] | RETRY |
| Database error | Failed to complete required database calls. | ['INCOMPLETE_SUBMISSION'] | RETRY |
Step 4: Retrieve the Signed Identity Payload
The signed identity payload is Reap's tamper-evident attestation that the entity passed Reap's checks. Retrieve it after the APPROVED webhook. It carries the verified identity fields, an expiry, and a cryptographic signature.
Call the Signed Payload Endpoint
Use GET /entity/entityId/signed-payload to retrieve the signed identity payload for the entity.
Sample Request (cURL)
curl --request GET \
--url https://sandbox-compliance.api.reap.global/entity/entityId/signed-payload \
--header 'Accept: 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 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). Re-fetch the payload if card creation is queued beyond it |
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 5: Create Card
Pass the signed payload returned in Step 4 into the Create Card endpoint. The recommended pattern is to copy the full signed-payload response into the kyc object rather than re-entering fields manually, which surfaces data and eligibility problems at Step 4 instead of at card creation.
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 |
| kyc.expiresAt | string | Expiry timestamp copied from the signed-payload response (Format: ISO 8601) |
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 1: Standard Card Issuance Clients
- Generate a share token in Sumsub for the applicant, verified against a Reap-defined Partner Level
- Ingest it via
POST /entity/kyc/import/syncwith theexternalIdand theshareToken, receiving status: "completed" - Wait for Reap's APPROVED webhook
- Retrieve the signed identity payload via
GET /entity/entityId/signed-payload - Create the card via
POST /cards, passing the payload into the kyc object
Scenario 2: BIN Sponsorship Client
- Generate a share token in Sumsub for the applicant, verified against a Reap-defined Partner Level
- Ingest it via
POST /entity/kyc/import/syncwith theexternalId, theshareToken, and thecardProcessorPublicToken - Wait for Reap's webhook for KYC decision. Every card must remain linked to an approved Reap KYC record via
cardProcessorPublicToken - Steps 4 and 5 do not apply. Reap is not in the card creation path, so there is no signed payload and no Create Card call
Common Errors
| Error | Cause | Resolution |
|---|---|---|
| 401 Unauthorized | Missing or invalid API key | Check the x-reap-api-key header |
TL;DR
- Verified Token Sharing reuses an existing Sumsub verification through a single share token, where the applicant must have been verified against a Reap-defined Sumsub Partner Level
- Register a webhook endpoint with
POST /notificationto receiveaccount_status_changeevents before ingesting any share tokens - Ingest synchronously with
POST /entity/kyc/import/syncby supplyingexternalIdandshareTokenpluscardProcessorPublicToken, which is mandatory for BIN sponsorship clients, noting that acompletedstatus confirms ingestion rather than the final decision - Reap validates the applicant against the enforced level and delivers APPROVED or REJECTED by webhook, with reviewRejectType distinguishing a correctable RETRY from a non-correctable FINAL
- Retrieve the signed identity payload with
GET /entity/entityId/signed-payloadafter the APPROVED webhook, then pass it intoPOST /cards - BIN sponsorship programs skip Steps 4 and 5. Instead, every card must stay linked to an approved KYC record via
cardProcessorPublicToken
Updated about 1 month ago
