Verification links
Verification links are single-use or time-limited URLs through which a user starts verification. You create links through the Tenant API or the admin panel and deliver them to the user (by email, SMS, QR code, or in your customer portal). When the user opens the link, a verification session is automatically created or attached, and the user is redirected to the KnowaKYC verification page.
Create a verification link
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Link options (flow_id required)
application/json- body
expires_in?integerseconds
external_reference?stringexternal_user_id?stringflow_id?stringlocale?stringmetadata?prefilled?redirect_url?stringutm_campaign?stringutm_medium?stringutm_source?stringCreated or reused link
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/verification-links' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "success": true, "data": { "created_at": "string", "delivery_eligible": true, "expires_at": "string", "external_reference": "string", "external_user_id": "string", "flow_id": "string", "id": "string", "link_url": "string", "locale": "string", "qr_code_url": "string", "redirect_url": "string", "reuse_reason": "external_reference", "reused": true, "session_id": "string", "session_resumable": true, "session_status": "string", "short_url": "string", "status": "string", "url": "string", "verification_link": "string", "verification_url": "string" }}Identity and unresolved review
external_user_id identifies an applicant within a tenant; it is not a session ID. Multiple historical sessions may belong to one applicant. Journey reuse is scoped by tenant, environment, external user ID, flow, and KYC/KYB entity type.
If that scoped identity already has an unresolved manual review, creating a fresh link returns HTTP 409 with error.code = "session_review_pending" and error.existing_session_id. Finish the existing review or use its resubmit action. Expiration of a link does not resolve a pending reviewer decision. Link duplication and activation of a previously created fresh link cannot bypass this check.
For a session still in progress, normal link creation continues to reuse that session. A final approved/declined decision permits a later independent verification. external_reference only reuses an eligible active link when the supplied external_user_id is empty or matches the link; a different external user receives an independent link. It is not a lifetime session-deduplication key. Batch creation reports review conflicts per item.
Correlate webhook outcomes by session_id as well as external_id. A historical session's later reviewer decision is an outcome for that historical session; it must not silently overwrite the result of another session solely because the external ID matches.
Legacy compatibility
The canonical KYC path is /tenant/v1/kyc/verification-links. For existing tenant integrations, KnowaKYC also intentionally keeps /tenant/v1/verification-links and /tenant/v1/verificationLinks as KYC aliases. Verification-link create and batch-create request bodies also accept legacy field aliases with different casing or separators, such as flowId, FlowID, externalUserId, redirectUrl, and prefilledData.
Do not treat these aliases as dead code. They are a supported compatibility contract and may be removed only after a separately versioned Tenant API deprecation and migration window.
Batch create links
Creates several verification links in a single request.
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Batch create request
application/json- body
defaults?items?array<>Created links
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/verification-links/batch' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "success": true, "data": { "failed": [ { "error": "string", "error_code": "string", "existing_session_id": "string", "index": 0, "link": { "created_at": "string", "delivery_eligible": true, "expires_at": "string", "external_reference": "string", "external_user_id": "string", "flow_id": "string", "id": "string", "link_url": "string", "locale": "string", "qr_code_url": "string", "redirect_url": "string", "reuse_reason": "external_reference", "reused": true, "session_id": "string", "session_resumable": true, "session_status": "string", "short_url": "string", "status": "string", "url": "string", "verification_link": "string", "verification_url": "string" } } ], "successful": [ { "error": "string", "error_code": "string", "existing_session_id": "string", "index": 0, "link": { "created_at": "string", "delivery_eligible": true, "expires_at": "string", "external_reference": "string", "external_user_id": "string", "flow_id": "string", "id": "string", "link_url": "string", "locale": "string", "qr_code_url": "string", "redirect_url": "string", "reuse_reason": "external_reference", "reused": true, "session_id": "string", "session_resumable": true, "session_status": "string", "short_url": "string", "status": "string", "url": "string", "verification_link": "string", "verification_url": "string" } } ], "summary": { "failed": 0, "successful": 0, "total": 0 } }}List links
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
page?integerPage (1-based)
page_size?integerPage size (1-100)
status?stringFilter by status (active, consumed, revoked)
external_user_id?stringFilter by external user ID
external_reference?stringFilter by external reference
flow_id?stringFilter by flow UUID
sort_by?stringSort field (default created_at)
sort_order?stringSort order: asc, desc (default desc)
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Verification links
*/*- response
data?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/verification-links' \ -H 'X-Timestamp: string'{ "success": true, "data": { "items": [ { "activated_at": "string", "consumed_at": "string", "created_at": "string", "created_by": "string", "expires_at": "string", "external_reference": "string", "external_user_id": "string", "flow_id": "string", "flow_session_id": "string", "id": "string", "locale": "string", "metadata": { "property1": null, "property2": null }, "prefilled_data": { "property1": null, "property2": null }, "redirect_url": "string", "revoked_at": "string", "revoked_reason": "string", "short_code": "string", "status": "string", "token": "string", "updated_at": "string", "utm_campaign": "string", "utm_medium": "string", "utm_source": "string" } ], "pagination": { "page": 0, "page_size": 0, "total": 0, "total_pages": 0 } }}Get a link by ID
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
id*stringLink UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Verification link details
*/*- response
data?success?booleancurl -X GET 'https://example.com/tenant/v1/kyc/verification-links/string' \ -H 'X-Timestamp: string'{ "success": true, "data": { "activated_at": "string", "consumed_at": "string", "created_at": "string", "created_by": "string", "expires_at": "string", "external_reference": "string", "external_user_id": "string", "flow_id": "string", "flow_session_id": "string", "id": "string", "locale": "string", "metadata": { "property1": null, "property2": null }, "prefilled_data": { "property1": null, "property2": null }, "redirect_url": "string", "revoked_at": "string", "revoked_reason": "string", "short_code": "string", "status": "string", "token": "string", "updated_at": "string", "utm_campaign": "string", "utm_medium": "string", "utm_source": "string" }}Revoke a link
A revoked link becomes invalid and cannot be used to start verification.
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
id*stringLink UUID
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Optional revoke reason
application/json- body
reason?stringRevoked link info
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/verification-links/string/revoke' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "success": true, "data": { "id": "string", "revoked_at": "string", "status": "string" }}Get a QR code
Returns the QR code for a verification link. Use it for the cross-device flow: the user scans the QR code on a mobile device and continues verification there.
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
id*stringLink UUID
size?integerQR size in pixels (1-1024, default 256)
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
PNG image
response?unknownimage/pngcurl -X GET 'https://example.com/tenant/v1/kyc/verification-links/string/qr' \ -H 'X-Timestamp: string'nullLink lifecycle
[Created] → [Activated] → [Consumed]
↓ ↓ ↓
[Expired] [Expired] [Completed]
↓ ↓
[Revoked] [Revoked]Link statuses:
| Status | Description |
|---|---|
active | Link created; the user has not opened it yet |
activated | The user opened the link; a session was created and verification is in progress |
consumed | Verification completed (approved, rejected, or routed to review) |
expired | The link's TTL (ttl_seconds) elapsed; the link is no longer usable |
revoked | The link was revoked manually through the API or the admin panel |
Note. After creating the link, deliver it to the user (by email, SMS, or QR code). Opening the link automatically creates a verification session. For the cross-device flow, use the QR code (
GET /v1/kyc/verification-links/{id}/qr).
Redirect after verification completes
When you create a link, you can pass the redirect_url parameter — the URL the user is redirected to once verification completes (for example, a customer portal or an application form).
How it works
- When creating the link, pass
redirect_urlin the request body (POST /v1/kyc/verification-linksor batch). - On activation,
redirect_urlis stored in the session and returned in the activation response (theredirect_urlfield). - On the completion screen (after approval, rejection, or routing to review) the user sees:
- a return button — the user clicks it and is redirected to
redirect_url; or - an automatic redirect after a configured delay.
- a return button — the user clicks it and is redirected to
Configuring behaviour
Redirect behaviour is set in the flow parameters in the admin panel:
- Redirect behaviour on completion — redirect mode: "Show button" or "Auto redirect".
- Redirect delay (seconds) — delay before the automatic redirect (applies when "Auto redirect" is selected).
Defaults: button is shown; automatic mode delay is 3 seconds. For details, see Flows (admin).