Skip to content
VerathYour digital identity. Reimagined.

Developers · Getting Started

Your first integration, step by step.

This guide walks through the full partner flow: receiving credentials, hashing identity numbers, sending signed events and handling owner responses.

API preview. The Verath API is in development. Endpoints, fields and behaviour shown here illustrate the planned design and may change before general availability. Sandbox credentials are issued to early partners on request.

1

Request access

Verath is onboarding early partners. Tell us about your organisation and use case and we’ll set up a sandbox account and a partner agreement.

Request sandbox access →

2

Store your credentials

You’ll receive four things. Keep them in a secrets manager, never in source control or client-side code.

  • VERATH_API_KEY

    Identifies your partner account

  • VERATH_SIGNING_SECRET

    Signs requests and verifies webhooks

  • VERATH_HASH_KEY

    Hashes identity numbers (versioned)

  • partner.crt / .key

    Client certificate for mutual TLS

3

Hash the identity number

At the moment you verify a NIN or BVN, compute an HMAC-SHA256 of the 11-digit number using your hash key. Send only the hash. The raw number never leaves your systems.

import { createHmac } from "node:crypto";

// hashKey is issued to you by Verath (one per key version).
export function identityHash(idNumber, hashKey) {
  const normalized = idNumber.replace(/\D/g, ""); // 11 digits, no spaces
  return createHmac("sha256", hashKey).update(normalized).digest("hex");
}
4

Send your first event

POST the event to /v1/events. Sign the request with a timestamp and HMAC of the body, and use your own reference as the idempotency key so retries are safe. Sending events should never block your customer flow; queue and retry in the background.

BODY='{
  "id_type": "BVN",
  "identity_hash": "3f9a…c21e",
  "hash_key_version": 1,
  "institution": { "name": "QuickLoan", "category": "digital_lender" },
  "purpose": "loan_application",
  "occurred_at": "2026-10-07T14:02:00+01:00",
  "partner_ref": "kyc-2026-10-07-55102"
}'
TS=$(date +%s)
SIG=$(printf "%s.%s" "$TS" "$BODY" | openssl dgst -sha256 -hmac "$VERATH_SIGNING_SECRET" | cut -d' ' -f2)

curl -X POST "$VERATH_BASE_URL/v1/events" \
  --cert partner.crt --key partner.key \
  -H "Authorization: Bearer $VERATH_API_KEY" \
  -H "Verath-Signature: t=$TS,v1=$SIG" \
  -H "Idempotency-Key: kyc-2026-10-07-55102" \
  -H "Content-Type: application/json" \
  -d "$BODY"
Supported purpose values
purposeWhen to use
kyc_checkRoutine identity verification
account_openingA new account is being opened
loan_applicationLoan or credit application
credit_inquiryCredit bureau inquiry
sim_registrationSIM registration or NIN-SIM link
account_updateChange to an existing account
otherAnything else (describe in purpose_detail)
5

Handle webhooks

Register an HTTPS endpoint for owner responses. Always verify the Verath-Signature header against the raw request body before acting, and respond with 2xx quickly. Process the work asynchronously.

dispute.created
{
  "id": "whk_01J9X…",
  "type": "dispute.created",
  "created_at": "2026-10-07T14:03:11+01:00",
  "data": {
    "event_id": "evt_8f21c0a9",
    "partner_ref": "kyc-2026-10-07-55102",
    "id_type": "BVN",
    "purpose": "loan_application",
    "owner_response": "not_me",
    "dispute_id": "dsp_4c7e19"
  }
}
import { createHmac, timingSafeEqual } from "node:crypto";

// Verify a Verath webhook before trusting it.
export function verifyVerathWebhook(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // replay protection
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
  const given = Buffer.from(parts.v1 ?? "", "hex");
  return given.length === expected.length && timingSafeEqual(given, expected);
}
6

Test and go live

Use the browser sandbox to see the full flow, then send test events from your sandbox account. When you’re ready, we’ll review your integration together and issue production credentials.

  • Events are sent for every NIN/BVN verification, including failures you choose to report
  • Retries use exponential backoff and the same partner_ref
  • Webhook signatures and timestamps are verified
  • Your fraud team knows how to act on dispute.created