Location Monitoring
Consent-based, background location tracking for loan portfolios. Instead of re-verification calls that borrowers ignore, the bank's app reports location silently on a schedule, and AfriHex alerts you the moment a borrower drifts out of their zone.
The flow is always:
consent → register zones → pings (on a schedule) → drift detection → webhook alert
1. Grant consent
Monitoring is opt-in. Record the customer's consent, including the hash of the signed legal document:
POST /v2/consent/grant
curl -X POST "https://api.afrihex.com/v2/consent/grant" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_123",
"loan_id": "loan_456",
"scope": "background_location",
"legal_document_hash": "sha256-of-signed-consent",
"consent_token": "tok_...",
"duration_days": 365
}'
The consent_token is used on every ping. Revoke at any time with
POST /v2/consent/revoke and check status with GET /v2/consent/status.
Grant in bulk with POST /v2/consent/bulk-grant.
Request object — POST /v2/consent/grant:
| Parameter | Type | Required | Definition |
|---|---|---|---|
customer_id | string | required | Your identifier for the customer |
loan_id | string | required | Your identifier for the loan |
legal_document_hash | string | required | SHA-256 of the signed consent document |
consent_token | string | required | Unique token used on every ping for this consent |
scope | string | optional | Defaults to background_location |
duration_days | integer | optional | Consent validity in days (default 365) |
2. Report a ping
The bank's app (or the SDK) sends the borrower's background location fix:
POST /v2/location/ping
curl -X POST "https://api.afrihex.com/v2/location/ping" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_123",
"loan_id": "loan_456",
"lat": 5.6041,
"lng": -0.1953,
"consent_token": "tok_...",
"source": "gps"
}'
{
"success": true,
"data": { "status": "ok", "next_ping_in": "daily" }
}
The response is intentionally minimal (bandwidth matters on mobile). Send
source: "none" with lat/lng of 0 as a heartbeat when the device has no
GPS fix — the platform flags a borrower "going dark" instead of just seeing
silence.
Request object — POST /v2/location/ping:
| Parameter | Type | Required | Definition |
|---|---|---|---|
customer_id | string | required | Your customer identifier |
loan_id | string | required | Your loan identifier |
lat / lng | number | required | The device's location fix (0 if none) |
consent_token | string | required | The token from the consent grant |
captured_at | integer | optional | Unix epoch ms when the fix was captured |
source | string | optional | gps, network, or none (location off) |
Schedule
Set the ping frequency per loan — riskier or higher-value loans can ping more often:
POST /v2/monitoring/schedule with frequency: "2h" | "6h" | "daily" | "weekly".
Read it with GET /v2/monitoring/schedule.
| Parameter | Type | Required | Definition |
|---|---|---|---|
loan_id | string | required | The loan to schedule |
customer_id | string | required | The customer |
frequency | string | required | 2h, 6h, daily, or weekly |
3. Drift detection
Each ping is compared against the borrower's registered zones. If they move outside, a drift event fires and a webhook is dispatched.
GET /v2/monitoring/drift?customer_id=cust_123
{
"success": true,
"data": {
"events": [
{
"event_id": "evt_...",
"customer_id": "cust_123",
"from_hex": "AF-GH-7-0GXTQD5RFZZZZ",
"to_hex": "AF-GH-7-0GXTQD5RJ0000",
"distance_hops": 4,
"timestamp": "2026-08-06T08:00:00Z"
}
]
}
}
Also available: GET /v2/monitoring/summary, GET /v2/monitoring/history
(location timeline for dispute resolution), and GET /v2/monitoring/staleness
(borrowers who've gone silent).
4. Get alerted (webhooks)
Configure a webhook once; drift and geofence events are POSTed to you automatically:
POST /v2/webhooks/configure
curl -X POST "https://api.afrihex.com/v2/webhooks/configure" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://bank.example.com/webhooks/afrihex",
"secret": "a-long-random-secret",
"event_types": ["drift", "geofence_breach"]
}'
Deliveries are signed with X-Webhook-Signature (HMAC-SHA256), retried with
backoff, and inspectable via GET /v2/webhooks/deliveries. See
Webhooks for the full contract.
Request object — POST /v2/webhooks/configure:
| Parameter | Type | Required | Definition |
|---|---|---|---|
url | string | required | HTTPS endpoint that receives the events |
secret | string | required | HMAC signing secret (stored encrypted) |
event_types | array<string> | optional | Defaults to ["drift"]; e.g. ["drift","geofence_breach"] |
5. Geofences (beyond the home zone)
Beyond "moved from home", define custom geofences — "alert if the borrower enters a known high-risk area", or "if they go more than 50 km from Accra":
curl -X POST "https://api.afrihex.com/v2/geofence/create" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Ashaiman high-risk zone",
"shape": { "type": "polygon", "coordinates": [[5.55,-0.19], [5.56,-0.18], [5.57,-0.19], [5.55,-0.19]] }
}'
POST /v2/geofence/check— is a coordinate inside a geofence?GET /v2/geofence/list,DELETE /v2/geofence/{id}— manage them.- A ping inside a geofence fires the
geofence_breachwebhook event.
6. Export
Pull monitoring data into your own risk models or regulators:
GET /v2/export/pings?loan_ids=...&format=csvGET /v2/export/drift?days=90&format=csvGET /v2/export/zones?format=csv
SDK
The TypeScript SDK wraps the whole flow — see SDK → monitoring:
await afrihex.consent.grant({customer_id, loan_id, ...})
await afrihex.location.ping({customer_id, loan_id, lat, lng, consent_token})
const drift = await afrihex.monitoring.drift({customer_id})
API reference
See Location Monitoring — API Reference for every endpoint in this group.