Urania REST API v1.0

A high-performance, strictly typed REST API for geographical data worldwide. Covers sovereign nations, administrative divisions, cities, coordinates, and spatial queries.

Base URL: https://urania.obilodev.com/api/v1
Encoding: UTF-8
Format: application/json

Getting Started

All API access is conducted over HTTPS. Endpoints are versioned in the URI path under /v1/. To get started, obtain an API key from the developer dashboard.

Quick ping test
curl -H "X-API-Key: YOUR_API_KEY" \
  "https://urania.obilodev.com/api/v1/countries/NG"

Authentication

Pass your API key in every request using the X-API-Key HTTP request header.

Header Type Description
X-API-Key string Your project secret key (format: sk_live_...). Required for all non-public endpoints.
Accept string Set to application/json.
Security Note: Never expose your API key in public client-side browser code or mobile application binaries. Always proxy requests through your own backend server.

Response Conventions

Urania responses are standardized in a predictable envelope with two top-level keys: data and meta.

Standard Response Envelope
{
  "data": [
    // Resource object or array of objects
  ],
  "meta": {
    "timestamp": "2026-09-22T17:00:00.000000Z",
    "data_source": "REST Countries v3.1 / GeoNames / Manual curation",
    "last_updated": "2026-06-26T00:00:00Z",
    "pagination": {
      "current_page": 1,
      "last_page": 13,
      "per_page": 20,
      "total": 250,
      "from": 1,
      "to": 20
    },
    "record_count": 20
  }
}

HTTP Status Codes & Errors

Urania uses standard HTTP status codes to communicate success or failure:

Code Status Meaning
200 OK Success The request succeeded and returned the requested payload.
304 Not Modified Cached Payload has not changed since the provided If-None-Match ETag.
400 Bad Request Validation Error Invalid parameters supplied (e.g. missing lat/lng coordinates).
401 Unauthorized Auth Failure Missing, revoked, or invalid X-API-Key.
403 Forbidden Scope Denied API key does not hold the required permission scope (e.g., read-cities).
404 Not Found Not Found The requested country, state, or city identifier does not exist.
429 Too Many Requests Rate Limited You have exceeded your per-minute burst rate or monthly request quota.
500 Server Error Internal Error Unexpected server error. Our engineering team receives automatic incident alerts.

ETags & HTTP Caching

All read responses contain an ETag HTTP header representing a cryptographic hash of the content. You can pass this back in the If-None-Match request header. If the dataset has not changed, Urania responds with 304 Not Modified (0 bytes transferred, 0 quota consumed).

Rate Limits & Headers

Every authenticated request returns rate limit telemetry in the HTTP response headers:

Header Description
X-RateLimit-Limit Your per-minute burst rate ceiling (default: 1,000).
X-RateLimit-Remaining Remaining requests available in the current 60-second window.
X-RateLimit-Reset Unix epoch timestamp when the current rate limit window refreshes.

Endpoints Reference

GET /v1/status Public (No Key)

Returns realtime operational status of the Urania API and database connection.

Response (200 OK)
{
  "status": "operational",
  "version": "1.0.0",
  "database": "connected",
  "timestamp": "2026-09-22T17:00:00+00:00",
  "uptime": "0.04s"
}
GET /v1/countries Scope: read-countries

Retrieve a paginated list of all 250 sovereign countries and autonomous territories.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number for pagination.
per_pageinteger20Items per page (max: 100).
namestringnullCase-insensitive substring search across country names.
continentstringnullFilter by continent: Africa, Europe, Asia, Americas, Oceania, Antarctica.
regionstringnullFilter by UN region (e.g. Western Africa, Northern America).
currencystringnullFilter by 3-letter currency code (e.g. USD, EUR, NGN).
sortstringnameSort field: name, -name, population, -population, areaKm2, -areaKm2.
Sample Request
curl -H "X-API-Key: YOUR_KEY" \
  "https://urania.obilodev.com/api/v1/countries?continent=Africa&per_page=2"
Sample Response (200 OK)
{
  "data": [
    {
      "id": 160,
      "name": "Nigeria",
      "iso2": "NG",
      "iso3": "NGA",
      "phoneCode": "+234",
      "currency": "NGN",
      "flag": null,
      "flagEmoji": "🇳🇬",
      "timezone": "Africa/Lagos",
      "timezones": ["Africa/Lagos"],
      "continent": "Africa",
      "region": "Africa",
      "subregion": "Western Africa",
      "population": 218541212,
      "areaKm2": 923768,
      "languages": { "eng": "English", "hau": "Hausa", "yor": "Yoruba", "ibo": "Igbo" },
      "tld": [".ng"],
      "borders": ["BEN", "CMR", "TCD", "NER"],
      "lat": 10.0,
      "lng": 8.0
    }
  ],
  "meta": {
    "timestamp": "2026-09-22T17:00:00.000000Z",
    "data_source": "REST Countries v3.1 / GeoNames / Manual curation",
    "last_updated": "2026-06-26T00:00:00Z",
    "pagination": {
      "current_page": 1,
      "last_page": 27,
      "per_page": 2,
      "total": 54,
      "from": 1,
      "to": 2
    },
    "record_count": 2
  }
}
GET /v1/countries/{country} Scope: read-countries

Lookup a single country by its numeric database id, ISO 3166-1 alpha-2 code (e.g. NG, US, GB), or ISO 3166-1 alpha-3 code (e.g. NGA, USA, GBR).

Sample Request
curl -H "X-API-Key: YOUR_KEY" "https://urania.obilodev.com/api/v1/countries/NG"
GET /v1/countries/{country}/states Scope: read-countries, read-states

Fetch all administrative subdivisions (states, provinces, regions) belonging to the specified country.

Sample Request
curl -H "X-API-Key: YOUR_KEY" "https://urania.obilodev.com/api/v1/countries/NG/states"
GET /v1/countries/autocomplete?q={query} Scope: read-countries

Ultra-low-latency prefix search optimized for UI typeahead search fields.

Sample Response
{
  "data": [
    { "id": 160, "name": "Nigeria", "iso2": "NG", "iso3": "NGA" },
    { "id": 161, "name": "Niger", "iso2": "NE", "iso3": "NER" }
  ]
}
GET /v1/states Scope: read-states

Retrieve a paginated list of states and provinces across all countries.

Query Parameters

ParameterTypeDescription
country_codestringFilter states by country ISO2 code (e.g. NG, CA, US).
country_idintegerFilter states by internal country ID.
namestringCase-insensitive substring search for state names.
codestringExact match for state subdivision code (e.g. LA, ON, TX).
pageintegerPage number (default: 1).
per_pageintegerItems per page (max: 100).
Sample Response (200 OK)
{
  "data": [
    {
      "id": 90,
      "name": "Lagos",
      "capital": "Ikeja",
      "slogan": "Centre of Excellence",
      "code": "LA",
      "lat": 6.5244,
      "lng": 3.3792,
      "countryId": 160
    }
  ],
  "meta": {
    "pagination": { "current_page": 1, "total": 37, "per_page": 20 }
  }
}
GET /v1/states/{state} Scope: read-states

Retrieve single state details by numeric state ID or state code.

GET /v1/states/{state}/cities Scope: read-states, read-cities

Retrieve all cities within a specified state or province.

Sample Request
curl -H "X-API-Key: YOUR_KEY" "https://urania.obilodev.com/api/v1/states/90/cities"
GET /v1/states/autocomplete?q={query} Scope: read-states

Prefix search for state names and codes.

GET /v1/cities Scope: read-cities

Retrieve a paginated list of cities worldwide with coordinates.

Query Parameters

ParameterTypeDescription
state_idintegerFilter cities belonging to a parent state ID.
country_codestringFilter cities belonging to a country ISO2 code.
namestringCase-insensitive substring search for city name.
pageintegerPage number (default: 1).
per_pageintegerItems per page (max: 100).
Sample Response (200 OK)
{
  "data": [
    {
      "id": 14502,
      "name": "Ikeja",
      "lat": 6.6059,
      "lng": 3.3491,
      "stateId": 90,
      "countryId": 160
    }
  ]
}
GET /v1/cities/nearby Scope: read-cities

Find cities within a specified radius of a geographic coordinate point using the Haversine spatial equation.

Query Parameters

ParameterRequiredTypeDescription
latRequiredfloatLatitude (-90.0 to 90.0).
lngRequiredfloatLongitude (-180.0 to 180.0).
radiusOptionalintegerRadius in kilometers (default: 50, max: 500).
Sample Request
curl -H "X-API-Key: YOUR_KEY" \
  "https://urania.obilodev.com/api/v1/cities/nearby?lat=6.5244&lng=3.3792&radius=30"
Sample Response (200 OK)
{
  "data": [
    {
      "id": 14502,
      "name": "Ikeja",
      "lat": 6.6059,
      "lng": 3.3491,
      "stateId": 90,
      "countryId": 160,
      "distance_km": 9.65
    }
  ]
}
GET /v1/cities/{city} Scope: read-cities

Lookup a single city by its unique integer ID.

GET /v1/cities/autocomplete?q={query} Scope: read-cities

Instant prefix search across city names worldwide.

Generated Client SDKs

Urania compiles typed SDK client packages directly from its OpenAPI specification. You can download and import them directly into your project:

JavaScript / TypeScript
Zero-dependency typed fetch client for Node.js, Bun, and browser.
Download SDK (.zip)
Python
Clean OOP client wrapper built on Requests with dataclass models.
Download SDK (.zip)
PHP
PSR-18 HTTP client with full namespace support and response DTOs.
Download SDK (.zip)