Developer Documentation

AfriVerify API Reference

Verify African identities, verify businesses (KYB), issue portable VITs, and gate high-risk actions. All requests are plain HTTP, no SDK required.

Base URL:https://api.afriverify.sankofaapp.com/v1

Authentication

Every request needs a bearer token in the Authorization header and an X-Platform header naming your platform. Requests missing either are rejected with 401. Get your API key from dashboard → API Keys.

bash
curl https://api.afriverify.sankofaapp.com/v1/internal/users/user_abc123/status \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName"
av_live_Production keys. Calls real identity providers, consumes your monthly verification quota.
av_test_Sandbox keys. Deterministic fake outcomes, no quota consumed, no real data.

Verify a person

A five-step flow: phone → OTP → government ID photo → selfie → poll for the result. Each step advances the same session token.

1. Initiate

bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/initiate \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{"phone": "+2348012345678", "platform_user_id": "user_abc123"}'
# { "session_token": "...", "expires_at": "...", "next_step": "otp" }

2. Send & confirm OTP

bash
# Send the OTP
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/otp/send \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{"session_token": "SESSION_TOKEN"}'
# { "sent": true, "expires_in": 300 }

# Confirm it
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/otp/confirm \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{"session_token": "SESSION_TOKEN", "otp": "123456"}'

3. Upload the government ID

bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/id/upload \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -F "session_token=SESSION_TOKEN" \
  -F "id_type=nin" \
  -F "id_number=12345678901" \
  -F "nationality=NG" \
  -F "first_name=Ada" \
  -F "last_name=Obi" \
  -F "dob=1995-04-12" \
  -F "id_photo=@id-photo.jpg"

4. Submit a selfie

bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/face/submit \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -F "session_token=SESSION_TOKEN" \
  -F "selfie=@selfie.jpg"
# { "processing": true, "estimated_seconds": 30 }

5. Poll for the result

bash
curl https://api.afriverify.sankofaapp.com/v1/verify/status/SESSION_TOKEN \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName"
# { "status": "complete", "vit": "...", "verification_level": 2, "identity_id": "..." }

Verify a business (KYB)

Business verification requires a registration document plus at least one director who has completed the individual verification flow above to full biometric level. Once both are in place, the business name is screened and the entity auto-verifies or is flagged for review.

1. Register the business

bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/kyb/register \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{
    "business_name": "Ada Trading Co",
    "registration_number": "RC1234567",
    "registration_country": "NG",
    "registration_type": "cac_ng"
  }'
# { "kyb_entity_id": "...", "verification_status": "pending", "next_steps": [...] }

2. Upload the registration document

bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/kyb/KYB_ENTITY_ID/document \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -F "document=@certificate-of-incorporation.pdf"

3. Attach a verified director

bash
# The director completes their own individual verification first
# (the flow above), then you attach their resulting identity:
curl -X POST https://api.afriverify.sankofaapp.com/v1/kyb/KYB_ENTITY_ID/directors \
  -H "Authorization: Bearer av_live_YOUR_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{"verified_identity_id": "IDENTITY_ID", "role": "director"}'
# Requires the identity to already have verification_level >= 2 (full biometric)

Sandbox testing

The sandbox environment returns deterministic outcomes for fixed test document IDs. No real identity providers are called, no quota consumed.

A sandbox key (prefix av_test_) is required. Switch environments in the dashboard.
bash
curl -X POST https://api.afriverify.sankofaapp.com/v1/verify/initiate \
  -H "Authorization: Bearer av_test_YOUR_SANDBOX_KEY" \
  -H "X-Platform: YourPlatformName" \
  -H "Content-Type: application/json" \
  -d '{"phone": "+2348000000001"}'

# Then use these test document IDs at the id/upload step:
# 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
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. Paths below are relative to the base URL above.

Individual verification

POST/verify/initiate

Start an individual verification session. Returns a session token.

Body / Params

phone, platform_user_id?, redirect_url?

Returns

session_token, expires_at, next_step

POST/verify/otp/send

Sends (or resends) a one-time code to the session phone number.

Body / Params

session_token

Returns

sent, expires_in

POST/verify/otp/confirm

Confirms the OTP and advances the session to the ID upload step.

Body / Params

session_token, otp

Returns

confirmed, identity_id, next_step

POST/verify/id/upload

Multipart. Uploads a government ID photo plus the holder’s declared details.

Body / Params

session_token, id_type, id_number, nationality, first_name, last_name, dob, id_photo (file)

Returns

id_verified, next_step

POST/verify/face/submit

Multipart. Uploads a selfie; triggers async biometric face-match processing.

Body / Params

session_token, selfie (file)

Returns

processing, estimated_seconds

GET/verify/status/:session_token

Poll session status. Returns the VIT once verification completes.

Body / Params

none

Returns

status, vit, verification_level, identity_id, rejection_reason

GET/internal/users/:platform_user_id/status

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

Body / Params

none

Returns

verified, level, trust_score, aml_status, is_blacklisted

GET/internal/users/:platform_user_id/vit

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

Body / Params

none

Returns

token, payload

DELETE/internal/users/:platform_user_id

Right-to-erasure: deletes stored photos and scrubs identifying fields (NDPA/GDPR).

Body / Params

none

Returns

erased, identity_id

Business verification (KYB)

POST/kyb/register

Registers a business for verification. Creates a KYB entity, pending.

Body / Params

business_name, registration_number, registration_country, registration_type, business_address?

Returns

kyb_entity_id, verification_status

POST/kyb/:id/document

Multipart. Uploads the business’s registration certificate.

Body / Params

document (file)

Returns

kyb_entity_id, verification_status

POST/kyb/:id/directors

Attaches a director/beneficial owner by their own verified_identity_id.

Body / Params

verified_identity_id, role

Returns

kyb_entity_id, verification_status

GET/kyb/:id/status

Poll KYB progress: document, director count, screening result.

Body / Params

none

Returns

verification_status, verification_level, director_count, has_document, rejection_reason

Errors

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

HTTPCodeMeaning
400validation_errorMissing or invalid request body field.
401unauthorizedAPI key missing, invalid, or the X-Platform header is missing.
403forbiddenAPI key does not have the permission required for this endpoint.
404not_foundSession token, identity, or KYB entity not found.
429rate_limit_exceededSlow down. Retry after retry_after seconds.
500internal_errorSomething went wrong on our end. Contact support.