Verify your first customer
Create a sandbox verification session using a workflow, an explicit customer reference, and an idempotency key. This guide documents the current product-bearer contract.
Authentication transition
Issued customer API keys are not yet accepted by the NestJS product authentication guard. Use a product bearer token for current sandbox testing. Do not design a production server integration around a staff password.
1. Prepare environment variables
Keep secrets outside source control.
export SMART_KYC_BASE_URL="https://your-api-host.example.com"
export SMART_KYC_PRODUCT_TOKEN="product-bearer-token"
export IDEMPOTENCY_KEY="$(uuidgen)"
2. Choose a workflow
Use GET /api/v1/workflows and select an active workflow allowed by your plan. The example uses document_selfie_with_profile, which requires both subjectProfile.fullName and subjectProfile.dateOfBirth.
Do not infer required customer fields from the workflow name. Read launchRequirements.requiredAllOfFields and launchRequirements.requiredAnyOfFields from the workflow response.
3. Create the verification session
Generate one new idempotency key for each new customer action. Reuse the same key only when retrying the identical request.
curl --request POST \
"$SMART_KYC_BASE_URL/api/v1/verification-sessions" \
--header "Authorization: Bearer $SMART_KYC_PRODUCT_TOKEN" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: $IDEMPOTENCY_KEY" \
--data '{
"workflowKey": "document_selfie_with_profile",
"sourceType": "partner_api",
"subjectReference": "verification-request-001",
"subjectExternalId": "cust_8a12c9f4",
"subjectProfile": {
"fullName": "Ada Okafor",
"dateOfBirth": "1996-04-12",
"countryCode": "NG"
},
"subjectContact": {
"email": "ada@example.com",
"phoneNumber": "+2348012345678"
}
}'4. Store the response safely
A successful response contains the verification ID, session token, expiry, workflow, source, and a masked customer summary.
{
"id": "74ed3b5e-1ae3-4f58-b0ae-4dc0c825c31b",
"sessionToken": "kP5h5m5S1eQ4f0QY2W0x0d9nW2l3k8gA",
"expiresAt": "2026-07-17T16:15:00Z",
"workflowKey": "document_selfie_with_profile",
"sourceType": "partner_api",
"subjectReference": "verification-request-001",
"subjectExternalId": "cust_8a12c9f4",
"subjectSummary": {
"fullName": "Ada Okafor",
"countryCode": "NG",
"emailMasked": "a**@example.com",
"phoneNumberMasked": "+********45678"
}
}
Treat sessionToken as sensitive and respect expiresAt. The mobile verification experience remains the primary capture client; the customer handoff mechanism for a hosted web capture URL is not part of the current documented contract.
5. Read the result
Use GET /api/v1/verification-sessions/:verificationId for operational reads and subscribe to webhook events for asynchronous outcomes. Drive automation from stable fields such as status, decision, failureCode, and reasonCodes.
Retry rule
- Same tenant, key, and payload: returns the original start response.
- Same tenant and key with a different payload: returns
409 idempotency_key_conflict. - Rate-limited creation: returns
429withretryAfterSecondswhen available.