Working with clientKey
clientKey is a user ID that you define and use to link KYC sessions to your users, applications, or contracts.
Using clientKey you can:
- find all KYC sessions of a specific user;
- match the verification results with your objects (userId, orderId, loanId, etc.);
- filter sessions via the REST API;
- easier to process webhooks.
Important: you create the clientKey value yourself, the platform does not generate it automatically.
Format and restrictions
- Type:
string - Maximum length: 36 characters
- Format: any string, it is convenient to limit yourself to Latin letters, numbers and separators (
[a-zA-Z0-9_-])
Recommended for use:
clientKey = userId— if one KYC check per user;clientKey = "${userId}:${applicationId}"— if KYC is linked to an application, order, or contract;clientKey = UUID— if it’s more convenient to work only with the KYC identifier.
Two forms of clientKey: «raw» and encrypted
To integrate with WebSDK, you need to understand that there are:
- Original value (
clientKeyRaw) What you came up with: for example,"user_123"or"loan-42". - Encrypted value (
clientKey) This is what you actually pass to the widget. It is the result of encryptingclientKeyRawwith the «scenario secret key» in the personal account.
Workflow:
- On the backend:
- you form
clientKeyRaw(up to 36 characters); - encrypt it with the script’s secret key;
- you send the encrypted
clientKeyto the frontend.
- On the frontend:
- you pass the encrypted
clientKeytoKYCWidget.setupKYC(...).
- On the side of the KYC service:
- the value is decrypted;
- the original
clientKeyRawis stored in the session; - you can filter sessions by it and get results via API and webhooks.
Where clientKey is used
In WebSDK
Widget call:
window.KYCWidget.setupKYC({
scenarioId: "SCENARIO_ID", // Test scenario ID
clientKey: "ENCRYPTED_CLIENT_KEY", // encrypted clientKeyRaw
theme: "light",
closeCb: () => console.log("CLOSE"),
successCb: (payload) => {
console.log("SUCCESS", payload);
// here you already know the original clientKeyRaw, as you set it yourself on the backend
},
}); In REST API
/kyc/session/status— you can passclientKeyto clarify the status for a specific key;/kyc/sessions/filter— there is aclientKeyfilter to get all sessions by key.
Here you pass the original value (clientKeyRaw), without encryption.
Generating and encrypting clientKey on the backend
The Scenario Secret Key is stored only on your server side. It cannot be transmitted to the browser.
General idea:
- Take
clientKeyRaw(up to 36 characters). - You take the scenario secret key from your personal account (
scenarioSecretKey). - On the backend, encrypt
clientKeyRawusing an algorithm (example — AES-256-CBC). - You pass the resulting Base64 string to WebSDK as
clientKey.
Node.js example (AES-256-CBC)
const crypto = require("crypto");
// 1. Original ID (what you want to see in the API and webhooks)
const clientKeyRaw = "user_123"; // up to 36 characters
// 2. Script secret key from your account (DO NOT pass to the browser!)
const password = "SCENARIO_SECRET_KEY";
// 3. Get a 32-byte key from the password
const key = crypto.createHash("sha256").update(password).digest('hex').substr(0, 32);
// 4. Generate a random IV (16 bytes)
const iv = crypto.randomBytes(16);
// 5. Encrypt clientKeyRaw
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
const encrypted = Buffer.concat([cipher.update(clientKeyRaw, "utf8"), cipher.final()]);
// 6. We concatenate IV + ciphertext and encode it in Base64 — this is the clientKey for the widget
const encryptedBase64 = Buffer.concat([iv, encrypted]).toString("base64");
console.log("clientKeyRaw:", clientKeyRaw);
console.log("clientKey (encrypted):", encryptedBase64); This is the encrypted clientKey you substitute into:
window.KYCWidget.setupKYC({
scenarioId: "SCENARIO_ID",
clientKey: encryptedBase64,
// ...
}); How to test clientKey
- In your account, find the scenario secret key.
- Click the «Check» button and enter the test
clientKeyRaw(e.g.,test_user_1). - The personal account will return an encrypted value — it can be temporarily substituted into integration examples (instead of
"ENCRYPTED_CLIENT_KEY"). - Make sure that:
- widget opens without errors;
- your KYC session logs show the original
clientKeyRaw(for example, when filtering byclientKeyvia/kyc/sessions/filter).
Frequent questions and errors
«Where do I get the values for clientKey and clientUser?»
clientKey— any string up to 36 characters that you define yourself:userId, application number, order, any convenient value. The parameter is required.clientUser— an optional string up to 36 characters, not required to be unique: you can use it later to find all sessions (attempts) of a single user.
Console error: «Asymmetric decryption failed!»
Most often it means that:
- the widget received an unencrypted
clientKeyRaw; - or a different secret key was used, other than the script key;
- or the
clientKeyvalue was corrupted/truncated (e.g., during copying).
Check:
- That you pass to the widget exactly the Base64 string obtained after encryption (see example above).
- That the script in the personal account and the secret key you use for encryption match.
- That the extra parameter
clientUseris not used (it can be removed).
«How do I find the clientKey to decrypt the webhook?»
To decrypt the webhook body, clientKey is not needed:
- the webhook is encrypted with the session key/webhook secret, not
clientKey; - to decrypt, you only need the password/key you specified in the webhook settings and the encrypted
encryptedfield from the POST request.
clientKey in the webhook is simply one of the JSON fields within the already decrypted body, and its value will be exactly what you specified in clientKeyRaw.
«Why does each test webhook come with a different encrypted string, even though the JSON is the same?»
It’s normal:
- encryption uses a random IV (initialization vector);
- even with the same JSON and encryption key, the ciphertext is different each time;
- after decryption, the body will be the same JSON.
«How is the overall success/failed status related to checks and bases?»
Overall KYC session status:
success— only if all checks passed successfully;- if there is
failedsomewhere (OCR, fraud, databases, etc.) — the overall status will befailed.
Checks against external databases (sanctions, debtor registries, etc.) also affect the overall success: if a «red flag» is considered critical, it will result in a failed status at the session level.
Recommended workflow with clientKey
- On the backend, when the KYC process starts:
- generate or select
clientKeyRaw(e.g.,user_123); - encrypt it with the script’s secret key →
encryptedClientKey; - save
clientKeyRawwithuserId/orderId.
- On the frontend:
- you pass
encryptedClientKeytoKYCWidget.setupKYC(...).
- To get the result:
- either accept the webhook and look at the
clientKeyfield inside the body; - either call
/kyc/sessions/filterwithclientKey = clientKeyRawto find all sessions by this key.
This way, you can always unambiguously determine which user or application any KYC session belongs to.