Developer Documentation

VerifyAfrica API Reference

Verify African identities, issue portable VITs, and gate high-risk actions — all from a single API. Full SDK support for JavaScript and Python.

Base URL:https://api.verifyafrica.com

Authentication

All requests require a bearer token in the Authorization header. Get your API key from the dashboard → API Keys.

bash
curl https://api.verifyafrica.com/v1/identity \
  -H "Authorization: Bearer ov_live_YOUR_KEY"
ov_live_Production keys — calls real identity providers. KYC credits consumed.
ov_sandbox_Sandbox keys — deterministic fake outcomes, no credits, no real data.

JavaScript / TypeScript SDK

Works in Node.js, Next.js, and Edge runtimes. Full TypeScript types included.

Install

bash
npm install @verifyafrica/sdk
# or
yarn add @verifyafrica/sdk

Initialize

typescript
import VerifyAfrica from '@verifyafrica/sdk';

const ov = new VerifyAfrica({
  apiKey: process.env.VERIFYAFRICA_API_KEY, // ov_live_... or ov_sandbox_...
});

Verify an identity

typescript
// 1. Initiate a verification session
const session = await ov.verify.initiate({
  phone: '+2348012345678',
  country: 'NG',
  platformUserId: 'user_abc123',
});
// { token: 'sess_...', expiresAt: '...' }

// 2. Poll for completion (typically 30–120s)
const result = await ov.verify.status(session.token);
// {
//   verified: true,
//   vit: 'ov_vit_...',
//   trust_score: 0.85,
//   verification_level: 1
// }

// 3. Check a user's status anytime (sub-100ms)
const status = await ov.identity.status('user_abc123');
// { verified: true, level: 'basic', trust_score: 0.85, aml_status: 'clear' }

Gate with a VIT

typescript
// Verify a VIT the user presents to your service
const payload = await ov.vit.verify(vitToken);
// {
//   verified: true,
//   level: 'basic',
//   trust_score: 0.85,
//   aml_clear: true,
//   flags: { blacklisted: false, aml_flagged: false }
// }

// Gate a high-risk action
if (!payload.verified || payload.flags.blacklisted || payload.flags.aml_flagged) {
  throw new Error('Identity verification required');
}

Python SDK

Compatible with Python 3.9+. Works in Django, FastAPI, Flask, and serverless runtimes.

Install

bash
pip install verifyafrica

Initialize

python
import verifyafrica

ov = verifyafrica.Client(api_key=os.environ["VERIFYAFRICA_API_KEY"])

Verify an identity

python
# 1. Initiate a verification session
session = ov.verify.initiate(
    phone="+2348012345678",
    country="NG",
    platform_user_id="user_abc123",
)
# {"token": "sess_...", "expires_at": "..."}

# 2. Poll for completion
result = ov.verify.status(session["token"])
# {"verified": True, "vit": "ov_vit_...", "trust_score": 0.85}

# 3. Check a user's status anytime
status = ov.identity.status("user_abc123")
# {"verified": True, "level": "basic", "aml_status": "clear"}

Gate with a VIT

python
# Verify a VIT presented by the user
payload = ov.vit.verify(vit_token)

if not payload["verified"] or payload["flags"]["blacklisted"]:
    raise PermissionError("Identity verification required")

Sandbox testing

The sandbox environment returns deterministic outcomes for fixed test document IDs. No real identity providers are called. No KYC credits consumed.

Sandbox keys (prefix ov_sandbox_) are required. Switch in the dashboard.
typescript
const ov = new VerifyAfrica({
  apiKey: 'ov_sandbox_test_key', // get from dashboard → API Keys
});

// Use these test document IDs in verify.initiate():
// TEST_NG_PASS_001  → pass (trust_score 0.85)
// TEST_NG_FAIL_001  → fail (name mismatch)
// TEST_NG_AML_001   → aml_flagged
// TEST_NG_BL_001    → blacklisted

const session = await ov.verify.initiate({
  phone: '+2348000000001',
  country: 'NG',
  documentId: 'TEST_NG_PASS_001',
  platformUserId: 'test_user_1',
});
Test IDCountryOutcome
TEST_NG_PASS_001NGpass
TEST_NG_FAIL_001NGfail
TEST_NG_AML_001NGaml_flagged
TEST_NG_BL_001NGblacklisted
TEST_GH_PASS_001GHpass
TEST_KE_PASS_001KEpass
TEST_PASS_PASS_001GLOBALpass

Full list: Dashboard → Sandbox or GET /v1/sandbox/credentials.

API reference

All endpoints return JSON. Successful responses use HTTP 2xx status codes.

POST/v1/verify/initiate

Start a verification session. Returns a session token.

Body / Params

phone, country, platformUserId

Returns

token, expiresAt

GET/v1/verify/status/:token

Poll session status. Returns VIT once verification completes.

Body / Params

Returns

verified, vit, trust_score, verification_level

GET/v1/internal/users/:id/status

Check a platform user's verification status. Sub-100ms.

Body / Params

Returns

verified, level, trust_score, aml_status, is_blacklisted

GET/v1/internal/users/:id/vit

Issue a fresh VIT for an already-verified platform user.

Body / Params

Returns

token, payload

GET/v1/sandbox/credentials

Retrieve the full table of sandbox test document IDs.

Body / Params

Returns

credentials (grouped by country)

POST/v1/sandbox/reset

Wipe a platform user's sandbox state. Re-run the full flow from scratch.

Body / Params

platform_user_id

Returns

reset, identity_deleted

Errors

All errors follow the same shape: { error: string, message: string }

HTTPCodeMeaning
400validation_errorMissing or invalid request body field.
401unauthorizedAPI key missing or revoked.
403sandbox_onlyEndpoint requires a sandbox key (ov_sandbox_...).
403forbiddenAPI key does not have access to this resource.
404not_foundSession token or identity not found.
429rate_limit_exceededSlow down. Retry after retry_after seconds.
500internal_errorSomething went wrong on our end. Contact support.