Integrate Urania’s RESTful GeoData API into your applications with ease.
Fetch datasets like countries, states, cities, and postal codes — all from one unified API.
The Urania API provides seamless access to geo datasets in a RESTful, developer-friendly way.
All requests require an X-API-Key header for authentication — no OAuth, no tokens, no complexity.
GET https://urania.obilodev.com/v1/countries
Headers:
X-API-Key: YOUR_API_KEY
Accept: application/json
Works in desktop, web, mobile, or server environments — just include your API key in the request header.
Every request must include your X-API-Key header.
Example using JavaScript (fetch):
const headers = { "X-API-Key": "YOUR_API_KEY" };
fetch("https://urania.obilodev.com/v1/countries", { headers })
.then(res => res.json())
.then(console.log)
.catch(console.error);
Want to cascade Countries - States - Cities into a HTML select form input, and cUrling using Javascript:
const countrySelect = document.getElementById('country');
const stateSelect = document.getElementById('state');
const citySelect = document.getElementById('city');
const API_KEY = 'your_api_key';
const BASE_URL = 'https://urania.obilodev.com/api/v1';
// Helper to fetch JSON
async function fetchData(url) {
const res = await fetch(url, {
headers: { 'X-API-KEY': API_KEY }
});
const json = await res.json();
return json.data || [];
}
// Populate countries
(async () => {
const countries = await fetchData(`${BASE_URL}/countries`);
countries.forEach(c => {
countrySelect.insertAdjacentHTML(
'beforeend',
``
);
});
})();
// When country changes → fetch states
countrySelect.addEventListener('change', async () => {
const countryId = countrySelect.value;
stateSelect.innerHTML = '';
citySelect.innerHTML = '';
if (!countryId) return;
const states = await fetchData(`${BASE_URL}/states?country_id=${countryId}`);
states.forEach(s => {
stateSelect.insertAdjacentHTML(
'beforeend',
``
);
});
});
// When state changes → fetch cities
stateSelect.addEventListener('change', async () => {
const stateId = stateSelect.value;
citySelect.innerHTML = '';
if (!stateId) return;
const cities = await fetchData(`${BASE_URL}/cities?state_id=${stateId}`);
cities.forEach(city => {
citySelect.insertAdjacentHTML(
'beforeend',
``
);
});
});
| Status | Meaning |
|---|---|
200 OK | Request successful |
400 Bad Request | Malformed or invalid parameters |
401 Unauthorized | Missing or invalid API key |
404 Not Found | Resource not found |
429 Too Many Requests | Rate limit exceeded |
500 Server Error | Unexpected internal error |
Every user works with Projects. A project can have multiple API keys, each representing a deployment target — web, mobile, or backend.
Urania automatically logs your API activity. You can view usage statistics, performance metrics, and error breakdowns — all from your project dashboard.
Retrieve a list of all countries available in the dataset.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/countries", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/countries",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/countries", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/countries", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/countries")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/countries");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/countries" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"countries": [
"Afghanistan",
"Aland Islands",
"Albania",
"Algeria",
"American Samoa"
]
},
"status": "success"
}
Retrieve detailed information about a specific country available in the dataset.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/countries/{country}", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/countries/{country}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/countries/{country}", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/countries/{country}", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/countries/{country}")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/countries/{country}");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/countries/{country}" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"country": "Nigeria",
"iso2": "NG",
"iso3": "NGA",
"phoneCode": "+234",
"currency": "NGN",
"timezone": "Africa/Lagos",
"id": 152
},
"status": "success"
}
Fetch states within a specific country.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/countries/{country}/states", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/countries/{country}/states",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/countries/{country}/states", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/countries/{country}/states", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/countries/{country}/states")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/countries/{country}/states");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/countries/{country}/states" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"country": "Nigeria",
"states": [
"Abia",
"Adamawa",
"Akwa Ibom",
"Anambra",
"Bauchi"
]
},
"status": "success"
}
Fetch a list of all states in the dataset.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/states", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/states",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/states", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/states", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/states")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/states");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/states" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"states": [
"Abia",
"Adamawa",
"Akwa Ibom",
"Anambra",
"Bauchi"
]
},
"status": "success"
}
Retrieve all cities within a given state.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/states/{state}/cities", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/states/{state}/cities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/states/{state}/cities", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/states/{state}/cities", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/states/{state}/cities")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/states/{state}/cities");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/states/{state}/cities" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"state": "Abia",
"cities": [
"Aba",
"Umuahia",
"Ohafia",
"Arochukwu",
"Bende"
]
},
"status": "success"
}
Fetch a list of all cities in the dataset.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/cities", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/cities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/cities", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/cities", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/cities")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/cities");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/cities" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"cities": [
"Aba",
"Umuahia",
"Ohafia",
"Arochukwu",
"Bende"
]
},
"status": "success"
}
Retrieve information about a specific city available in the dataset.
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get("https://urania.obilodev.com/api/v1/cities/{city}", headers=headers)
print(response.json())
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://urania.obilodev.com/api/v1/cities/{city}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY"]
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import fetch from "node-fetch";
const res = await fetch("https://urania.obilodev.com/api/v1/cities/{city}", {
headers: { "X-API-Key": "YOUR_API_KEY" }
});
console.log(await res.json());
package main
import ("fmt"; "net/http"; "io/ioutil")
func main() {
req, _ := http.NewRequest("GET", "https://urania.obilodev.com/api/v1/cities/{city}", nil)
req.Header.Add("X-API-Key", "YOUR_API_KEY")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
use reqwest::blocking::Client;
fn main() -> Result<(), Box> {
let client = Client::new();
let res = client.get("https://urania.obilodev.com/api/v1/cities/{city}")
.header("X-API-Key", "YOUR_API_KEY")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
URL url = new URL("https://urania.obilodev.com/api/v1/cities/{city}");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-Key", "YOUR_API_KEY");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine; StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) response.append(inputLine);
in.close();
System.out.println(response.toString());
}
}
curl -X GET "https://urania.obilodev.com/api/v1/cities/{city}" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"
{
"code": 200,
"data": {
"name": "Aba",
"lat": "5.1200000",
"lng": "7.4000000",
"stateId": 1,
"countryId": null
},
"status": "success"
}
Urania API is Free of Charge — no subscription required.
Donations and gifts are always welcome to help keep the servers running 💙