Skip to content

Sumsub Integration

Cruits uses Sumsub for worker identity verification (ID check). The integration covers three concerns: issuing WebSDK access tokens so workers can submit documents in-browser, verifying incoming webhook signatures, and retrieving applicant data after review.

Environment Variables

Variable Required Default (dev) Description
SUMSUB_BASE_URL No https://api.sumsub.com Sumsub REST API base URL.
SUMSUB_TOKEN Yes App token (X-App-Token) issued in the Sumsub dashboard.
SUMSUB_SECRET Yes App secret used to sign outgoing HMAC-SHA256 request signatures.
SUMSUB_WEBHOOK_SECRET Yes Webhook secret used to verify the X-Payload-Digest header on incoming webhook events.

Setup Steps

1. Create a Sumsub App

  1. Log in to the Sumsub dashboard.
  2. Go to DevelopersApp tokensCreate new token.
  3. Copy the App token into SUMSUB_TOKEN and the Secret key into SUMSUB_SECRET.

2. Create a Verification Level

  1. In the Sumsub dashboard, go to Verification FlowsCreate new level.
  2. Name it id-and-liveness (matches the hardcoded SUMSUB_LEVEL_NAME constant in client.py).
  3. Add Document verification + Liveness checks.

To use a different level name, update SUMSUB_LEVEL_NAME in integrations/sumsub/client.py.

3. Configure the Webhook

  1. In the Sumsub dashboard, go to DevelopersWebhooksAdd endpoint.
  2. Set the URL to https://<your-domain>/api/screenings/sumsub/webhook.
  3. Select events: applicantReviewed.
  4. Copy the generated Secret into SUMSUB_WEBHOOK_SECRET.

How It Works

Request Signing

Every outgoing request to Sumsub is HMAC-SHA256 signed per Sumsub's scheme. SumsubAPIMixin.finalize_request() computes:

signature = HMAC-SHA256(secret, timestamp + METHOD + path_with_query + body)

And attaches three headers:

Header Value
X-App-Token SUMSUB_TOKEN
X-App-Access-Ts Unix timestamp (seconds)
X-App-Access-Sig Hex HMAC-SHA256 signature

Webhook Verification

Incoming webhook requests are verified by verify_sumsub_webhook_signature() in integrations/sumsub/client.py. The function computes HMAC(secret, body) with the algorithm specified in X-Payload-Digest-Alg (defaults to HMAC_SHA256_HEX) and compares it to X-Payload-Digest. Requests that fail are rejected with 403 via IsSumsubWebhookRequest permission class.

Supported digest algorithms: HMAC_SHA1_HEX, HMAC_SHA256_HEX, HMAC_SHA512_HEX.

Worker ID Check Flow

GET /api/screenings/sumsub/access-token
  → SumsubClient.create_access_token(user_id)   # issues WebSDK token
  → store applicantId on User.id_check_ref
  → create IdCheckApplication(user, external_id=applicantId)

Worker completes ID + liveness in Sumsub WebSDK

POST /api/screenings/sumsub/webhook  (applicantReviewed)
  → SumSubWebhookProcessor._process_review_completed()
  → IdCheckApplication.status = SUCCESS | FAILED

After a successful review, downstream tasks (retrieve_application_id_data, store_document_data_in_salesforce, name_mismatch_notification) are triggered via IdCheckApplication lifecycle hooks.

Data Model

Model Purpose
IdCheckApplication One per worker; stores external_id (Sumsub applicantId) and review status
IdCheckDocument Parsed document fields extracted from Sumsub after a successful review

IDcheckStatus values: PENDING, SUCCESS, FAILED (see screenings/constants.py).

API Endpoints

Method Path Auth Description
GET /api/screenings/sumsub/access-token Worker JWT Fetches a WebSDK access token for the authenticated worker. Also creates/links the IdCheckApplication.
POST /api/screenings/sumsub/webhook HMAC signature Sumsub event receiver. Updates IdCheckApplication.status on applicantReviewed.

Relevant Code

File Purpose
integrations/sumsub/client.py SumsubClient (API calls), verify_sumsub_webhook_signature()
screenings/permissions.py IsSumsubWebhookRequest — verifies webhook HMAC before the view runs
screenings/views.py SumsubAccessTokenView, SumsubWebhookView
screenings/utils.py SumSubWebhookProcessor — routes webhook events to handlers
screenings/serializers.py SumsubWebhookSerializer, SumsubAccessTokenSerializer
screenings/models.py IdCheckApplication, IdCheckDocument
screenings/tasks.py retrieve_application_id_data, store_document_data_in_salesforce, name_mismatch_notification
screenings/urls.py URL routing for Sumsub endpoints