Sessions API
Sessions are the core of KYC verification. Create a session on your backend, then initialize the widget on your frontend — or drive the whole flow yourself via the Direct API.
Using the SDK
typescriptimport { FlonkKYCServer } from '@flonkid/kyc/server';const flonk = new FlonkKYCServer({secretKey: process.env.FLONK_SECRET_KEY!,});// Create sessionconst session = await flonk.createSession({clientMetadata: { email: 'user@example.com', userId: 'user_123' },expiryMinutes: 30,language: 'de',});// → { id, embedToken, status, expiresAt, widgetUrl, qrCodeUrl, ... }// Get sessionconst details = await flonk.getSession(session.id);// Update sessionawait flonk.updateSession(session.id, {clientMetadata: { email: 'updated@example.com' },});
REST API Reference
Create Session
POST /v1/sessions
Creates a new KYC verification session.
Request
json{"clientMetadata": {"email": "user@example.com","userId": "user_123","name": "John Doe"},"language": "de","expiryMinutes": 30}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
clientMetadata | object | No | Custom data to associate with session |
clientMetadata.email | string | No | User email (recommended for webhook matching) |
clientMetadata.userId | string | No | Your internal user ID |
clientMetadata.name | string | No | User display name |
language | string | No | Widget language: en, de, uk (default: de) |
expiryMinutes | number | No | Session expiry in minutes, 1-60 (default: 5) |
Note: All
clientMetadatafields are optional. Pass any key-value pairs you need — they are returned in webhook events, so you can match verifications to your users.
Idempotency
Send an optional Idempotency-Key header to make a create safely retriable: a
retry with the same key returns the original session instead of creating a
duplicate (a concurrent retry while the first is still in flight gets 409).
Keys are scoped to your project and remembered for 24h. The Node SDK sets one
automatically, so createSession retries can never duplicate.
Idempotency-Key: 6f0c…-uuid
Response
json{"id": "clxxxxxxxxxxxxxxxxx","embedToken": "eyJhbGciOi...","status": "pending","expiresAt": "2026-01-15T12:30:00Z","createdAt": "2026-01-15T12:00:00Z","widgetUrl": "https://verify.flonk.id/?sessionId=...","qrCodeUrl": "https://verify.flonk.id/?sessionId=...","allowManualUpload": false,"testMode": false}
Get Session
GET /v1/sessions/{sessionId}
Retrieves details of an existing session.
Response
json{"id": "clxxxxxxxxxxxxxxxxx","status": "completed","clientMetadata": {"email": "user@example.com","userId": "user_123"},"createdAt": "2026-01-15T12:00:00Z","expiresAt": "2026-01-15T12:30:00Z","updatedAt": "2026-01-15T12:05:00Z"}
Session Statuses
| Status | Description |
|---|---|
pending | Session created, waiting for user to open widget |
connected | User opened the widget |
processing | Documents uploaded, AI verification in progress |
completed | Verification finished and approved (check webhook for result) |
failed | Verification failed — reopens for resubmission within TTL (see Direct API) |
expired | Session expired before completion |
manual_review | Automated checks were inconclusive; a human reviewer is deciding. Frozen: does not expire on TTL and rejects further uploads. See Manual review |
rejected | A reviewer rejected the verification. Closed permanently — create a new session |