API Reference
Complete reference for the Idumu address validation API. All endpoints require an API key passed via the Authorization header.
Authentication
Every request (except GET /health) requires a valid API key. Pass it as a Bearer token:
Authorization: Bearer idumu_abc123def456...
API keys are issued via the admin endpoint. Each key has a tier with a monthly call quota. When the quota is exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Base URL
https://api.idumu.ng/v1/
All versioned endpoints are prefixed with /v1/. The health check endpoint is at the root: /health.
Error Codes
| Code | Meaning |
|---|---|
400 | Bad Request — missing or invalid parameters |
401 | Unauthorized — invalid, missing, or deactivated API key |
404 | Not Found — endpoint or resource does not exist |
429 | Too Many Requests — rate limit or monthly quota exceeded |
500 | Internal Server Error — unexpected failure (retry or contact support) |
POST /v1/validate
The primary endpoint. Accepts a raw Nigerian address string, parses it, geocodes it, validates against LGA boundaries, and returns a structured, scored response.
Request Body
| Field | Type | Description |
|---|---|---|
address_raw | string required | The raw, unstructured Nigerian address |
country | string optional | Country code (default: "NG") |
hints.lga | string optional | Known LGA to improve parsing accuracy |
hints.state | string optional | Known state to improve parsing accuracy |
options.geocode | boolean optional | Enable geocoding (default: true) |
options.confidence_threshold | number optional | Minimum confidence threshold (0.0–1.0) |
Response
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "validated",
"confidence": 0.84,
"address": {
"raw": "opposite GTBank, Wuse 2, Abuja",
"parsed": {
"house_number": null,
"street": "Aminu Kano Crescent",
"landmark": "GTBank",
"reference_landmarks": ["GTBank"],
"area": "Wuse 2",
"lga": "Abuja Municipal",
"state": "FCT",
"postcode": null,
"country": "Nigeria"
},
"standardised": "Aminu Kano Crescent, Wuse 2, Abuja Municipal, FCT",
"geocode": {
"lat": 9.0634,
"lng": 7.4697,
"accuracy": "STREET_LEVEL"
}
},
"validation": {
"deliverable": true,
"residential_indicator": false,
"lga_confirmed": true,
"flags": []
},
"metadata": {
"processing_ms": 340,
"cache_hit": false,
"data_sources": ["llm_parser", "nominatim"]
}
}
Status Rules
| Confidence | Status |
|---|---|
| ≥ 0.75 | validated |
| 0.50 – 0.74 | low_confidence |
| < 0.50 | unresolvable |
Validation Flags
| Flag | Meaning |
|---|---|
LGA_MISMATCH | LGA from parser doesn't match LGA from geocoder boundary check |
LANDMARK_ONLY | No street name found — only landmarks |
STATE_INFERRED | State was not explicitly stated, was inferred by the parser |
GEOCODE_FALLBACK | Primary geocoder failed, fallback geocoder was used |
LOW_LLM_CONFIDENCE | LLM parser returned confidence below 0.6 |
POST /v1/validate/batch
Submit up to 100 addresses for asynchronous validation. Returns a batch ID immediately.
Request Body
{
"addresses": [
{ "address_raw": "opposite GTBank, Wuse 2, Abuja" },
{ "address_raw": "15 Awolowo Road, Ikoyi, Lagos" }
],
"webhook_url": "https://your-server.com/webhook"
}
Response (202 Accepted)
{
"batch_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"total_addresses": 2,
"message": "Batch processing started. Use GET /v1/batch/{batch_id} to check status."
}
GET /v1/batch/{batch_id}
Retrieve the current status and results (partial or complete) for a batch job.
GET /v1/autocomplete
Real-time address suggestions as a user types. Returns up to 5 matches from the landmark database.
| Parameter | Type | Description |
|---|---|---|
q | string required | Search query (minimum 3 characters) |
state | string optional | Filter by state |
lga | string optional | Filter by LGA |
GET /v1/usage
Returns usage statistics for the authenticated API key.
{
"calls_this_month": 1234,
"quota_remaining": 8766,
"monthly_limit": 10000,
"tier": "starter",
"daily_breakdown": [
{ "date": "2026-03-31", "count": 45 },
{ "date": "2026-03-30", "count": 62 }
],
"top_states": [
{ "state": "Lagos", "count": 520 },
{ "state": "FCT", "count": 310 }
],
"top_lgas": [
{ "lga": "Eti-Osa", "count": 180 },
{ "lga": "Abuja Municipal", "count": 145 }
]
}
GET /health
Public health check endpoint. No authentication required.
{
"status": "ok",
"version": "1.0.0",
"uptime_seconds": 86400,
"timestamp": "2026-03-31T12:00:00.000Z"
}
Nigeria Address Guide
Nigerian addresses are unique. Most people give directions using landmarks, not street numbers. Here are the common patterns Idumu handles:
| Pattern | Example |
|---|---|
| Landmark reference | "opposite GTBank, Wuse 2, Abuja" |
| Relative direction | "2nd house after the blue gate, off Awolowo Road, Ikoyi" |
| Road junction | "Allen Avenue / Adeniyi Jones junction, Ikeja" |
| Named area | "Balogun Market, Lagos Island" |
| Filling station reference | "near NNPC filling station, Aba Road, Port Harcourt" |
| Multiple landmarks | "behind the mosque, near Total petrol station, Ring Road, Benin" |
Tips for better results
- Pass
hints.stateandhints.lgawhen you know them — this significantly improves accuracy. - Include as many landmarks and references as the user provides.
- Common abbreviations (Rd, St, Ave, PH, Eko) are normalised automatically.
LGA/State Reference
Nigeria has 774 Local Government Areas across 36 states and the FCT. The API validates every parsed LGA against the official list. Common state aliases are supported:
| State | Aliases | Capital | LGA Count |
|---|---|---|---|
| Lagos | Eko, Lasgidi | Ikeja | 20 |
| FCT | Abuja | Abuja | 6 |
| Rivers | PH, Port Harcourt | Port Harcourt | 23 |
| Kano | — | Kano | 44 |
| Oyo | Ibadan | Ibadan | 33 |
| Enugu | — | Enugu | 17 |
cURL
curl -X POST https://api.idumu.ng/v1/validate \
-H "Authorization: Bearer idumu_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"address_raw": "opposite GTBank, Wuse 2, Abuja",
"country": "NG",
"options": { "geocode": true }
}'
Python
import requests
response = requests.post(
"https://api.idumu.ng/v1/validate",
headers={
"Authorization": "Bearer idumu_your_api_key_here",
"Content-Type": "application/json",
},
json={
"address_raw": "opposite GTBank, Wuse 2, Abuja",
"country": "NG",
"options": {"geocode": True},
},
)
data = response.json()
print(f"Status: {data['status']}, Confidence: {data['confidence']}")
print(f"Standardised: {data['address']['standardised']}")
print(f"Coordinates: {data['address']['geocode']['lat']}, {data['address']['geocode']['lng']}")
JavaScript
const response = await fetch("https://api.idumu.ng/v1/validate", {
method: "POST",
headers: {
"Authorization": "Bearer idumu_your_api_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
address_raw: "opposite GTBank, Wuse 2, Abuja",
country: "NG",
options: { geocode: true },
}),
});
const data = await response.json();
console.log(`Status: ${data.status}, Confidence: ${data.confidence}`);
console.log(`Standardised: ${data.address.standardised}`);
console.log(`Coordinates: ${data.address.geocode.lat}, ${data.address.geocode.lng}`);