Sumsub Know Your Customer (KYC) Integration Guide
3. API Integration
The client backend creates the applicant, submits verification data, requests review, and retrieves the result through the Sumsub API.
Keep App Token and Secret Key on the server. The applicant experience in your product collects the data; it does not call Sumsub directly.
3.1 API Prerequisites
| Item | Requirement |
|---|---|
| App Token | Sumsub app token for the correct environment. Sandbox tokens usually begin with sbx: and production tokens with prd:. |
| Secret Key | Used to generate HMAC-SHA256 request signatures. |
| Base URL | https://api.sumsub.com. Environment is determined by token prefix, not a different hostname. |
| Level name | Pass <client>-kyc-individuals-address, <client>-kyc-individuals-address-tin, or <client>-kyc-individuals-poa-batch. Replace <client> with the client name prefix. Use <client>-kyc-individuals-address-tin for United States applicants. Use <client>-kyc-individuals-poa-batch for High Risk applicants. Use <client>-kyc-individuals-address for every other country. |
| HTTP client | Must support HTTPS, custom headers, JSON, multipart/form-data, and UTC-synced timestamps. |
Store credentials in a secrets manager. Never embed the app token or secret key in frontend or mobile code.
3.2 API Authentication
Every Sumsub API request requires the following headers:
| Header | Description |
|---|---|
X-App-Token | App token. |
X-App-Access-Ts | Unix timestamp in seconds, UTC. |
X-App-Access-Sig | Lowercase hex HMAC-SHA256 signature. |
Signature Format
payload = bytes(timestamp + METHOD + path + body)
signature = HMAC_SHA256(secretKey, payload) -> lowercase hexRules
METHODmust be uppercase, for exampleGET,POST, orPATCH.pathmust include the query string and must start with/.- For
multipart/form-data, sign the exact bytes sent on the wire. - For bodyless requests, omit the body from the signed payload.
3.3 API Flow Summary
- 1
Create applicant with the selected levelName, full fixedInfo, and metadata.
POST/resources/applicants?levelName=<client>-kyc-individuals-address - 2
Upload ID front.
POST/resources/applicants/{applicantId}/info/idDoc - 3
Upload ID back, when required.
POST/resources/applicants/{applicantId}/info/idDoc - 4
Check PoA status on
<client>-kyc-individuals-poa-batchonly.GET/resources/applicants/{applicantId}/requiredIdDocsStatus - 5
Upload dedicated PoA on
<client>-kyc-individuals-poa-batchif still required.POST/resources/applicants/{applicantId}/info/idDoc - 6
Upload selfie.
POST/resources/applicants/{applicantId}/info/idDoc - 7
Submit questionnaire.
POST/resources/applicants/{applicantId}/questionnaires - 8
Preflight required steps.
GET/resources/applicants/{applicantId}/requiredIdDocsStatus - 9
Request review.
POST/resources/applicants/{applicantId}/status/pending - 10
Await result.
GET polling or webhook/resources/applicants/{applicantId}/status or applicantReviewed webhook
Persist applicantId returned in Step 1 and map it to your externalUserId.
3.4 API Flow Diagram
The sequence below shows how the client system, Sumsub, and Payblr interact during API-based verification.
KYC API Integration
API-based verification sequence
Client
Client System
Provider
Sumsub
Platform
Payblr
3.5 Create Applicant with Full fixedInfo
Recommended single-shot approach: send the applicant profile, address, required metadata, and the selected levelName in the create applicant request. Include fixedInfo.tin only when the selected level requires TIN/SSN. A follow-up PATCH /fixedInfo is optional and normally used only when correcting or refreshing an existing applicant.
POST /resources/applicants?levelName=<client>-kyc-individuals-address
Content-Type: application/json
X-App-Token: <token>
X-App-Access-Ts: <unix-seconds>
X-App-Access-Sig: <signature>{
"externalUserId": "user-92847-unique",
"email": "anna.krause@example.com",
"phone": "+491701234567",
"lang": "en",
"metadata": [
{ "key": "sourceKey", "value": "<payblr-assigned-source-key>" },
{ "key": "partnerName", "value": "Payblr-YourCompany" },
{ "key": "cardHolderId", "value": "ch-92847" },
{ "key": "customerPartnerId", "value": "user-92847" }
],
"fixedInfo": {
"firstName": "Anna",
"middleName": "Marie",
"lastName": "Krause",
"dob": "1990-05-15",
"country": "DEU"
"addresses": [
{
"street": "Musterstrasse 1",
"town": "Berlin",
"state": "Berlin",
"country": "DEU",
"postCode": "10115"
}
]
}
}Expected response: 201 with the Sumsub applicant ID. Save that value as applicantId.
3.6 Optional PATCH fixedInfo
PATCH /resources/applicants/{applicantId}/fixedInfo is optional when the create applicant call already includes complete fixedInfo.
Use it when:
- Updating profile, address, or TIN/SSN on an existing applicant when that level requires it.
- Retrying after corrected data.
- Resuming a partially completed submission.
3.7 Upload Documents
Each file is sent as a separate multipart/form-data request.
POST /resources/applicants/{applicantId}/info/idDoc
Content-Type: multipart/form-data; boundary=----...
X-Return-Doc-Warnings: trueForm Parts
| Part | Content Type | Value |
|---|---|---|
metadata | application/json | JSON metadata object. |
content | Image MIME type | Binary image file. |
Common Metadata Examples
{
"idDocType": "ID_CARD",
"country": "DEU",
"idDocSubType": "FRONT_SIDE"
}
{
"idDocType": "ID_CARD",
"country": "DEU",
"idDocSubType": "BACK_SIDE"
}
{
"idDocType": "UTILITY_BILL",
"country": "DEU"
}
{
"idDocType": "SELFIE",
"country": "DEU"
}3.8 Submit Questionnaire
POST /resources/applicants/{applicantId}/questionnaires
Content-Type: application/jsonRequest body:
{
"id": "beforeWeFinishWeJust",
"sections": {
"workAndIncome": {
"items": {
"occupation": { "value": "Analyst" },
"industryYouWorkFor": { "value": "Finance and Insurance" },
"workStatus": { "value": "Full Time" }
}
},
"section2": {
"items": {
"sourceOfFunds": { "value": "Salary" },
"expectedMonthVolume": { "value": "$0 - $1,999" },
"expectedAnnualIncome": { "value": "$50,000 - $74,999" }
}
},
"cardholderAgreementA": {
"items": {
"cardTermsConditionsAccept": { "value": "true" }
}
}
}
}Expected response: 200 on success.
3.9 Preflight: Required Steps Status
GET /resources/applicants/{applicantId}/requiredIdDocsStatusInspect the response before moving the applicant to pending. Every required step should show as fulfilled. If a step is incomplete, Sumsub may not process the review correctly.
Use this call in integration tests and logging.
3.10 Request Review
Move the applicant to pending when all required data, documents, and questionnaire answers have been submitted.
POST /resources/applicants/{applicantId}/status/pendingOptional Query Parameter
?reason=Your+reason+stringExpected response: 200 when the applicant is queued for automated or manual review.
After this call, the applicant is locked for editing until the review completes or is reset.
3.11 Get Review Result
Option A: Polling
Polling is the simplest option to start during early integration.
GET /resources/applicants/{applicantId}/statusPoll every 5 to 10 seconds until reviewStatus is completed.
Option B: Webhooks
Webhooks are recommended for production result handling. Sumsub sends the applicantReviewed result to Payblr, and Payblr processes the final KYC outcome according to the configured onboarding flow.
Polling is acceptable for early integration, but production implementations should use the agreed Payblr result delivery process.
Example Completed Response
{
"reviewStatus": "completed",
"reviewResult": {
"reviewAnswer": "GREEN",
"reviewRejectType": null,
"rejectLabels": []
}
}Review Answer Values
| reviewAnswer | Meaning |
|---|---|
GREEN | Approved. |
RED | Rejected or retry required. Inspect rejectLabels and reviewRejectType. |
Review Reject Type Values
| reviewRejectType | Meaning |
|---|---|
RETRY | User may resubmit corrected documents. |
FINAL | Final rejection. |
Next steps
Continue to Proof of Address only when <client>-kyc-individuals-poa-batch is selected and identity documents do not satisfy residence requirements. Skip that page for <client>-kyc-individuals-address and <client>-kyc-individuals-address-tin.