Identity & KYC
Part of AfriHex Verify — verify a customer's address before you lend, onboard, or deliver to them. AfriHex turns an address or a live GPS fix into a verifiable identity signal: structured address components, a confidence score, risk signals, fraud checks, and optionally a cryptographically signed certificate you can keep for compliance.
Verification is usually the start of a longer relationship, not the end: once a customer is onboarded, Location Monitoring and Collections & Service Areas (both part of AfriHex Operate) are what tell you if they've moved.
The quality score
Every resolved location carries quality_score (0.0–1.0), computed from data
completeness — street, area, postcode, bounding box, coordinates. Use it as your
threshold for "verified enough":
≥ 0.8— strong address, suitable for KYC without further checks.0.5 – 0.8— usable, but consider corroborating evidence.< 0.5— sparse; escalate for manual review.
Verify an address (KYC)
POST /v2/kyc/verify accepts four input methods. Pick the one that matches the
data you have:
| Method | location you send |
|---|---|
gps_fix | lat + lng from the customer's device |
hex_code | a hex code (e.g. from an earlier session) |
gps_code | a GhanaPostGPS code like GA-142-7281 |
manual | coords you type-checked yourself (lowest trust) |
Request object — POST /v2/kyc/verify:
| Parameter | Type | Required | Definition |
|---|---|---|---|
customer_id | string | required | Your customer identifier |
method | string | required | gps_fix, manual, hex_code, or gps_code |
location | object | required | Input matching the method: {lat,lng}, {hex_code}, or {gps_code} |
consent_token | string | required | The consent token (from monitoring consent) |
device_id | string | optional | Device identifier, for fraud correlation |
curl -X POST "https://api.afrihex.com/v2/kyc/verify" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_123",
"method": "gps_code",
"location": { "gps_code": "GA-142-7281" }
}'
{
"success": true,
"data": {
"verification_id": "uuid",
"verified": true,
"hex_code": "AF-GH-7-...",
"ghanapost_code": "GA-142-7281",
"address": { "region": "Greater Accra", "district": "Accra Metropolitan", "area": "Accra Central" },
"quality_score": 0.91,
"verification": { "method": "gps_code", "accuracy_meters": 250, "confidence": "high" },
"risk_signals": {
"known_residential_area": true,
"address_density": "high",
"previously_verified_by_others": true
}
}
}
Proximity verification
POST /v2/verify/proximity is for the moment you actually meet the customer:
compare their declared address with the live GPS fix from their device
and get a confidence score plus a device-integrity report (mock-location
detection, provider, accuracy, IP-geo consistency).
curl -X POST "https://api.afrihex.com/v2/verify/proximity" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_123",
"consent_token": "tok_...",
"declared_address": "GA-142-7281",
"device_location": {
"lat": 5.5561,
"lng": -0.1962,
"gps_accuracy_m": 12,
"is_mock_location": false
}
}'
{
"success": true,
"data": {
"verification_id": "6f3c…",
"result": "NEAR",
"verified": true,
"confidence": 0.97,
"declared_address": {
"gps_code": "GA1427281",
"region": "Greater Accra",
"district": "Accra",
"area": "West Ridge",
"postcode": "GA142"
},
"proximity": { "distance_m": 18.4, "within_threshold": true },
"integrity": {
"mock_location": "NOT_DETECTED",
"gps_accuracy": "GOOD",
"provider": "gps",
"ip_geo_match": "MATCH"
},
"timestamp": "2026-08-05T15:30:00Z"
}
}
The response returns result: NEAR | FAR, verified, confidence, and the
integrity factors. verified is true only when the device is NEAR and
confidence ≥ 0.6.
Request object — POST /v2/verify/proximity:
| Parameter | Type | Required | Definition |
|---|---|---|---|
customer_id | string | required | Your customer identifier |
consent_token | string | required | The consent token |
declared_address | string | required | The customer's declared GhanaPostGPS code |
device_location | object | required | The device's live fix — {lat, lng} plus optional integrity fields below |
device_id | string | optional | Device identifier |
device_signals | object | optional | e.g. { "timezone": "Africa/Accra" } |
device_location optional integrity fields: gps_accuracy_m, altitude_m,
speed_mps, bearing_deg, location_provider (gps/network/fused/
passive), is_mock_location, location_age_ms. When absent, the matching
integrity check reports NOT_PROVIDED instead of failing.
Signed certificates
When a verification passes, AfriHex can issue an Ed25519-signed certificate — a shareable, independently verifiable artifact for your records or a regulator:
# Get a verification certificate
curl "https://api.afrihex.com/v2/certificates/{id}" \
-H "X-API-Key: $AFRIHEX_API_KEY"
# Public verification (no API key needed) — an auditor can check any cert
curl "https://api.afrihex.com/v2/certificates/{id}/verify"
The public verification key is published at
/.well-known/verification-key.json, so anyone can verify a certificate
without an account.
{
"success": true,
"data": {
"certificate_id": "cert_…",
"valid": true,
"signature_valid": true,
"subject": { "hex_code": "AF-GH-7-0GXTQD5RFZZZZ", "quality_score": 0.91 },
"issued_at": "2026-08-05T15:30:00Z",
"revoked": false
}
}
Proof of delivery
POST /v2/pod/issue and POST /v2/pod/confirm issue a signed delivery receipt
at the point of handover and confirm it with a webhook
(delivery.confirmed) to your systems:
curl -X POST "https://api.afrihex.com/v2/pod/issue" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_123",
"declared_address": "GA-142-7281",
"consent_token": "tok_..."
}'
{
"success": true,
"data": {
"pod_id": "pod_9ab1",
"order_ref": "ORD-887",
"destination": { "hex_code": "AF-GH-7-0GXTQD5RFZZZZ", "label": "Customer doorstep" },
"confirmed_location": { "lat": 5.6041, "lng": -0.1953 },
"distance_m": 14.2,
"location_verified": true,
"recipient_verified": true,
"status": "issued",
"issuer": "delivery_partner"
}
}
The receipt carries a signature you can verify against the same public key, plus an optional webhook to your backend on confirmation.
Re-verification scheduling
POST /v2/verify/schedule schedules periodic re-verification (e.g. annually for
loan reviews); manage schedules with GET/DELETE /v2/verify/schedule/{id}.
Unlike kyc/verify and verify/proximity above, re-verification scheduling
requires Banking Suite access —
it's provisioned per institution.
Compliance notes
- An address match or proximity result is location evidence — not
guaranteed proof of identity, ownership, residence, creditworthiness, or
legality. A
verified: trueresult means a location claim was corroborated by data of a known quality; it is one input to your own decisioning policy, never the decision itself. This applies to every building block on this page — quality scores, proximity verification, signed certificates, and proof of delivery alike. See Understanding Confidence and Verification for the same principle spelled out field-by-field, and Risk & Fraud's compliance notes for how it extends to fraud and AML/PEP signals. - Every verification is persisted with a
verification_id, timestamp, and method, giving you an audit trail. If your account has Banking Suite access, retrieve it yourself withGET /v2/banking/audit-log. - Risk signals and fraud checks are advisory — combine them with your own
policies. A fraud check can be
degradedwhen a sub-check couldn't run (fewer signals than usual, not "nothing found") — see Fraud detection. - See Fraud & Risk for the fraud-detection layer that runs alongside KYC.
API reference
See Identity & KYC — API Reference for every endpoint in this group.