@kwik-id/sdk-node
v0.1.0
Published
Server-side Node.js SDK for [KwikID](https://identity.kwiknkap.com) identity verification. Create verification sessions, retrieve results, and verify webhook signatures.
Readme
@kwik-id/sdk-node
Server-side Node.js SDK for KwikID identity verification. Create verification sessions, retrieve results, and verify webhook signatures.
Installation
npm install @kwik-id/sdk-node
# or
pnpm add @kwik-id/sdk-node
# or
yarn add @kwik-id/sdk-nodeRequirements: Node.js 18+
Quick Start
import { KwikIDNode } from "@kwik-id/sdk-node";
const kwikId = new KwikIDNode({
apiKey: process.env.KWIKID_API_KEY!,
});
// 1. Create a session (returns a clientSecret for the frontend SDK)
const session = await kwikId.createSession({
referenceId: "user_123",
userName: "Jane Doe",
userEmail: "[email protected]",
});
// 2. Pass session.token to your frontend as the clientSecret
// The frontend SDK handles the verification flow
// 3. Later, retrieve the verification result
const result = await kwikId.getVerificationResult(session.jobId);
console.log(result.status); // "verified" | "rejected" | "pending"
console.log(result.scores); // { overall, liveness, document, faceMatch }
console.log(result.extractedData); // { firstName, lastName, dateOfBirth, ... }Configuration
const kwikId = new KwikIDNode({
apiKey: "your-api-key", // Required — from KwikID dashboard at identity.kwiknkap.com
baseUrl: "https://api.identity.kwiknkap.com", // Optional — defaults to production
timeout: 30000, // Optional — request timeout in ms (default: 30s)
});API Reference
Sessions
createSession(options?)
Creates a new verification session. Returns a SessionToken containing the token (client secret) to pass to the frontend SDK.
const session = await kwikId.createSession({
referenceId: "user_123", // Optional — your internal user/order ID
userName: "Jane Doe", // Optional — pre-fill user name
userEmail: "[email protected]", // Optional — pre-fill user email
metadata: { plan: "premium" }, // Optional — arbitrary metadata
});
// session.sessionId — unique session identifier
// session.jobId — verification job ID
// session.token — client secret for frontend SDK
// session.expiresAt — ISO 8601 expiration timestampgetSession(sessionId)
Retrieves session details.
const details = await kwikId.getSession(session.sessionId);
// details.isUsed — whether the session has been consumed
// details.expiresAt — expiration timestampVerifications
listVerifications(options?)
Lists verification jobs with pagination and filtering.
const list = await kwikId.listVerifications({
status: "verified", // Filter by status
referenceId: "user_123", // Filter by your reference ID
page: 1, // Pagination
limit: 20,
sortBy: "createdAt", // "createdAt" | "updatedAt" | "status"
sortOrder: "desc", // "asc" | "desc"
});
// list.verifications — array of VerificationSummary
// list.pagination — { total, page, limit, totalPages }getVerification(id)
Gets full details of a single verification.
const verification = await kwikId.getVerification(jobId);
// verification.status — "pending" | "verified" | "rejected" | ...
// verification.documentType — "passport" | "id_card" | "drivers_license" | ...
// verification.userName
// verification.completedAtgetVerificationByReference(referenceId)
Looks up a verification by your reference ID.
const verification = await kwikId.getVerificationByReference("user_123");getVerificationResult(id)
Gets the detailed result including scores and extracted document data.
const result = await kwikId.getVerificationResult(jobId);
// Scores (0–1 scale)
result.scores?.overall; // Combined score
result.scores?.liveness; // Liveness detection score
result.scores?.document; // Document authenticity score
result.scores?.faceMatch; // Face match score
// Extracted document data (from OCR)
result.extractedData?.firstName;
result.extractedData?.lastName;
result.extractedData?.dateOfBirth; // YYYY-MM-DD
result.extractedData?.idNumber; // Document number
result.extractedData?.expiryDate; // YYYY-MM-DD
result.extractedData?.documentType;Webhooks
verifyWebhookSignature(options)
Verifies incoming webhook signatures to ensure authenticity. Webhooks are signed using HMAC-SHA256.
import { verifyWebhookSignature } from "@kwik-id/sdk-node";
// Express example
app.post("/webhooks/kwikid", (req, res) => {
const result = verifyWebhookSignature({
payload: JSON.stringify(req.body),
signature: req.headers["kwik-signature"] as string,
secret: process.env.KWIKID_WEBHOOK_SECRET!,
toleranceSeconds: 300, // Optional — reject events older than 5min (default)
});
if (!result.valid) {
console.error("Invalid webhook:", result.error);
return res.status(400).send("Invalid signature");
}
const { event } = result;
switch (event.event) {
case "verification.completed":
console.log("Verified:", event.data.jobId);
console.log("Scores:", event.data.scores);
console.log("Extracted:", event.data.extractedData);
break;
case "verification.rejected":
console.log("Rejected:", event.data.jobId);
break;
case "verification.failed":
console.log("Failed:", event.data.errorMessage);
break;
}
res.sendStatus(200);
});Webhook Events
| Event | Description |
|---|---|
| verification.started | User began the verification flow |
| verification.uploaded | Documents and selfie uploaded |
| verification.completed | Verification passed |
| verification.rejected | Verification rejected (e.g., document mismatch) |
| verification.failed | Verification failed (e.g., processing error) |
Webhook Payload
{
event: "verification.completed", // WebhookEventType
timestamp: "2024-01-15T10:30:00.000Z",
data: {
jobId: "job_abc123",
referenceId: "user_123", // your reference ID (if provided at session creation)
status: "verified",
environment: "live", // "live" | "test"
// Scores — present on completed/rejected events
scores?: {
documentScore?: number; // 0–1
documentBackScore?: number; // 0–1 (if back was captured)
faceMatchScore?: number; // 0–1
livenessScore?: number; // 0–1
},
// Extracted OCR data — present on completed events
extractedData?: {
firstName?: string;
lastName?: string;
fullName?: string;
dateOfBirth?: string; // YYYY-MM-DD
documentNumber?: string;
uniqueIdentifier?: string;
nationality?: string;
expiryDate?: string; // YYYY-MM-DD
issuanceDate?: string; // YYYY-MM-DD
documentType?: string;
},
// Error info — present on failed events
errorCode?: string;
errorMessage?: string;
metadata?: Record<string, unknown>;
}
}Framework Examples
Express
import express from "express";
import { KwikIDNode } from "@kwik-id/sdk-node";
const app = express();
const kwikId = new KwikIDNode({ apiKey: process.env.KWIKID_API_KEY! });
// Create a session for the frontend
app.post("/api/create-session", async (req, res) => {
const session = await kwikId.createSession({
referenceId: req.user.id,
userName: req.user.name,
});
res.json({ clientSecret: session.token });
});Next.js (App Router)
// app/api/verification/session/route.ts
import { KwikIDNode } from "@kwik-id/sdk-node";
import { NextResponse } from "next/server";
const kwikId = new KwikIDNode({ apiKey: process.env.KWIKID_API_KEY! });
export async function POST(request: Request) {
const { userId, userName } = await request.json();
const session = await kwikId.createSession({
referenceId: userId,
userName,
});
return NextResponse.json({ clientSecret: session.token });
}NestJS
import { Injectable } from "@nestjs/common";
import { KwikIDNode } from "@kwik-id/sdk-node";
@Injectable()
export class VerificationService {
private kwikId = new KwikIDNode({ apiKey: process.env.KWIKID_API_KEY! });
async createSession(userId: string, userName: string) {
return this.kwikId.createSession({ referenceId: userId, userName });
}
async getResult(jobId: string) {
return this.kwikId.getVerificationResult(jobId);
}
}Error Handling
All methods throw an Error with a descriptive message on failure:
try {
const result = await kwikId.getVerification("invalid-id");
} catch (error) {
// "KwikIDNode: GET /api/v1/verifications/invalid-id failed — Not found"
console.error(error.message);
}License
MIT
