Skip to content
Switch to light mode

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.

On this page

3.1 API Prerequisites

ItemRequirement
App TokenSumsub app token for the correct environment. Sandbox tokens usually begin with sbx: and production tokens with prd:.
Secret KeyUsed to generate HMAC-SHA256 request signatures.
Base URLhttps://api.sumsub.com. Environment is determined by token prefix, not a different hostname.
Level namePass <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 clientMust 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:

HeaderDescription
X-App-TokenApp token.
X-App-Access-TsUnix timestamp in seconds, UTC.
X-App-Access-SigLowercase hex HMAC-SHA256 signature.

Signature Format

payload = bytes(timestamp + METHOD + path + body)
signature = HMAC_SHA256(secretKey, payload) -> lowercase hex

Rules

  • METHOD must be uppercase, for example GET, POST, or PATCH.
  • path must 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. 1

    Create applicant with the selected levelName, full fixedInfo, and metadata.

    POST/resources/applicants?levelName=<client>-kyc-individuals-address
  2. 2

    Upload ID front.

    POST/resources/applicants/{applicantId}/info/idDoc
  3. 3

    Upload ID back, when required.

    POST/resources/applicants/{applicantId}/info/idDoc
  4. 4

    Check PoA status on <client>-kyc-individuals-poa-batch only.

    GET/resources/applicants/{applicantId}/requiredIdDocsStatus
  5. 5

    Upload dedicated PoA on <client>-kyc-individuals-poa-batch if still required.

    POST/resources/applicants/{applicantId}/info/idDoc
  6. 6

    Upload selfie.

    POST/resources/applicants/{applicantId}/info/idDoc
  7. 7

    Submit questionnaire.

    POST/resources/applicants/{applicantId}/questionnaires
  8. 8

    Preflight required steps.

    GET/resources/applicants/{applicantId}/requiredIdDocsStatus
  9. 9

    Request review.

    POST/resources/applicants/{applicantId}/status/pending
  10. 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

Generate an app token signature

Client SystemprocessesClient System

Create applicant with selected levelName, sourceKey, and fixedInfo

API flow
Client SystemSumsub

Return applicantId

SumsubClient System

Upload ID, PoA only on <client>-kyc-individuals-poa-batch, selfie, and questionnaire

Client SystemSumsub

Optional PATCH fixedInfo when correcting, refreshing, or resuming

Client SystemSumsub

Preflight requiredIdDocsStatus and request review

API flow
Client SystemSumsub

Perform verification checks

SumsubprocessesSumsub

Send applicantReviewed result

API flow
SumsubPayblr

Get applicant review status

applicantReviewed webhook or Get applicant data API

Client SystemSumsub
altGREEN

Verification completed

GREEN path

PayblrClient System
altRED

Verification rejected, retry required, or review required

RED path

PayblrClient System

Route to compliance review

Approve, reject, or request action

PayblrprocessesPayblr

Final handling result

API flow
PayblrClient System
sequenceLaneCenter(index, columnCount)
Backend-managed applicant creation, document submission, review request, and Payblr-processed final handling.

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: true

Form Parts

PartContent TypeValue
metadataapplication/jsonJSON metadata object.
contentImage MIME typeBinary 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/json

Request 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}/requiredIdDocsStatus

Inspect 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/pending

Optional Query Parameter

?reason=Your+reason+string

Expected 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}/status

Poll 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

reviewAnswerMeaning
GREENApproved.
REDRejected or retry required. Inspect rejectLabels and reviewRejectType.

Review Reject Type Values

reviewRejectTypeMeaning
RETRYUser may resubmit corrected documents.
FINALFinal 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.