API Reference

Complete endpoint documentation for the Veriadd REST API. Base URL: https://api.veriadd.tech

Note:All responses are JSON. Timestamps are ISO-8601 UTC. Monetary amounts are expressed in both kobo (integer) and NGN (float) for precision.

POST /v1/verify/address

The primary KYC endpoint. Resolves a NIPOST postcode and optionally cross-checks the supplied identity fields (BVN, phone, NIN) to return a graded verification decision.

POST/v1/verify/addressX-API-Key (required)

Request body

ParamTypeReqDescription
postcodestringrequiredNIPOST 5-segment postcode e.g. LA-11-W06-TC-10. Hyphens are required; extra whitespace is stripped.
statestringoptionalSelf-reported state, matched against the registry address (+15).
first_namestringoptionalApplicant first name for BVN/NIN name matching.
last_namestringoptionalApplicant last name.
bvnstringoptional11-digit BVN. Triggers Dojah BVN lookup when provided. Hashed before storage.
phonestringoptionalNigerian mobile number (080/081/070/090 prefix). Triggers SIM-identity lookup.
ninstringoptional11-digit National Identification Number.
lgastringoptionalSelf-reported LGA, token-matched against the registry (+15).
streetstringoptionalSelf-reported street, fuzzy-matched against the house address (+5/+10).
dobstringoptionalDate of birth (yyyy-mm-dd) used for BVN validation.
levelintegeroptionalNIPOST lookup depth 1–5. Billing: L1 free, L2 ₦30, L3+ ₦50. Defaults to 3.
request
json
{
  "postcode":   "LA-11-W06-TC-10",
  "state":      "LAGOS",
  "first_name": "Adaeze",
  "last_name":  "Okafor",
  "bvn":        "22233344455",
  "phone":      "08031234567",
  "level":      3
}

Response

200 response
json
{
  "data": {
    "audit_id":           "9b2ac137-f5a0-4c3d-8e6f-abcd12345678",
    "status":             "verified",
    "confidence":         92,
    "reasons": [
      "postcode valid (+40)",
      "state match (+5)",
      "bvn name match (+25)",
      "phone identity match (+22)"
    ],
    "postcode_canonical": "LA-11-W06-TC-10",
    "nipost": {
      "state":    "LAGOS",
      "lga":      "Eti-Osa",
      "locality": "Victoria Island",
      "building_use": "residential"
    },
    "identity": {
      "bvn_verified":   true,
      "phone_verified": true,
      "nin_verified":   false
    },
    "billed_kobo": 5000,
    "billed_ngn":  50
  }
}

status is one of verified partial failed invalid. Gate onboarding on status === "verified" && confidence >= 80.

GET /v1/lookup

Direct NIPOST postcode lookup with L1/L2/L3 depth control. L1 is free and unauthenticated.

GET/v1/lookup?code=&level=Optional key (required for L2/L3)
ParamTypeReqDescription
codestringrequiredNIPOST postcode.
levelintegeroptional1–3 (default 1). Higher levels return more address detail and may bill the wallet.
example
bash
curl "https://api.veriadd.tech/v1/lookup?code=LA-11-W06-TC-10&level=1"

GET /v1/search/autocomplete

Segment-aware typeahead for partial postcodes. Returns suggestions for the active segment. Free, no key needed.

GET/v1/search/autocomplete?q=Public
ParamTypeReqDescription
qstringrequiredPartial postcode, e.g. 'EK 01 A' (segment-aware).
bash
curl "https://api.veriadd.tech/v1/search/autocomplete?q=LA-11"

GET /v1/search/nearby

Find postcodes within a radius of a coordinate. Useful for field agent apps and delivery routing.

GET/v1/search/nearby?lat=&lng=&radius=Public
ParamTypeReqDescription
latfloatrequiredLatitude in decimal degrees.
lngfloatrequiredLongitude in decimal degrees.
radiusfloatoptionalSearch radius in metres (default 300).
bash
curl "https://api.veriadd.tech/v1/search/nearby?lat=6.4549&lng=3.4204&radius=2"

GET /v1/search/reverse

Reverse-geocode a coordinate to its nearest verified postcode.

GET/v1/search/reverse?lat=&lng=Public
ParamTypeReqDescription
latfloatrequiredLatitude.
lngfloatrequiredLongitude.
max_distance_mfloatoptionalSnap radius in metres (default 25, max 250).

Assembly / Disassembly

Parse a postcode into its component segments, or assemble components into a canonical code. Useful for validating user input before a lookup.

GET/v1/assembly/disassemble?code=Public
POST/v1/assembly/assemblePublic
disassemble response (native NIPOST shape)
json
{
  "data": {
    "postcode": "LA-11-W06-TC-10",
    "display":  "LA 11 W06 TC 10",
    "compact":  "LA11W06TC10"
    // ... plus segment fields in NIPOST's native shape
  }
}

GET /v1/wallet

Returns the current wallet balance and pricing configuration for your API key.

GET/v1/walletX-API-Key (required)
response
json
{
  "data": {
    "client":         "My Fintech",
    "email":          "api@myfintech.ng",
    "balance_kobo":   150000,
    "balance_ngn":    1500,
    "price_l2_kobo":  3000,
    "price_l3_kobo":  5000
  }
}

GET /v1/usage

Returns a paginated log of API calls made with your key.

GET/v1/usage?limit=X-API-Key (required)
ParamTypeReqDescription
limitintegeroptionalNumber of entries to return (1–200, default 50).

Wallet top-up

Top up via Paystack. Initialize a checkout session, redirect the user, then verify to credit the wallet.

POST/v1/wallet/topup/initializeX-API-Key (required)
ParamTypeReqDescription
amount_kobointegerrequiredAmount to credit in kobo (minimum 10000 = ₦100).
emailstringrequiredCustomer email passed to Paystack.
callback_urlstringoptionalURL Paystack redirects to after checkout.
topup/initialize response
json
{
  "data": {
    "authorization_url": "https://checkout.paystack.com/...",
    "access_code":       "...",
    "reference":         "veriadd_1699123456_abc123"
  }
}
GET/v1/wallet/topup/verify?reference=X-API-Key (required)
Warning:The verify endpoint is idempotent on reference — it is safe to call multiple times. Wallet is only credited once per reference.

KYB verification

New workspaces start in sandbox: test keys route to sandbox upstreams and are never billed. Live billable traffic unlocks when KYB is approved. Submit business details (RC auto-checked against CAC), track review, resubmit on rejection.

GET/v1/kybX-API-Key or session
POST/v1/kybX-API-Key or session
ParamTypeReqDescription
business_namestringrequiredRegistered business name (matched against CAC).
rc_numberstringrequiredCAC registration (RC) number.
company_typestringrequiredBUSINESS_NAME, COMPANY, INCORPORATED_TRUSTEES, LIMITED_PARTNERSHIP or LIMITED_LIABILITY_PARTNERSHIP.
registered_addressstringoptionalRegistered business address.
websitestringoptionalCompany website.
use_casestringoptionalHow you will use Veriadd.
submission response
json
{
  "data": {
    "id": "…",
    "business_name": "Demo Lender Ltd",
    "rc_number": "1234567",
    "cac_verified": true,
    "cac_legal_name": "DEMO LENDER LIMITED",
    "status": "under_review"   // or "approved" with instant CAC match
  }
}

Live keys calling billable endpoints without approval receive 403 kyb_required. Test keys without sandbox credentials receive 503 sandbox_not_configured.

GET /health · GET /v1/status

Liveness probe. Returns 200 when the server is up. No authentication required.

GET/healthPublic
json
{ "status": "ok" }

GET /v1/status powers the public status page: live Postgres/Redis pings plus upstream key presence. Public, no key needed.

status response
json
{
  "data": {
    "service": "veriadd", "version": "0.1.0",
    "time": "2026-10-03T09:00:00Z", "uptime_seconds": 45213,
    "deps": {
      "postgres": { "ok": true, "latency_ms": 3 },
      "redis":    { "ok": true, "disabled": false, "latency_ms": 1 },
      "nipost":   { "configured": true },
      "dojah":    { "configured": true },
      "paystack": { "configured": true }
    }
  }
}