Free · Open · No Auth Required
One API for all 36 states + FCT, 774 LGAs, GPS coordinates, NIPOST postal codes, geopolitical zones, and proximity search — built for Nigerian developers tired of building location dropdowns from scratch.
{
"status": "success",
"meta": {
"state": {
"name": "Lagos",
"capital": "Ikeja",
"geo_zone": "SW",
"iso_code": "NG-LA"
},
"total": 20
},
"data": [
{
"name": "Agege",
"slug": "agege",
"state": "Lagos",
"coordinates": {
"lat": 6.6167,
"lng": 3.3167
},
"postal_code": "100283"
},
// ... 19 more LGAs
]
}
The Problem
Shipping a product in Nigeria means writing the same address form logic, the same state/LGA arrays, the same KYC dropdowns — over and over. This API ends that cycle.
API Reference
No API key. No registration. Just fetch. All responses return a consistent JSON envelope.
| Param | Type | Required | Description |
|---|---|---|---|
| geo_zone | string | optional | Filter by zone code: NC NE NW SE SS SW |
Example Request
GET /api/v1/states?geo_zone=SW
Example Response
{
"status": "success",
"data": [
{
"id": 25,
"name": "Lagos",
"slug": "lagos",
"capital": "Ikeja",
"geo_zone": "SW",
"geo_zone_full": "South West",
"iso_code": "NG-LA",
"country_code": "NG",
"coordinates": { "lat": 6.5244, "lng": 3.3792 },
"postal_prefix": "100",
"lga_count": 20
}
],
"meta": { "total": 6 }
}
The {slug} parameter accepts:
slug (lagos), state name (Lagos),
or ISO code (NG-LA).
GET /api/v1/states/lagos GET /api/v1/states/Lagos # also works GET /api/v1/states/NG-LA # also works
GET /api/v1/states/rivers/lgas
{
"status": "success",
"data": [
{
"name": "Port Harcourt",
"slug": "port-harcourt",
"state": "Rivers",
"coordinates": { "lat": 4.8156, "lng": 7.0498 },
"postal_code": "500001"
}
],
"meta": {
"state": { "name": "Rivers", "capital": "Port Harcourt" },
"total": 23
}
}
| Param | Type | Required | Description |
|---|---|---|---|
| state | string | optional | Filter by state slug or name |
GET /api/v1/lgas?state=kano
| Param | Type | Required | Description |
|---|---|---|---|
| q | string | required | Search term, min 2 characters |
| state | string | optional | Scope to a single state |
GET /api/v1/lgas/search?q=aba&state=abia
Returns all 6 zones: North Central (NC), North East (NE), North West (NW), South East (SE), South South (SS), South West (SW) — each with their states grouped.
GET /api/v1/geo-zones
{
"status": "success",
"data": [
{
"zone": "NC",
"zone_full": "North Central",
"state_count": 7,
"states": [ ... ]
}
],
"meta": { "total_zones": 6 }
}
{zone} accepts short form (SW)
or full name (South West).
GET /api/v1/geo-zones/SW/states
| Param | Type | Required | Description |
|---|---|---|---|
| code | string | required | NIPOST postal code (3–10 digits) |
Tries exact LGA match first. Falls back to state-level prefix match (first 3 digits).
GET /api/v1/postal-codes/lookup?code=100283
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| lat | float | required | — | Latitude |
| lng | float | required | — | Longitude |
| radius | float | optional | 100 | Radius in km (max 500) |
| limit | int | optional | 10 | Max results (max 50) |
| type | string | optional | lga | lga or state |
GET /api/v1/nearby?lat=6.45&lng=3.39&radius=30&limit=5
{
"data": [
{
"name": "Lagos Island",
"state": "Lagos",
"coordinates": { "lat": 6.4531, "lng": 3.3958 },
"postal_code": "101221",
"distance_km": 1.84
}
],
"meta": {
"center": { "lat": 6.45, "lng": 3.39 },
"radius_km": 30,
"total": 5
}
}
{
"status": "success", // or "error"
"data": { ... }, // resource or array
"meta": { // present on lists
"total": 20,
"state": { ... }
}
}
// Error format
{
"status": "error",
"message": "State not found"
}
Consistent slug resolution
All {slug} parameters accept the slug (akwa-ibom), the state name (Akwa Ibom), or the ISO code (NG-AK). Case-insensitive.
HTTP Status Codes
200 — Success ·
404 — Not found ·
422 — Validation error
No authentication
This is a public API. No API key, no OAuth, no headers required. Just make the request.
Integration Guide
Ready-made snippets for the most common Nigerian dev stacks.
const BASE = '.jamiuadewaleyusuf.com/api/v1'; // Get all states const states = await fetch(`${BASE}/states`).then(r => r.json()); // Get LGAs for a state const { data: lgas } = await fetch(`${BASE}/states/lagos/lgas`).then(r => r.json()); // Find LGAs near a coordinate const nearby = await fetch( `${BASE}/nearby?lat=6.45&lng=3.39&radius=50&limit=10` ).then(r => r.json()); // Lookup postal code const location = await fetch(`${BASE}/postal-codes/lookup?code=100283`).then(r => r.json());
<?php use Illuminate\Support\Facades\Http; class NigeriaLocationService { private string $base = 'https://nigeria.jamiuadewaleyusuf.com/api/v1'; public function states(string $geoZone = null): array { $params = $geoZone ? ['geo_zone' => $geoZone] : []; return Http::get("{$this->base}/states", $params)->json('data'); } public function lgasByState(string $state): array { return Http::get("{$this->base}/states/{$state}/lgas")->json('data'); } public function nearby(float $lat, float $lng, int $radius = 100): array { return Http::get("{$this->base}/nearby", compact('lat', 'lng', 'radius'))->json('data'); } public function lookupPostal(string $code): ?array { $resp = Http::get("{$this->base}/postal-codes/lookup", ['code' => $code])->json(); return $resp['status'] === 'success' ? $resp['data'] : null; } }
import requests BASE = ".jamiuadewaleyusuf.com/api/v1" # All states in South West states = requests.get(f"{BASE}/states", params={"geo_zone": "SW"}).json()["data"] # LGAs by state lgas = requests.get(f"{BASE}/states/lagos/lgas").json()["data"] # Nearby nearby = requests.get(f"{BASE}/nearby", params={ "lat": 6.45, "lng": 3.39, "radius": 50 }).json()["data"] # Postal lookup location = requests.get(f"{BASE}/postal-codes/lookup", params={"code": "100283"}).json()
import 'dart:convert'; import 'package:http/http.dart' as http; const _base = 'https://nigeria.jamiuadewaleyusuf.com/api/v1'; // Get states Future<List> getStates() async { final res = await http.get(Uri.parse('$_base/states')); return jsonDecode(res.body)['data']; } // Get LGAs Future<List> getLgas(String state) async { final res = await http.get(Uri.parse('$_base/states/$state/lgas')); return jsonDecode(res.body)['data']; } // Nearby Future<List> getNearby(double lat, double lng, {int radius=100}) async { final uri = Uri.parse('$_base/nearby').replace(queryParameters: { 'lat': '$lat', 'lng': '$lng', 'radius': '$radius' }); final res = await http.get(uri); return jsonDecode(res.body)['data']; }
import { useState, useEffect } from 'react'; const BASE = 'https://nigeria.jamiuadewaleyusuf.com/api/v1'; // State → LGA cascade hook export function useNigeriaLocation() { const [states, setStates] = useState([]); const [lgas, setLgas] = useState([]); const [selectedState, setSelectedState] = useState(''); useEffect(() => { fetch(`${BASE}/states`) .then(r => r.json()) .then(d => setStates(d.data)); }, []); useEffect(() => { if (!selectedState) return; fetch(`${BASE}/states/${selectedState}/lgas`) .then(r => r.json()) .then(d => setLgas(d.data)); }, [selectedState]); return { states, lgas, setSelectedState }; }
# All states curl https://nigeria.jamiuadewaleyusuf.com/api/v1/states # States by geopolitical zone curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/states?geo_zone=SW" # LGAs for a state curl https://nigeria.jamiuadewaleyusuf.com/api/v1/states/lagos/lgas # Nearby (Abuja coords) curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/nearby?lat=9.0765&lng=7.3986&radius=50" # Postal code lookup curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/postal-codes/lookup?code=900001" # Search LGAs curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/lgas/search?q=aba"
Use Cases
FAQ
php artisan migrate && php artisan db:seed and you have your own private instance.
This is especially useful for teams with strict data residency requirements.
/api/v1/states on page load to populate your state dropdown.
When a user selects a state, fire a request to /api/v1/states/{slug}/lgas
to populate the LGA dropdown. Both responses are fast enough for real-time use without caching.
type=state to find the nearest states instead of LGAs.