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

CodeMeaning
400Bad Request — missing or invalid parameters
401Unauthorized — invalid, missing, or deactivated API key
404Not Found — endpoint or resource does not exist
429Too Many Requests — rate limit or monthly quota exceeded
500Internal 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

FieldTypeDescription
address_rawstring requiredThe raw, unstructured Nigerian address
countrystring optionalCountry code (default: "NG")
hints.lgastring optionalKnown LGA to improve parsing accuracy
hints.statestring optionalKnown state to improve parsing accuracy
options.geocodeboolean optionalEnable geocoding (default: true)
options.confidence_thresholdnumber optionalMinimum 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

ConfidenceStatus
≥ 0.75validated
0.50 – 0.74low_confidence
< 0.50unresolvable

Validation Flags

FlagMeaning
LGA_MISMATCHLGA from parser doesn't match LGA from geocoder boundary check
LANDMARK_ONLYNo street name found — only landmarks
STATE_INFERREDState was not explicitly stated, was inferred by the parser
GEOCODE_FALLBACKPrimary geocoder failed, fallback geocoder was used
LOW_LLM_CONFIDENCELLM 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.

ParameterTypeDescription
qstring requiredSearch query (minimum 3 characters)
statestring optionalFilter by state
lgastring optionalFilter 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:

PatternExample
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

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:

StateAliasesCapitalLGA Count
LagosEko, LasgidiIkeja20
FCTAbujaAbuja6
RiversPH, Port HarcourtPort Harcourt23
KanoKano44
OyoIbadanIbadan33
EnuguEnugu17

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}`);