API Documentation - Endpoints & Examples

All Cities

Overview

This endpoint returns a list of all cities available in the CountryDataAPI database. It provides a global listing of cities, making it ideal for applications that need to display or search through city-level data worldwide.

Country Data API provides detailed information about +200 different countries

Authentication

All API requests require authentication using an API key. Include your API key as a query parameter in each request:

?apikey=YOUR_API_KEY

You can obtain an API key by registering at CountryDataAPI.


Request

HTTP GET

https://api.countrydataapi.com/v1/cities/all

Returns a list of all cities

Every 5 cities returned will consume 1 token

Query Params


Parameter Type Description
apikey required, token Account authentication key
lang optional, lang en (default). Expected language of the response
limit optional, number 100 (default). Maximum number of cities to be returned

Response

Response Example

[
  {
    "id": "d54ba796-1136-4776-9776-537fd5a857c9",
    "lang": "en",
    "city_name": "Bala Morghab"
  }
]

Code Examples

JavaScript (Fetch)

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/all';

async function getAllCities(limit = 100) {
  try {
    const params = new URLSearchParams({
      apikey: API_KEY,
      lang: 'en',
      limit: limit.toString()
    });

    const response = await fetch(`${BASE_URL}?${params}`);

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const cities = await response.json();
    console.log(`Retrieved ${cities.length} cities`);
    return cities;
  } catch (error) {
    console.error('Error fetching cities:', error);
    throw error;
  }
}

// Usage
getAllCities(50);  // Get first 50 cities
getAllCities(200); // Get first 200 cities

JavaScript (Axios)

import axios from 'axios';

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/all';

async function getAllCities(limit = 100) {
  try {
    const response = await axios.get(BASE_URL, {
      params: {
        apikey: API_KEY,
        lang: 'en',
        limit: limit
      }
    });

    console.log(`Retrieved ${response.data.length} cities`);
    return response.data;
  } catch (error) {
    if (axios.isAxiosError(error)) {
      console.error('API Error:', error.response?.data || error.message);
    }
    throw error;
  }
}

// Usage
getAllCities(100);

React

import { useState, useEffect } from 'react';

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/all';

function CitiesList({ limit = 100 }) {
  const [cities, setCities] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchCities = async () => {
      try {
        setLoading(true);
        const params = new URLSearchParams({
          apikey: API_KEY,
          lang: 'en',
          limit: limit.toString()
        });

        const response = await fetch(`${BASE_URL}?${params}`);

        if (!response.ok) {
          throw new Error('Failed to fetch cities');
        }

        const data = await response.json();
        setCities(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchCities();
  }, [limit]);

  if (loading) return <div>Loading cities...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <h2>All Cities</h2>
      <p>Showing {cities.length} cities</p>
      <ul>
        {cities.map((city) => (
          <li key={city.id}>{city.city_name}</li>
        ))}
      </ul>
    </div>
  );
}

// City search with pagination
function CitiesWithPagination() {
  const [cities, setCities] = useState([]);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const pageSize = 50;

  const loadCities = async () => {
    setLoading(true);
    const params = new URLSearchParams({
      apikey: API_KEY,
      lang: 'en',
      limit: (page * pageSize).toString()
    });

    try {
      const response = await fetch(`${BASE_URL}?${params}`);
      const data = await response.json();
      setCities(data);
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadCities();
  }, [page]);

  return (
    <div>
      <h2>Cities ({cities.length})</h2>
      <ul>
        {cities.map((city) => (
          <li key={city.id}>{city.city_name}</li>
        ))}
      </ul>
      <button
        onClick={() => setPage(p => p + 1)}
        disabled={loading}
      >
        {loading ? 'Loading...' : 'Load More'}
      </button>
    </div>
  );
}

export default CitiesList;

Vue 3

<template>
  <div>
    <div v-if="loading">Loading cities...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else>
      <h2>All Cities</h2>
      <p>Showing {{ cities.length }} cities</p>
      <ul>
        <li v-for="city in cities" :key="city.id">
          {{ city.city_name }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue';

const props = defineProps({
  limit: {
    type: Number,
    default: 100
  }
});

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/all';

const cities = ref([]);
const loading = ref(true);
const error = ref(null);

const fetchCities = async () => {
  try {
    loading.value = true;
    error.value = null;

    const params = new URLSearchParams({
      apikey: API_KEY,
      lang: 'en',
      limit: props.limit.toString()
    });

    const response = await fetch(`${BASE_URL}?${params}`);

    if (!response.ok) {
      throw new Error('Failed to fetch cities');
    }

    cities.value = await response.json();
  } catch (err) {
    error.value = err.message;
  } finally {
    loading.value = false;
  }
};

watch(() => props.limit, fetchCities);
onMounted(fetchCities);
</script>

Angular

import { Component, Input, OnInit, OnChanges } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { CommonModule } from '@angular/common';

interface City {
  id: string;
  city_name: string;
  lang: string;
}

@Component({
  selector: 'app-cities-list',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div>
      <div *ngIf="loading">Loading cities...</div>
      <div *ngIf="error">Error: {{ error }}</div>
      <div *ngIf="!loading && !error">
        <h2>All Cities</h2>
        <p>Showing {{ cities.length }} cities</p>
        <ul>
          <li *ngFor="let city of cities">{{ city.city_name }}</li>
        </ul>
      </div>
    </div>
  `
})
export class CitiesListComponent implements OnInit, OnChanges {
  @Input() limit = 100;

  private readonly API_KEY = 'YOUR_API_KEY';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1/cities/all';

  cities: City[] = [];
  loading = true;
  error: string | null = null;

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.fetchCities();
  }

  ngOnChanges(): void {
    this.fetchCities();
  }

  private fetchCities(): void {
    this.loading = true;
    this.error = null;

    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('lang', 'en')
      .set('limit', this.limit.toString());

    this.http.get<City[]>(this.BASE_URL, { params }).subscribe({
      next: (data) => {
        this.cities = data;
        this.loading = false;
      },
      error: (err) => {
        this.error = err.message;
        this.loading = false;
      }
    });
  }
}

PHP

<?php

$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://api.countrydataapi.com/v1/cities/all';

function getAllCities($limit, $apiKey) {
    $baseUrl = 'https://api.countrydataapi.com/v1/cities/all';

    $params = http_build_query([
        'apikey' => $apiKey,
        'lang' => 'en',
        'limit' => $limit
    ]);

    $url = $baseUrl . '?' . $params;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        throw new Exception("HTTP Error: $httpCode");
    }

    return json_decode($response, true);
}

// Usage
try {
    $cities = getAllCities(100, $apiKey);

    echo "Retrieved " . count($cities) . " cities\n\n";

    foreach ($cities as $city) {
        echo "- " . $city['city_name'] . " (ID: " . $city['id'] . ")\n";
    }
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

// Calculate token usage
function calculateTokenUsage($cityCount) {
    return ceil($cityCount / 5);
}

$limit = 100;
$cities = getAllCities($limit, $apiKey);
echo "Cities retrieved: " . count($cities) . "\n";
echo "Tokens consumed: " . calculateTokenUsage(count($cities)) . "\n";
?>

Python

import requests

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://api.countrydataapi.com/v1/cities/all'

def get_all_cities(limit=100):
    """Fetch all cities from the CountryDataAPI."""
    params = {
        'apikey': API_KEY,
        'lang': 'en',
        'limit': limit
    }

    try:
        response = requests.get(BASE_URL, params=params)
        response.raise_for_status()

        cities = response.json()
        return cities
    except requests.exceptions.RequestException as e:
        print(f'Error fetching cities: {e}')
        raise

def calculate_token_usage(city_count):
    """Calculate tokens consumed (5 cities = 1 token)."""
    return (city_count + 4) // 5  # Ceiling division

# Usage
if __name__ == '__main__':
    limit = 100
    cities = get_all_cities(limit)

    print(f"Retrieved {len(cities)} cities")
    print(f"Tokens consumed: {calculate_token_usage(len(cities))}")
    print("\nFirst 10 cities:")

    for city in cities[:10]:
        print(f"  - {city['city_name']}")


# Async version with aiohttp
import aiohttp
import asyncio

async def get_all_cities_async(limit=100):
    """Fetch all cities asynchronously."""
    params = {
        'apikey': API_KEY,
        'lang': 'en',
        'limit': limit
    }

    async with aiohttp.ClientSession() as session:
        async with session.get(BASE_URL, params=params) as response:
            if response.status == 200:
                return await response.json()
            else:
                raise Exception(f'HTTP Error: {response.status}')

# Usage
# cities = asyncio.run(get_all_cities_async(200))

cURL

# Get first 100 cities (default)
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=en"

# Get first 50 cities
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=en&limit=50"

# Get 200 cities
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=en&limit=200"

# With pretty-printed JSON output
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=en&limit=100" | json_pp

# Save response to file
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=en&limit=500" -o all_cities.json

# Get cities in Spanish
curl -X GET "https://api.countrydataapi.com/v1/cities/all?apikey=YOUR_API_KEY&lang=es&limit=100"

Error Handling

The API may return the following error responses:

Status Code Description
400 Bad Request - Invalid parameters
401 Unauthorized - Invalid or missing API key
403 Forbidden - Insufficient permissions or token balance
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error

Error Response Example

{
  "statusCode": 401,
  "message": "Invalid API key",
  "error": "Unauthorized"
}

Token Consumption

Every 5 cities returned will consume 1 token. For example:

  • 50 cities = 10 tokens
  • 100 cities = 20 tokens
  • 500 cities = 100 tokens

Plan your requests accordingly to optimize token usage.