API Documentation - Endpoints & Examples

All Data from a City

Overview

This endpoint retrieves complete data for a specific city by its ID or name. It provides detailed information about a particular city, including all available fields for that location.

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/

Returns all data from a city

Each city returned will consume 1 token

Query Params


Parameter Type Description
apikey required, token Account authentication key
city required, id or string City ID or name
lang optional, lang en (default). Expected language of the response

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/';

async function getCityData(cityNameOrId) {
  try {
    const params = new URLSearchParams({
      apikey: API_KEY,
      city: cityNameOrId,
      lang: 'en'
    });

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

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

    const cityData = await response.json();
    console.log('City Data:', cityData);
    return cityData;
  } catch (error) {
    console.error('Error fetching city data:', error);
    throw error;
  }
}

// Usage - by city name
getCityData('Denver');
getCityData('New York');

// Usage - by city ID
getCityData('d54ba796-1136-4776-9776-537fd5a857c9');

JavaScript (Axios)

import axios from 'axios';

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

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

    console.log('City Data:', response.data);
    return response.data;
  } catch (error) {
    if (axios.isAxiosError(error)) {
      console.error('API Error:', error.response?.data || error.message);
    }
    throw error;
  }
}

// Usage
getCityData('Los Angeles');

React

import { useState, useEffect } from 'react';

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

function CityDetails({ cityName }) {
  const [cityData, setCityData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchCityData = async () => {
      if (!cityName) {
        setCityData(null);
        return;
      }

      try {
        setLoading(true);
        setError(null);

        const params = new URLSearchParams({
          apikey: API_KEY,
          city: cityName,
          lang: 'en'
        });

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

        if (!response.ok) {
          throw new Error('City not found');
        }

        const data = await response.json();
        setCityData(data[0] || null);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchCityData();
  }, [cityName]);

  if (loading) return <div>Loading city data...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!cityData) return <div>Enter a city name to search</div>;

  return (
    <div>
      <h2>{cityData.city_name}</h2>
      <p>ID: {cityData.id}</p>
      <p>Language: {cityData.lang}</p>
    </div>
  );
}

// City search with autocomplete
function CitySearch() {
  const [searchTerm, setSearchTerm] = useState('');
  const [selectedCity, setSelectedCity] = useState('');

  const handleSearch = (e) => {
    e.preventDefault();
    setSelectedCity(searchTerm);
  };

  return (
    <div>
      <form onSubmit={handleSearch}>
        <input
          type="text"
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
          placeholder="Enter city name..."
        />
        <button type="submit">Search</button>
      </form>

      {selectedCity && <CityDetails cityName={selectedCity} />}
    </div>
  );
}

export default CitySearch;

Vue 3

<template>
  <div>
    <div v-if="loading">Loading city data...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else-if="cityData">
      <h2>{{ cityData.city_name }}</h2>
      <p>ID: {{ cityData.id }}</p>
      <p>Language: {{ cityData.lang }}</p>
    </div>
    <div v-else>Enter a city name to search</div>
  </div>
</template>

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

const props = defineProps({
  cityName: {
    type: String,
    default: ''
  }
});

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

const cityData = ref(null);
const loading = ref(false);
const error = ref(null);

const fetchCityData = async () => {
  if (!props.cityName) {
    cityData.value = null;
    return;
  }

  try {
    loading.value = true;
    error.value = null;

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

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

    if (!response.ok) {
      throw new Error('City not found');
    }

    const data = await response.json();
    cityData.value = data[0] || null;
  } catch (err) {
    error.value = err.message;
  } finally {
    loading.value = false;
  }
};

watch(() => props.cityName, fetchCityData);
onMounted(() => {
  if (props.cityName) {
    fetchCityData();
  }
});
</script>

Angular

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

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

@Component({
  selector: 'app-city-details',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div>
      <div *ngIf="loading">Loading city data...</div>
      <div *ngIf="error">Error: {{ error }}</div>
      <div *ngIf="!loading && !error && cityData">
        <h2>{{ cityData.city_name }}</h2>
        <p>ID: {{ cityData.id }}</p>
        <p>Language: {{ cityData.lang }}</p>
      </div>
      <div *ngIf="!loading && !error && !cityData">
        Enter a city name to search
      </div>
    </div>
  `
})
export class CityDetailsComponent implements OnInit, OnChanges {
  @Input() cityName = '';

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

  cityData: City | null = null;
  loading = false;
  error: string | null = null;

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    if (this.cityName) {
      this.fetchCityData();
    }
  }

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

  private fetchCityData(): void {
    if (!this.cityName) {
      this.cityData = null;
      return;
    }

    this.loading = true;
    this.error = null;

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

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

// City search component
@Component({
  selector: 'app-city-search',
  standalone: true,
  imports: [CommonModule, FormsModule, CityDetailsComponent],
  template: `
    <div>
      <form (ngSubmit)="search()">
        <input
          type="text"
          [(ngModel)]="searchTerm"
          name="city"
          placeholder="Enter city name..."
        />
        <button type="submit">Search</button>
      </form>

      <app-city-details
        *ngIf="selectedCity"
        [cityName]="selectedCity"
      ></app-city-details>
    </div>
  `
})
export class CitySearchComponent {
  searchTerm = '';
  selectedCity = '';

  search(): void {
    this.selectedCity = this.searchTerm;
  }
}

PHP

<?php

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

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

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

    $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 - by city name
try {
    $cityName = 'Denver';
    $cities = getCityData($cityName, $apiKey);

    if (!empty($cities)) {
        $city = $cities[0];
        echo "City: " . $city['city_name'] . "\n";
        echo "ID: " . $city['id'] . "\n";
        echo "Language: " . $city['lang'] . "\n";
    } else {
        echo "City not found\n";
    }
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

// Usage - by city ID
try {
    $cityId = 'd54ba796-1136-4776-9776-537fd5a857c9';
    $cities = getCityData($cityId, $apiKey);

    if (!empty($cities)) {
        $city = $cities[0];
        echo "Found city by ID: " . $city['city_name'] . "\n";
    }
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>

Python

import requests

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

def get_city_data(city_name_or_id):
    """Fetch detailed data for a specific city."""
    params = {
        'apikey': API_KEY,
        'city': city_name_or_id,
        'lang': 'en'
    }

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

        city_data = response.json()
        return city_data[0] if city_data else None
    except requests.exceptions.RequestException as e:
        print(f'Error fetching city data: {e}')
        raise

# Usage
if __name__ == '__main__':
    # Search by city name
    city = get_city_data('Denver')

    if city:
        print(f"City: {city['city_name']}")
        print(f"ID: {city['id']}")
        print(f"Language: {city['lang']}")
    else:
        print("City not found")

    # Search by city ID
    city_by_id = get_city_data('d54ba796-1136-4776-9776-537fd5a857c9')
    if city_by_id:
        print(f"\nFound by ID: {city_by_id['city_name']}")


# Async version with aiohttp
import aiohttp
import asyncio

async def get_city_data_async(city_name_or_id):
    """Fetch city data asynchronously."""
    params = {
        'apikey': API_KEY,
        'city': city_name_or_id,
        'lang': 'en'
    }

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

# Fetch multiple cities concurrently
async def get_multiple_cities(city_names):
    """Fetch multiple cities concurrently."""
    tasks = [get_city_data_async(name) for name in city_names]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return dict(zip(city_names, results))

# Usage
# cities = ['Denver', 'Miami', 'Seattle', 'Boston']
# results = asyncio.run(get_multiple_cities(cities))
# for name, data in results.items():
#     if data:
#         print(f"{name}: {data['id']}")

cURL

# Get city data by name
curl -X GET "https://api.countrydataapi.com/v1/cities/?apikey=YOUR_API_KEY&city=Denver&lang=en"

# Get city data by ID
curl -X GET "https://api.countrydataapi.com/v1/cities/?apikey=YOUR_API_KEY&city=d54ba796-1136-4776-9776-537fd5a857c9&lang=en"

# With pretty-printed JSON output
curl -X GET "https://api.countrydataapi.com/v1/cities/?apikey=YOUR_API_KEY&city=New%20York&lang=en" | json_pp

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

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

# Search multiple cities
for city in Denver Miami Seattle Boston; do
  echo "City: $city"
  curl -s "https://api.countrydataapi.com/v1/cities/?apikey=YOUR_API_KEY&city=$city" | json_pp
  echo ""
done

Error Handling

The API may return the following error responses:

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

Error Response Example

{
  "statusCode": 404,
  "message": "City not found",
  "error": "Not Found"
}

Important Notes

  • City Name Variations: Some cities have multiple names or spellings. Try different variations if your initial search fails.
  • Duplicate Names: Many cities share the same name (e.g., "Springfield"). The API may return multiple results.
  • Using City ID: For precise lookups, use the city's unique ID instead of its name.