@certilayer/node
v1.0.2
Published
CertiLayer behavioral biometrics SDK for Node.js — verify human sessions server-side in 3 lines.
Maintainers
Readme
@certilayer/node
Verify human sessions server-side in 3 lines.
The official Node.js SDK for CertiLayer — call it after your Web, iOS, Android, or React Native SDK has captured a session, and get back a Human Confidence Score (HCS) you can gate critical actions on: login, checkout, signup, password changes.
Installation
npm install @certilayer/node⚠️ Secret key — server-side only
CertiLayerClient takes your secret key (certilayer_live_sk_... or
certilayer_test_sk_...). This SDK is for server environments only —
never ship this key to a browser, mobile app, or any client-side code.
For the client side, use @certilayer/web (or the iOS/Android/React
Native SDK), which takes your public key instead.
Quick start
import { CertiLayerClient } from '@certilayer/node'
const client = new CertiLayerClient({ apiKey: process.env.CERTILAYER_KEY! })
const result = await client.verifySession(sessionId)
// result.verdict: 'human_verified' | 'human_likely' | 'synthetic'
// result.score: 0.0 – 1.0
if (result.verdict === 'synthetic') {
return res.status(403).json({ error: 'bot_detected' })
}sessionId is the session ID produced by whichever client-side SDK
(@certilayer/web, iOS, Android, or React Native) is running on the
same page/app the user is on.
Client configuration
interface CertiLayerOptions {
apiKey: string // required — your secret key
baseUrl?: string // default: 'https://api.certilayer.net/v1'
timeoutMs?: number // default: 10000
maxRetries?: number // default: 2 — exponential backoff, 5xx/network only
}| Option | Default | Notes |
| ------------ | ------------------------------------ | ---------------------------------------------------------------------- |
| apiKey | — | Required. Throws INVALID_API_KEY if missing or empty. |
| baseUrl | https://api.certilayer.net/v1 | Override only for self-hosted deployments. |
| timeoutMs | 10000 | Per-request timeout. |
| maxRetries | 2 | Retries 5xx and network errors with exponential backoff. 4xx errors are never retried. Set to 0 to disable. |
API reference
client.verifySession(sessionId, options?): Promise<VerifyResult>
Full verification — returns score, verdict, and session metadata.
interface VerifyResult {
score: number // 0.0 – 1.0
verdict: 'human_verified' | 'human_likely' | 'synthetic'
sessionId: string
scoredAt: string // ISO-8601
}Pass { critical: true } immediately before a high-stakes action
(payment, password change, account mutation). This tells the policy
engine to apply stricter critical-action rules, which can escalate a
grey-zone score to a step-up challenge or session termination instead of
a softer response.
try {
await client.verifySession(sessionId, { critical: true })
} catch (e) {
if (e.code === 'STEP_UP_REQUIRED') return promptWebAuthn()
throw e
}client.quickCheck(sessionId, minScore?, options?): Promise<QuickCheckResult>
Lighter than verifySession() — just a pass/fail gate decision without
full session metadata.
interface QuickCheckResult {
score: number
verdict: 'human_verified' | 'human_likely' | 'synthetic'
passed: boolean // true if score >= minScore
}minScore defaults to 0.30 (the confirmed-synthetic boundary) if
omitted.
const { passed, verdict } = await client.quickCheck(sessionId)
if (!passed) return res.status(403).end()HCS verdict thresholds
| Verdict | Score range | Recommended action |
| ----------------- | ------------ | ------------------------------ |
| human_verified | ≥ 0.35 | Allow — high confidence |
| human_likely | 0.30 – 0.35 | Soft friction / step-up auth |
| synthetic | < 0.30 | Block or challenge |
Framework middleware
Ready-made middleware that reads a session ID from a request header and rejects requests below your minimum score — no manual wiring needed.
interface MiddlewareOptions {
sessionHeader?: string // default: 'x-certilayer-session'
minScore?: number // default: 0.30
rejectStatus?: number // default: 403
}Express
app.post('/checkout', client.middleware.express(), checkoutHandler)Fastify
fastify.addHook('preHandler', client.middleware.fastify())Both middlewares attach the result to the request object
(req.certilayer = { passed, verdict, score }) for downstream handlers
to read, and fail open (allow the request through) if the CertiLayer
API is unreachable or errors — so a transient outage never blocks real
users. Override this in your own error handling if you'd rather fail
closed.
Error handling
All SDK errors throw a CertiLayerError with a machine-readable .code:
import { CertiLayerError } from '@certilayer/node'
try {
await client.verifySession(sessionId)
} catch (e) {
if (e instanceof CertiLayerError) {
console.error(e.code, e.message)
}
}| Code | Meaning |
| --------------------- | ---------------------------------------------------------------------- |
| INVALID_API_KEY | API key missing, empty, or rejected by the server |
| SESSION_NOT_FOUND | No session exists for the given sessionId |
| SESSION_EXPIRED | Session exists but has exceeded its TTL |
| STEP_UP_REQUIRED | Policy engine requires additional verification (WebAuthn/OTP) |
| SESSION_TERMINATED | Policy engine has revoked this session as confidently synthetic |
| RATE_LIMITED | Too many requests — back off and retry |
| NETWORK_ERROR | Could not reach the CertiLayer API |
| TIMEOUT | Request exceeded timeoutMs |
| UNEXPECTED_ERROR | Unclassified server or SDK error |
License
MIT
Support
- Docs: certilayer.net/docs
- Issues: please contact [email protected]
