Video-identification EDD
Complete video-identification EDD requests for eligible EEA-resident applicants through Sumsub and linked KYC submissions.
Complete a video-identification enhanced due diligence (EDD) request for an eligible EEA-resident applicant through a Sumsub session.
When this applies
This flow applies only to applicants resident in the European Economic Area (EEA) when Due raises a video-identification requirement.
Due handles this requirement through the video_id preset, an enhanced due diligence (EDD) check. When triggered for an applicant, Due creates an information request (RFI) with an applicant subject and a linked submission whose presetCode is video_id.
Resolve the RFI by resolving its linked submission. Video identification is a live-capture step: you cannot satisfy it by uploading a file through the API. The applicant must complete the check in the Sumsub flow, using either a hosted link or the embedded Sumsub WebSDK. You use the API to detect, retrieve, and track the request.
Overview
| Step | What happens | How |
|---|---|---|
| 1 | Detect the request | information_request.updated webhook |
| 2 | Retrieve the RFI and its submissionId | GET /v1/information_requests |
| 3 | Inspect the linked submission's requirements | GET /v1/kyc/submissions/{submissionId} |
| 4 | Complete the video identification | GET /v1/kyc/submissions/{submissionId}/external_checks/{checkId}/link |
| 5 | Track the outcome | information_request.updated webhook |
Step 1: Detect the request
Subscribe to information_request.updated. If the RFI is linked to a transfer, you also receive transfer.status_changed with status set to action_required; for an applicant-level requirement, the information-request event is the primary signal.
{
"url": "https://example.com/webhooks/due",
"events": ["information_request.updated", "transfer.status_changed"]
}When you receive information_request.updated, retrieve the latest RFI before acting. Do not rely on the webhook payload alone.
Step 2: Retrieve the RFI
List the information requests for the account:
curl "https://api.due.network/v1/information_requests" \
-H "Authorization: Bearer <API_KEY>" \
-H "Due-Account-Id: <ACCOUNT_ID>"Identify video-identification requests by the video_id preset.
| Field | Example | Meaning |
|---|---|---|
| RFI ID | ir_2mxpCxF6BF1RRb | The information request |
| Type | due_diligence | Category of the request |
| Preset | video_id | The preset that raised it |
submissionId | ksub_i5AJeBrZgW2cXtsS | The linked submission you resolve |
| Applicant | ka_TSq5pN01w9BbKIbk | The applicant the check applies to |
| Status | requested | Moves to resolved once the check is completed |
The RFI's subject.kind is applicant. It includes both the submissionId and applicant ID, so you do not need to retrieve them separately. Store the submissionId; it identifies the submission you resolve.
Step 3: Inspect the linked submission
Retrieve the linked submission:
curl "https://api.due.network/v1/kyc/submissions/<SUBMISSION_ID>" \
-H "Authorization: Bearer <API_KEY>" \
-H "Due-Account-Id: <ACCOUNT_ID>"A video_id submission can look like this:
{
"id": "ksub_i5BhoD7AskPt4Rc2",
"ownerId": "acct_Dv7VMAEADsE18XuF",
"applicantId": "ka_TUU7dyusjiJLixGf",
"status": "open",
"presetCode": "video_id",
"source": "api",
"info": {},
"requirements": [
{
"kind": "static",
"externalChecks": [
{ "type": "sumsub_video_id" }
]
}
],
"externalChecks": [
{
"id": "kchk_xM2j7a6zdyzucyDI",
"type": "sumsub_video_id",
"status": "pending"
}
],
"agreements": [],
"documents": [],
"questionnaires": [],
"subject": {
"kind": "applicant",
"id": "ka_TUU7dyusjiJLixGf",
"type": "individual",
"residenceCountry": "ES",
"basicInfo": { "firstName": "Snow", "lastName": "John", "dob": "1995-04-02" }
}
}Two arrays determine how you handle the submission:
requirementsis the authoritative list of outstanding items. The video-identification requirement includesexternalChecks.externalChecksat the top level contains check instances. Each instance has anid,type, andstatus. Use theidof thesumsub_video_idinstance as thecheckIdin Step 4. Its status, such aspending, shows whether the video identification is complete more precisely than the overall submission status.
In a pure video_id submission, the external check is the only requirement. The info object is empty and there are no agreements, documents, or questionnaires. The applicant resolves the submission by completing the Sumsub flow in Step 4.
Complete any requirement with externalChecks in the Sumsub flow, not through the API. sumsub_video_id is the video-identification check.
Detect video identification by checking for externalChecks[].type == "sumsub_video_id", rather than matching only on the preset code. Other presets can include this check.
Step 4: Complete the video identification
Obtain the applicant's Sumsub link using one of the following options. Both lead to the same video-identification flow.
Option A: Fetch a link for the specific check
Use the checkId from the submission's externalChecks array to fetch a link scoped to that check:
curl --request GET \
--url https://api.due.network/v1/kyc/submissions/<SUBMISSION_ID>/external_checks/<CHECK_ID>/link \
--header 'Due-Account-Id: <ACCOUNT_ID>' \
--header 'accept: application/json' \
--header 'authorization: Bearer <API_KEY>'The response includes the hosted Sumsub URL and its expiry time:
{
"url": "https://in.sumsub.com/websdk/p/9PIDZZDlmedwWywc",
"expiresAt": "2026-10-24T17:17:45.30545242Z"
}Present the url as a link or button in your onboarding flow. Because it is scoped to the check, it takes the applicant directly to video identification.
Use expiresAt to decide when to generate a replacement. Links are valid for an extended period, around 30 days. If an applicant returns after the link expires, call this endpoint again instead of reusing a stored URL. The link is generated only when you call the endpoint.
Option B: Generate an account session
Generate a Sumsub session for the account when you want to embed the Sumsub WebSDK in your application:
curl --request POST \
--url https://api.due.network/v1/kyc/session \
--header 'Due-Account-Id: <ACCOUNT_ID>' \
--header 'accept: application/json' \
--header 'authorization: Bearer <API_KEY>'If a previous link has expired, send { "force": true } in the request body to generate a new one. The response includes a hosted link and an access token:
{
"link": "https://...",
"accessToken": "..."
}Use accessToken to embed the Sumsub WebSDK so the applicant remains in your interface. Access tokens are short-lived; implement the WebSDK token-expiration handler to request a fresh token from the same endpoint.
After the applicant completes the video
Completing the external check closes the submission and resolves the RFI. Do not call complete yourself for a submission with this live video-identification requirement.
If the submission has additional API-managed requirements, satisfy them before the applicant completes the video. Completion closes the submission.
Step 5: Track the outcome
Continue listening for information_request.updated. On every event, retrieve the latest RFI before updating your internal state.
The RFI status moves from requested to resolved when the applicant completes video identification and the session closes the submission. An update can also indicate that further information is required; retrieve the linked submission and inspect requirements to determine what is outstanding.
Do not treat a completed Sumsub session as approval. The RFI outcome confirms that the requirement has been satisfied.
Handle webhooks safely
Verify the webhook signature before processing any event. Store each webhook event ID and make your handler idempotent so retries do not create duplicate work or sessions.
Updated about 6 hours ago