Why this API Endpoints Integration Guide Scope & Limits FAQ View Docs ↓

Free · Open · No Auth Required

Nigerian geo-data,
finally structured.

One API for all 36 states + FCT, 774 LGAs, GPS coordinates, NIPOST postal codes, geopolitical zones, routing, reverse geocoding, and proximity search — built for Nigerian developers tired of building location data from scratch.

GET nigeria.jamiuadewaleyusuf.com/api/v1/states/lagos/lgas
{
  "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
  ]
}
37 States + FCT
774 LGAs covered
20 API Endpoints
6 Geo Zones
0 Auth required
₦0 Cost forever

The Problem

Every Nigerian developer has built this themselves — at least twice.

Shipping a product in Nigeria means writing the same address form logic, the same state/LGA arrays, the same KYC dropdowns, the same Google Maps bill — over and over. This API ends that cycle.

😤
Hardcoded state arrays
Most teams maintain a static JSON or PHP array of states and LGAs, copied from another project, riddled with spelling inconsistencies and missing new LGAs.
📍
No coordinates or postal codes
When location features land on the roadmap — delivery radius, store finder, nearest agent — the team has to source coordinates manually from Wikipedia or Google Maps.
🔄
Inconsistent data across products
"Akwa Ibom" appears as "Akwa-Ibom", "AkwaIbom", "Cross-River" — especially across microservices. Slugs, ISO codes, and consistent naming solve this permanently.
🏦
KYC & fintech onboarding
Address verification, state-of-origin fields, and document validation all need authoritative location data with postal codes matching NIPOST format.
🚚
Delivery & logistics
E-commerce platforms need to know if a customer address is within delivery range. The proximity endpoint returns nearby LGAs sorted by distance in km.
💸
Google Maps is expensive
Geocoding, routing, autocomplete — billed per call, no generous free tier for Nigerian developer budgets. This API replaces all of it at zero cost.

API Reference

20 endpoints. Zero setup.

No API key. No registration. No rate limit headers. All responses return a consistent JSON envelope.

BASE URL https://nigeria.jamiuadewaleyusuf.com/api/v1

Response Envelope

{
  "status": "success",  // or "error"
  "data":   { ... },
  "meta":   { "total": 20 }
}
// Errors:
{
  "status":  "error",
  "message": "State not found"
}

Slug resolution

All {slug} params accept slug (lagos), name (Lagos), or ISO code (NG-LA). Case-insensitive.

HTTP codes

200 Success  ·  404 Not found  ·  422 Validation error

ParamTypeRequiredDescription
geo_zonestringoptionalFilter: NC NE NW SE SS SW

Example

GET /api/v1/states?geo_zone=SW

{
  "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 }
}

Accepts slug, state name, or ISO 3166-2:NG code. Case-insensitive.

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
  }
}

Returns geographic bounding box and center point. Use to fly a map camera to show a full state.

GET /api/v1/states/lagos/bounds

{
  "data": {
    "state": "Lagos",
    "south": 6.3934, "north": 6.7022,
    "west": 3.0982,  "east": 3.7297,
    "center": { "lat": 6.5244, "lng": 3.3792 }
  }
}
ParamTypeRequiredDescription
statestringoptionalFilter by state slug or name
GET /api/v1/lgas?state=kano
ParamTypeRequiredDescription
qstringrequiredSearch term, min 2 chars
statestringoptionalScope to a single state
GET /api/v1/lgas/search?q=aba&state=abia
GET /api/v1/lgas/ikeja/bounds

{
  "data": {
    "lga": "Ikeja", "state": "Lagos",
    "south": 6.5518, "north": 6.6518,
    "west": 3.3015,  "east": 3.4015,
    "center": { "lat": 6.6018, "lng": 3.3515 }
  }
}
ParamTypeRequiredDefaultDescription
radiusfloatoptional50Radius in km (max 500)
limitintoptional10Max results (max 50)
GET /api/v1/lgas/ikeja/nearby-lgas?radius=30&limit=5
GET /api/v1/geo-zones

{
  "data": [{
    "zone": "NC", "zone_full": "North Central",
    "state_count": 7, "states": [ ... ]
  }],
  "meta": { "total_zones": 6 }
}

Accepts short form (SW) or full name (South West).

GET /api/v1/geo-zones/SW/states
ParamTypeRequiredDescription
codestringrequiredNIPOST code (3–10 digits). Tries exact LGA match, falls back to state prefix.
GET /api/v1/postal-codes/lookup?code=100283
ParamTypeRequiredDefaultDescription
latfloatrequiredLatitude
lngfloatrequiredLongitude
radiusfloatoptional100km, max 500
limitintoptional10max 50
typestringoptionallgalga or state
GET /api/v1/nearby?lat=6.45&lng=3.39&radius=30&limit=5

Calls Nominatim (OpenStreetMap) + enriches with local LGA/state from DB. Cached 24h. Falls back to local DB if Nominatim is down.

ParamTypeRequired
latfloatrequired
lngfloatrequired
GET /api/v1/geocode/reverse?lat=6.45&lng=3.39

{
  "data": {
    "full_address": "Allen Avenue, Ikeja, Lagos, Nigeria",
    "coordinates": { "lat": 6.45, "lng": 3.39 },
    "address_parts": {
      "road": "Allen Avenue", "suburb": "Ikeja",
      "city": "Lagos", "postcode": "100281"
    },
    "lga":   { "name": "Ikeja", "postal_code": "100281" },
    "state": { "name": "Lagos", "geo_zone": "SW" },
    "source": "nominatim+local"
  }
}

Queries Nominatim constrained to Nigeria. Returns short names for dropdown display. Cached 1h.

ParamTypeRequiredDescription
qstringrequiredMin 3 chars
limitintoptionalMax 10, default 8
GET /api/v1/geocode/search?q=Victoria+Island+Lagos&limit=5

No external API calls — purely local Haversine match. No rate limit. Use for bulk GPS log processing or analytics pipelines.

POST /api/v1/geocode/batch
Content-Type: application/json

{
  "points": [
    { "lat": 6.45, "lng": 3.39 },
    { "lat": 9.07, "lng": 7.39 }
  ]
}

// Each returns: lga, state, distance_to_lga_center_km
GET /api/v1/geocode/validate?lat=6.45&lng=3.39

{
  "data": {
    "lat": 6.45, "lng": 3.39,
    "valid": true, "in_nigeria": true,
    "nearest_lga": {
      "name": "Ikeja", "state": "Lagos", "distance_km": 2.3
    }
  }
}

Powered by OSRM (free, no key). Returns Leaflet-ready polyline. Falls back to Haversine if OSRM unavailable. Cached 30min.

ParamTypeRequiredDescription
from_lat / from_lngfloatrequiredOrigin coordinates
to_lat / to_lngfloatrequiredDestination coordinates
profilestringoptionaldriving | walking | cycling
GET /api/v1/route?from_lat=6.45&from_lng=3.39&to_lat=9.07&to_lng=7.39

{
  "data": {
    "distance_km": 487.3,
    "duration_minutes": 365,
    "duration_text": "6 hr 5 mins",
    "profile": "driving",
    "polyline": [[6.45, 3.39], [6.48, 3.41], ...],
    "steps": [
      { "instruction": "turn right", "name": "Allen Avenue",
        "distance_km": 0.8, "duration_min": 3 }
    ],
    "source": "osrm"
  }
}
ParamTypeRequiredDescription
fromstringrequiredOrigin LGA slug
tostringrequiredDestination LGA slug
profilestringoptionaldriving | walking | cycling
GET /api/v1/route/lgas?from=ikeja&to=lekki&profile=driving

Pure Haversine calculation. Includes rough duration estimate at 40km/h. Zero latency. Use for eligibility checks ("is this within 20km?").

GET /api/v1/distance?from_lat=6.45&from_lng=3.39&to_lat=9.07&to_lng=7.39

{
  "data": {
    "distance_km": 418.2, "duration_minutes": 627,
    "duration_text": "10 hr 27 mins",
    "note": "Straight-line estimate. Road distance will be longer.",
    "source": "haversine"
  }
}

Up to 10 origins × 10 destinations = 100 pairs. Results sorted by distance. Use for nearest-warehouse, nearest-agent, or coverage analysis.

POST /api/v1/distance/matrix

{
  "origins": [
    { "lat": 6.45, "lng": 3.39, "label": "Warehouse Lagos" }
  ],
  "destinations": [
    { "lat": 9.07, "lng": 7.39, "label": "Customer Abuja" },
    { "lat": 4.81, "lng": 7.04, "label": "Customer PH" }
  ]
}

// Returns all pairs sorted by distance_km

Integration Guide

Drop it into anything in minutes.

Ready-made snippets for the most common Nigerian dev stacks.

const BASE = 'https://nigeria.jamiuadewaleyusuf.com/api/v1';

// State + LGA cascade
const states = await fetch(`${BASE}/states`).then(r => r.json());
const { data: lgas } = await fetch(`${BASE}/states/lagos/lgas`).then(r => r.json());

// Reverse geocode (replaces Google Geocoding API)
const geo = await fetch(`${BASE}/geocode/reverse?lat=6.45&lng=3.39`).then(r => r.json());

// Address autocomplete (replaces Google Places)
const places = await fetch(`${BASE}/geocode/search?q=Victoria+Island&limit=5`).then(r => r.json());

// Road route + polyline (replaces Google Directions)
const route = await fetch(
  `${BASE}/route?from_lat=6.45&from_lng=3.39&to_lat=9.07&to_lng=7.39`
).then(r => r.json());

// Nearby LGAs
const nearby = await fetch(`${BASE}/nearby?lat=6.45&lng=3.39&radius=50`).then(r => r.json());

// Postal code lookup
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 reverseGeocode(float $lat, float $lng): ?array
    {
        return Http::get("{$this->base}/geocode/reverse", compact('lat', 'lng'))->json('data');
    }

    public function search(string $query, int $limit = 8): array
    {
        return Http::get("{$this->base}/geocode/search", ['q' => $query, 'limit' => $limit])->json('data');
    }

    public function route(float $fromLat, float $fromLng, float $toLat, float $toLng): array
    {
        return Http::get("{$this->base}/route", [
            'from_lat' => $fromLat, 'from_lng' => $fromLng,
            'to_lat'   => $toLat,   'to_lng'   => $toLng,
        ])->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 = "https://nigeria.jamiuadewaleyusuf.com/api/v1"

# States by zone
states = requests.get(f"{BASE}/states", params={"geo_zone": "SW"}).json()["data"]

# LGAs for a state
lgas = requests.get(f"{BASE}/states/lagos/lgas").json()["data"]

# Reverse geocode
geo = requests.get(f"{BASE}/geocode/reverse", params={"lat": 6.45, "lng": 3.39}).json()["data"]

# Address search
places = requests.get(f"{BASE}/geocode/search", params={"q": "Lekki Lagos", "limit": 5}).json()["data"]

# Routing
route = requests.get(f"{BASE}/route", params={
    "from_lat": 6.45, "from_lng": 3.39,
    "to_lat": 9.07,   "to_lng": 7.39
}).json()["data"]

# Distance matrix (POST)
matrix = requests.post(f"{BASE}/distance/matrix", json={
    "origins":      [{"lat": 6.45, "lng": 3.39, "label": "Lagos"}],
    "destinations": [{"lat": 9.07, "lng": 7.39, "label": "Abuja"}]
}).json()["data"]
import 'dart:convert';
import 'package:http/http.dart' as http;

const _base = 'https://nigeria.jamiuadewaleyusuf.com/api/v1';

Future<List> getStates() async {
  final res = await http.get(Uri.parse('$_base/states'));
  return jsonDecode(res.body)['data'];
}

Future<List> getLgas(String state) async {
  final res = await http.get(Uri.parse('$_base/states/$state/lgas'));
  return jsonDecode(res.body)['data'];
}

Future<Map> reverseGeocode(double lat, double lng) async {
  final uri = Uri.parse('$_base/geocode/reverse').replace(
    queryParameters: {'lat': '$lat', 'lng': '$lng'}
  );
  final res = await http.get(uri);
  return jsonDecode(res.body)['data'];
}

Future<Map> getRoute(double fromLat, double fromLng, double toLat, double toLng) async {
  final uri = Uri.parse('$_base/route').replace(queryParameters: {
    'from_lat': '$fromLat', 'from_lng': '$fromLng',
    'to_lat':   '$toLat',   'to_lng':   '$toLng',
  });
  final res = await http.get(uri);
  return jsonDecode(res.body)['data'];
}
import { useState, useEffect, useCallback } 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 [selected, setSelected] = useState('');

  useEffect(() => {
    fetch(`${BASE}/states`).then(r => r.json()).then(d => setStates(d.data));
  }, []);

  useEffect(() => {
    if (!selected) return setLgas([]);
    fetch(`${BASE}/states/${selected}/lgas`)
      .then(r => r.json()).then(d => setLgas(d.data));
  }, [selected]);

  return { states, lgas, setSelected };
}

// Address autocomplete hook
export function useAddressSearch() {
  const [results, setResults] = useState([]);

  const search = useCallback(async (q) => {
    if (q.length < 3) return setResults([]);
    const data = await fetch(`${BASE}/geocode/search?q=${encodeURIComponent(q)}&limit=6`)
      .then(r => r.json());
    setResults(data.data || []);
  }, []);

  return { results, search };
}
# All states
curl https://nigeria.jamiuadewaleyusuf.com/api/v1/states

# States by geo 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

# Reverse geocode
curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/geocode/reverse?lat=6.45&lng=3.39"

# Address autocomplete
curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/geocode/search?q=Victoria+Island"

# Road route
curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/route?from_lat=6.45&from_lng=3.39&to_lat=9.07&to_lng=7.39"

# LGA-to-LGA route
curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/route/lgas?from=ikeja&to=lekki"

# Nearby (Abuja)
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"

# Validate coordinates
curl "https://nigeria.jamiuadewaleyusuf.com/api/v1/geocode/validate?lat=6.45&lng=3.39"

# Distance matrix (POST)
curl -X POST https://nigeria.jamiuadewaleyusuf.com/api/v1/distance/matrix \
  -H "Content-Type: application/json" \
  -d '{"origins":[{"lat":6.45,"lng":3.39,"label":"Lagos"}],"destinations":[{"lat":9.07,"lng":7.39,"label":"Abuja"}]}'

Use Cases

Built for real Nigerian product problems.

Every endpoint was designed around a specific recurring pain in Nigerian product development.

🛒
E-commerce Checkout
Populate state → LGA cascading dropdowns. Validate postal codes. Auto-suggest delivery zone from device GPS.
🏦
Fintech KYC
Validate state of origin, LGA of residence, and postal codes during onboarding with authoritative NIPOST data.
🚚
Logistics & Delivery
Use /nearby or /distance to check if an address is within service radius. Route between warehouses and customers.
🗺️
Property & Real Estate
Filter listings by LGA. Show nearby LGAs. Reverse geocode device location. Draw polylines between properties.
🚗
Ride-Hailing & Transport
Real-time GPS tracking, route calculation with polylines, pickup/drop-off address display — all without Google.
📊
Data Analytics
Batch geocode GPS logs, group transaction data by geopolitical zone, normalize inconsistent location strings across datasets.
🏥
Healthcare & NGOs
Map patients to LGAs, generate zone-level reports, power humanitarian dashboards, find nearest facilities.
📱
Mobile Apps
Seed a local SQLite database from /states and /lgas for offline-capable Nigerian location pickers.
🏛️
Civic & GovTech
Electoral maps, constituency boundaries, zone-level analytics — structured with ISO codes and geo zone groupings.
🏗️
Micro-services
Replace inconsistent local arrays across services with a single source of truth — consistent slugs, ISO codes, spelling.
🔍
Address Autocomplete
Drop-in replacement for Google Places Autocomplete on Nigerian address fields. Returns coordinates + LGA + postal.
📦
Warehouse & Fleet
Distance matrix finds the nearest depot to any number of customers. Sort by km, plan multi-stop routes.

Scope & Limits

What this solves. What it does not.

Understanding the boundary is as important as understanding the capability. This is infrastructure, not a product — know where it ends.

✓ What this API solves

The hardcoded state/LGA array problem
One source of truth. Consistent slugs. ISO codes. Authoritative spelling. All 774 LGAs. Fetch once, or self-host.
Missing coordinates
Every state and LGA has GPS centroid coordinates. Every response includes a coordinates object.
Missing NIPOST postal codes
Every LGA has a 6-digit NIPOST code. Reverse lookup from postal code to LGA + state in one call.
Google Maps bill
Geocoding, autocomplete, routing, polylines — all replaceable with this API + free tools (OSRM, Nominatim, Leaflet). Zero cost.
Geopolitical zone grouping
NC/NE/NW/SE/SS/SW zones with states grouped. Not available in any other free structured API.
Proximity search
Find LGAs or states within any radius. Distance matrix for multi-origin, multi-destination logistics.

✗ What this API does NOT solve

Real-time traffic data
OSRM routing has no traffic awareness. Lagos go-slow, rush hour, flooding are not accounted for. Use Google Directions with departure_time=now for live traffic — no free alternative exists.
Street-level precision geocoding
Nominatim coverage of Nigerian streets is incomplete. Rural addresses, new estates, and informal settlement names may return no result. For precision: Google Geocoding API or Mapbox.
Business / POI data
Administrative boundaries only. No restaurants, hospitals, banks, or petrol stations. Use Google Places or OSM Overpass API (coverage varies).
Street View / 360° imagery
No free equivalent for Nigeria. Google Street View only.
Consumer voice navigation
OSRM routing is for developers drawing polylines, not end-user navigation. No voice guidance, no re-routing on deviation. Use Google Maps app or Waze.
Formal uptime guarantee
Community-hosted on Contabo VPS. No SLA. For production: cache state/LGA responses locally (they almost never change) or self-host.

Quick decision guide

What you need Free solution Paid if you need more
State / LGA dropdownThis API /states, /lgas
Postal codeThis API /postal-codes/lookup
Geopolitical zone groupingThis API /geo-zones
Coordinates for state / LGAThis API in every response
Proximity / nearest LGAThis API /nearby, /nearby-lgas
Map renderingFree Leaflet.js + OpenStreetMapGoogle Maps SDK
Address autocompleteThis API /geocode/searchGoogle Places API
Reverse geocode (lat → address)This API /geocode/reverseGoogle Geocoding API
Road route + polylineThis API /route via OSRMGoogle Directions API
Distance + duration estimateThis API /distanceGoogle Directions API
Real-time trafficNot available freeGoogle Directions API
Street ViewNot available freeGoogle Street View
Business / POI searchLimited OSM Overpass APIGoogle Places API
High-res satellite imageryNon-commercial EsriGoogle Maps / Mapbox
Consumer voice navigationUse Google Maps / WazeGoogle Maps SDK
High-volume geocoding (1000s/min)Self-host NominatimGoogle / Mapbox

Self-hosting for production scale

For high traffic, self-host Nominatim (free geocoding, Nigeria OSM ~120MB, ~2hr import) and OSRM (free routing, ~30min processing) on your own VPS. Then update GeoService.php to point to http://localhost:8080 and http://localhost:5000 respectively. After that: zero external dependencies, unlimited throughput.

# Self-host Nominatim (geocoding)
docker run -e PBF_URL=https://download.geofabrik.de/africa/nigeria-latest.osm.pbf \
  -p 8080:8080 mediagis/nominatim:4.4

# Self-host OSRM (routing)
wget https://download.geofabrik.de/africa/nigeria-latest.osm.pbf
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-extract -p /opt/car.lua /data/nigeria-latest.osm.pbf
docker run -t -i -p 5000:5000 -v $(pwd):/data osrm/osrm-backend osrm-routed --algorithm mld /data/nigeria-latest.osrm

FAQ

Common questions.

Yes, completely free and completely open. No registration, no API key, no rate limit headers to manage. Just make the request. If this API helps your product, share it with other Nigerian developers — that's the only ask.
State and LGA names come from the Nigerian Federal Government's official classification. Coordinates are centroid points from GeoNames and OpenStreetMap. Postal codes follow the official NIPOST 6-digit format. ISO codes are from ISO 3166-2:NG. Geopolitical zones are the Federal Government's standard 6-zone classification.
Coordinates represent the centroid of each LGA's major town or headquarters — not the geographic center of the LGA polygon. They are accurate enough for proximity search, map pins, zone calculations, and routing. For precision polygon-level LGA boundaries you would need a GeoJSON shapefile from a GIS source.
Absolutely. It is a standard Laravel 11 application. Clone the repo, run php artisan migrate && php artisan db:seed, and you have a private instance with no external dependencies. This is the recommended approach for teams with strict data residency requirements or high traffic needs.
Fetch /api/v1/states on page load to populate the state dropdown. When a user selects a state, fetch /api/v1/states/{slug}/lgas to populate the LGA dropdown. Both responses are fast enough for real-time use without client-side caching. See the React hook in the Integration Guide for a ready-made implementation.
For most Nigerian product use cases — address forms, delivery radius, map rendering, autocomplete, routing, reverse geocoding — yes, completely and at zero cost. The exceptions are real-time traffic, Street View, business/POI listings, and consumer voice navigation. See the Scope section for the full breakdown and decision guide.
Geocoding (reverse and forward) uses Nominatim — the open-source geocoder built on OpenStreetMap data, no API key required. Routing uses OSRM (Open Source Routing Machine) on the public demo server. All external calls are cached aggressively (geocoding 24h, routing 30min) and wrapped with local fallbacks, so the API never fails hard if they are temporarily unavailable.
CORS is fully open — you can call this API directly from browser JavaScript, React, Vue, Flutter Web, or any frontend without a proxy. If you are building a high-traffic application, consider self-hosting to avoid depending on external uptime.
This is a community resource hosted on a Contabo VPS monitored with Uptime Kuma. There is no formal SLA or uptime commitment. For production applications: cache state and LGA responses locally (they almost never change), and consider self-hosting your own instance for anything customer-facing. The original 9 endpoints (states, LGAs, geo-zones, postal, nearby) are 100% local DB — they work regardless of whether Nominatim or OSRM are reachable.
Common uses: checking if a customer address is within your delivery radius (set radius to your max km, check if result count > 0), finding the nearest service agent to a user, sorting property listings by proximity to a search point, and "stores near you" features. Pass type=state to find nearest states instead of LGAs. For pre-built convenience, use /lgas/{slug}/nearby-lgas to find all LGAs surrounding a known LGA without needing raw coordinates.