Developer Platform

One key. Every African identity rail.

REST and GraphQL APIs, SDKs in 8 languages, signed webhooks, and a sandbox that mirrors production. Sign up, copy a snippet, get your first verification in under 5 minutes.

< 600ms
p99 latency
99.99%
Uptime SLA
42+
Endpoints
54
Countries
Quickstart

Your first verification in 4 steps

Copy, paste, run. Every step works against the sandbox with no real customer data.

1. Get your sandbox key

Join the waitlist to receive a workspace, then copy your sandbox key. Sandbox keys are free and never touch real registries.

export TRUSTLAYER_KEY="tl_sandbox_xxxxxxxxxxxxx"

2. Install an SDK (optional)

Or skip it and call the REST API directly with any HTTP client.

npm install @trustlayer/node   # Node.js
pip install trustlayer         # Python

3. Run your first verification

Send an ID number plus the name on the account. You get a decision back in one call.

curl -X POST https://sandbox.trustlayer.ai/v1/verify/nin \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "nin": "12345678901",
  "first_name": "Test",
  "last_name": "Applicant",
  "liveness": true,
  "aml": true
}'

4. Read the decision

status is verified, review or rejected. risk_score and the match block tell you why — store request_id for your audit trail.

{
  "request_id": "req_8a31f7c2",
  "status": "verified",
  "confidence": 98.4,
  "match": { "name": true, "dob": true, "photo": 0.967 },
  "liveness": { "passed": true, "score": 0.997 },
  "aml": { "hits": 0, "screened_lists": 1432 },
  "risk_score": 12
}
Interactive

Request builder

Pick an endpoint, edit parameters, and fire a sandbox request. Snippets stay in sync as you type.

Verify NIN (Nigeria)

Validate a National Identity Number against the NIMC registry, optionally fused with face match, liveness and AML.

POST/v1/verify/nin

11-digit NIN

Given name

Family name

ISO date YYYY-MM-DD

Base64 selfie for face match

Run passive liveness on selfie

Screen against sanctions/PEP lists

Idempotency-Key: 00000000-0000-4000
Authorization: Bearer sk_test_•••••
curl -X POST https://api.trustlayer.ai/v1/verify/nin --retry 5 --retry-delay 1 --retry-all-errors \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Idempotency-Key: 00000000-0000-4000-8000-000000000000" \
  -H "Content-Type: application/json" \
  -d '{
  "nin": "12345678901",
  "first_name": "Test",
  "last_name": "Applicant",
  "dob": "1994-08-12",
  "selfie": "data:image/jpeg;base64,...",
  "liveness": true,
  "aml": false
}'
Response
awaiting request
// Click "Send request" to see a live sandbox response.
Reference

Endpoints

Full coverage across identity, biometrics, documents, business and compliance — versioned and backwards compatible.

POST/v1/verify/ninIdentity

Verify NIN (Nigeria)

Validate a National Identity Number against the NIMC registry, optionally fused with face match, liveness and AML.

Example request
curl -X POST https://api.trustlayer.ai/v1/verify/nin \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "nin": "12345678901",
  "first_name": "Test",
  "last_name": "Applicant",
  "dob": "1994-08-12",
  "selfie": "data:image/jpeg;base64,...",
  "liveness": true,
  "aml": false
}'
Example response · 200 OK
{
  "request_id": "req_8a31f7c2",
  "status": "verified",
  "confidence": 98.4,
  "match": {
    "name": true,
    "dob": true,
    "photo": 0.967
  },
  "liveness": {
    "passed": true,
    "score": 0.997
  },
  "aml": {
    "hits": 0,
    "screened_lists": 1432
  },
  "risk_score": 12,
  "latency_ms": 412
}
POST/v1/verify/bvnIdentity

Verify BVN (Nigeria)

Resolve a Bank Verification Number and confirm holder identity across the NIBSS network.

Example request
curl -X POST https://api.trustlayer.ai/v1/verify/bvn \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "bvn": "22198765432",
  "first_name": "Test",
  "last_name": "Applicant",
  "phone": "+2348031234567"
}'
Example response · 200 OK
{
  "request_id": "req_b21e90af",
  "status": "verified",
  "bank_count": 4,
  "match": {
    "name": true,
    "phone": true
  },
  "risk_score": 7,
  "latency_ms": 286
}
POST/v1/verify/documentDocuments

Document AI

Classify, OCR and authenticate passports, driver's licences, voter cards and residence permits across 54 African countries.

Example request
curl -X POST https://api.trustlayer.ai/v1/verify/document \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "document_type": "passport",
  "country": "KE",
  "front_image": "https://uploads.trustlayer.ai/...",
  "extract_mrz": true
}'
Example response · 200 OK
{
  "request_id": "req_d09c1144",
  "status": "authentic",
  "document": {
    "type": "passport",
    "country": "KE",
    "number": "AK0928411",
    "expires": "2031-04-22"
  },
  "holder": {
    "full_name": "TEST APPLICANT",
    "dob": "1990-11-03",
    "sex": "F"
  },
  "checks": {
    "mrz_checksum": true,
    "hologram": true,
    "font_consistency": 0.94,
    "tamper_score": 0.02
  },
  "latency_ms": 538
}
POST/v1/verify/faceBiometrics

Face Match + Liveness

1:1 face comparison with passive liveness, deepfake and presentation attack detection.

Example request
curl -X POST https://api.trustlayer.ai/v1/verify/face \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "liveness_threshold": 0.9
}'
Example response · 200 OK
{
  "request_id": "req_face_1f22",
  "status": "match",
  "similarity": 0.972,
  "liveness": {
    "passed": true,
    "score": 0.994,
    "attack_type": null
  },
  "deepfake_score": 0.011,
  "latency_ms": 318
}
POST/v1/aml/screenCompliance

AML / PEP / Sanctions Screening

Screen individuals or entities against 1,400+ global watchlists with adverse media.

Example request
curl -X POST https://api.trustlayer.ai/v1/aml/screen \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "full_name": "Test Applicant",
  "country": "NG",
  "include_adverse_media": true,
  "fuzzy": 0.85
}'
Example response · 200 OK
{
  "request_id": "req_aml_77ad",
  "status": "clear",
  "hits": 0,
  "screened_lists": 1432,
  "adverse_media": {
    "articles": 0,
    "sentiment": "neutral"
  },
  "latency_ms": 224
}
POST/v1/business/verifyBusiness

KYB — Business Verification

Resolve registration, directors and ultimate beneficial owners across CAC, CIPC, URSB and 18 other African registries.

Example request
curl -X POST https://api.trustlayer.ai/v1/business/verify \
  -H "Authorization: Bearer $TRUSTLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "country": "NG",
  "registration_number": "RC1234567",
  "include_ubo": true
}'
Example response · 200 OK
{
  "request_id": "req_kyb_4421",
  "status": "active",
  "business": {
    "name": "Pangaea Technologies Ltd",
    "rc": "RC1234567",
    "incorporated": "2019-03-12",
    "type": "Private Limited"
  },
  "directors": [
    {
      "name": "Director A",
      "role": "CEO"
    },
    {
      "name": "Director B",
      "role": "CTO"
    }
  ],
  "ubo": [
    {
      "name": "Director A",
      "ownership": 62.5
    }
  ],
  "risk_score": 18,
  "latency_ms": 712
}
Authentication · guided rotation

Create. Rotate. Revoke. Re-auth.

A zero-downtime workflow for rotating API keys quarterly, plus how to authenticate calls with the new key or a short-lived JWT.

Step 1Create a new API key

Issue a scoped key from the dashboard or via the management API. Choose Sandbox or Live and limit it to the verifications it needs.

1-create-key.sh
# Create a new live key, scoped and IP-locked
curl -X POST https://api.trustlayer.ai/v1/management/keys \
  -H "Authorization: Bearer $TRUSTLAYER_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "checkout-prod-2026Q2",
    "env": "live",
    "scopes": ["verify:nin", "verify:face", "aml:screen"],
    "ip_allowlist": ["52.214.0.0/16"]
  }'

# → returns: { "id": "key_a2c1...", "secret": "sk_live_NEW_…" }
# Save the secret immediately — it is only shown once.
1 / 5
Keys are hashed with Argon2id at rest, never logged, and a key.rotated webhook fires on every change.
Rate limits & retries

Handle 429s gracefully.

Every response carries X-RateLimit-Remaining and Retry-After headers. Combine exponential backoff with idempotency keys to retry POSTs safely.

retry-with-idempotency.tsNode 20+
// Exponential backoff with jitter + idempotency key
import { randomUUID } from "crypto";

async function verifyWithRetry(payload, attempt = 0) {
  const idempotencyKey = payload._idem ??= randomUUID();

  const res = await fetch("https://api.trustlayer.ai/v1/verify/nin", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.TRUSTLAYER_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": idempotencyKey,
    },
    body: JSON.stringify(payload),
  });

  if (res.status === 429 && attempt < 5) {
    const retryAfter = Number(res.headers.get("Retry-After") ?? 1);
    const backoff = retryAfter * 1000 + Math.random() * 250;
    await new Promise(r => setTimeout(r, backoff));
    return verifyWithRetry(payload, attempt + 1);
  }
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

When you'll see 429

  • Sustained traffic above your RPS allowance.
  • Bursting beyond the token bucket capacity.
  • Per-endpoint quotas (face verify is stricter than reads).

Idempotency rules

  • Send a UUID v4 in Idempotency-Key on every POST.
  • Replays within 24h return the cached response (no double-charge).
  • Different body + same key → 409 Conflict.
PlanSustained RPSBurstMonthly verifications
Sandbox5201,000
Startup25100100,000
Growth1004001M
EnterpriseCustomCustomUnlimited
OpenAPI 3.1

Export the full spec.

Generated live from the documented endpoints. Drop it into Postman, Insomnia, Stoplight, or your code generator of choice.

6 paths
2 servers
JWT + Bearer
trustlayer-openapi.json
{
  "openapi": "3.1.0",
  "info": {
    "title": "TrustLayer AI API",
    "version": "1.0.0",
    "description": "Identity, KYB, biometrics and AML APIs for Africa.",
    "contact": {
      "name": "TrustLayer Support",
      "email": "support@trustlayer.ai"
    },
    "license": {
      "name": "Commercial",
      "url": "https://trustlayer.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.trustlayer.ai",
      "description": "Production"
    },
    {
      "url": "https://sandbox.trustlayer.ai",
  …
Swagger UI

Try the spec, in-page.

The same OpenAPI 3.1 document, rendered as interactive Swagger UI. Expand any operation to inspect request and response schemas.

Loading Swagger UI…
GraphQL · live sandbox

Explorer with introspection.

Queries execute against /api/public/graphql in real time. Edit, run, ship.

query.graphql
variables (JSON)
live result
// Click Run to execute against /api/public/graphql
Webhooks · live signing & verification

Sign, deliver, verify.

Pick a signing secret, send a test event, and we run the same HMAC-SHA256 verification your server should run — pass or fail, in real time.

Event types

Used to compute HMAC-SHA256(`$${ts}.${rawBody}`). Never shipped to a server — verification runs in your browser.

Event: verification.completed · POST · application/json
Recent deliveries0/8
No deliveries yet — fire a test event above.

Server-side verification (Node)

import { createHmac, timingSafeEqual } from "crypto";

const sig = req.headers["x-trustlayer-signature"];      // t=...,v1=...
const [, ts] = sig.match(/t=(\d+)/);
const [, v1] = sig.match(/v1=([a-f0-9]+)/);

const expected = createHmac("sha256", process.env.TRUSTLAYER_WEBHOOK_SECRET)
  .update(`${ts}.${rawBody}`)
  .digest("hex");

if (!timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex"))) {
  return res.status(401).end();
}

API Reference

Every endpoint, parameter and error code documented with live examples.

8 SDKs

Node, Python, Go, Java, PHP, Ruby, .NET, Swift — fully typed.

Signed webhooks

HMAC-SHA256 signatures, replay protection, dead-letter queues.

Sandbox

Production-identical environment with 50 deterministic test identities.

CLI

Test, replay and tail logs from your terminal.

GraphQL

One query for orchestrated, multi-step verification flows.

SOC 2 + ISO 27001

Audited controls, encryption at rest and in transit, EU + Africa data residency.

Edge runtime

Anycast endpoints in Lagos, Nairobi, Cape Town, Frankfurt and Virginia.

Scoped keys

Per-environment keys with IP allowlists and granular permissions.