Este endpoint recupera todas las ciudades que pertenecen a un país específico. Es perfecto para construir selectores de país-ciudad, filtrar datos geográficos por país, o cuando necesitas mostrar todas las ciudades dentro de una nación particular.
Todas las solicitudes a la API requieren autenticación mediante una clave API. Incluye tu clave API como parámetro de consulta en cada solicitud:
?apikey=TU_CLAVE_API
Puedes obtener una clave API registrándote en CountryDataAPI.
https://api.countrydataapi.com/v1/cities/country
Retorna todas las ciudades de un país
Cada 5 ciudades retornadas consumirá 1 token
| Parámetro | Tipo | Descripción |
|---|---|---|
| apikey | requerido, token | Clave de autenticación de la cuenta |
| country | requerido, id o string | ID o nombre del país |
| limitToken | opcional, number | 1000 (predeterminado). Número máximo de tokens que quieres gastar en esta petición |
| lang | opcional, lang | en (predeterminado). Idioma esperado de la respuesta |
[
{
"id": "d54ba796-1136-4776-9776-537fd5a857c9",
"lang": "en",
"city_name": "Bala Morghab"
}
]
const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/country';
async function getCitiesByCountry(countryName) {
try {
const params = new URLSearchParams({
apikey: API_KEY,
country: countryName,
lang: 'en'
});
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(`Cities in ${countryName}:`, cities.length);
return cities;
} catch (error) {
console.error('Error fetching cities by country:', error);
throw error;
}
}
// Uso
getCitiesByCountry('United States');
getCitiesByCountry('Spain');
getCitiesByCountry('Germany');
import axios from 'axios';
const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/country';
async function getCitiesByCountry(countryName, limitToken = 1000) {
try {
const response = await axios.get(BASE_URL, {
params: {
apikey: API_KEY,
country: countryName,
lang: 'en',
limitToken: limitToken
}
});
console.log(`Cities in ${countryName}:`, response.data.length);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('API Error:', error.response?.data || error.message);
}
throw error;
}
}
// Uso
getCitiesByCountry('France');
getCitiesByCountry('Japan', 500);
import { useState, useEffect } from 'react';
const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/country';
function CitiesByCountry({ country }) {
const [cities, setCities] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchCities = async () => {
if (!country) {
setCities([]);
return;
}
try {
setLoading(true);
setError(null);
const params = new URLSearchParams({
apikey: API_KEY,
country: country,
lang: 'en'
});
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();
}, [country]);
if (loading) return <div>Cargando ciudades...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h2>Ciudades en {country}</h2>
<p>Total: {cities.length} ciudades</p>
<ul>
{cities.slice(0, 50).map((city) => (
<li key={city.id}>{city.city_name}</li>
))}
</ul>
{cities.length > 50 && (
<p>...y {cities.length - 50} ciudades más</p>
)}
</div>
);
}
// Selector de país con lista de ciudades
function CountryCityBrowser() {
const [selectedCountry, setSelectedCountry] = useState('');
const [cities, setCities] = useState([]);
const [loading, setLoading] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const countries = ['United States', 'Spain', 'Germany', 'France', 'Japan', 'Mexico', 'Canada'];
useEffect(() => {
if (!selectedCountry) {
setCities([]);
return;
}
const fetchCities = async () => {
setLoading(true);
const params = new URLSearchParams({
apikey: API_KEY,
country: selectedCountry,
lang: 'en'
});
try {
const response = await fetch(`${BASE_URL}?${params}`);
const data = await response.json();
setCities(data);
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
};
fetchCities();
}, [selectedCountry]);
const filteredCities = cities.filter(city =>
city.city_name.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<div>
<select
value={selectedCountry}
onChange={(e) => setSelectedCountry(e.target.value)}
>
<option value="">Seleccionar País</option>
{countries.map((c) => (
<option key={c} value={c}>{c}</option>
))}
</select>
{selectedCountry && (
<>
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Filtrar ciudades..."
/>
<p>Mostrando {filteredCities.length} de {cities.length} ciudades</p>
</>
)}
{loading ? (
<p>Cargando...</p>
) : (
<ul>
{filteredCities.slice(0, 100).map((city) => (
<li key={city.id}>{city.city_name}</li>
))}
</ul>
)}
</div>
);
}
export default CitiesByCountry;
<template>
<div>
<div v-if="loading">Cargando ciudades...</div>
<div v-else-if="error">Error: {{ error }}</div>
<div v-else>
<h2>Ciudades en {{ country }}</h2>
<p>Total: {{ cities.length }} ciudades</p>
<input
v-model="searchTerm"
type="text"
placeholder="Filtrar ciudades..."
/>
<ul>
<li v-for="city in filteredCities" :key="city.id">
{{ city.city_name }}
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
const props = defineProps({
country: {
type: String,
required: true
}
});
const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/cities/country';
const cities = ref([]);
const loading = ref(false);
const error = ref(null);
const searchTerm = ref('');
const filteredCities = computed(() => {
if (!searchTerm.value) {
return cities.value.slice(0, 100);
}
return cities.value
.filter(city =>
city.city_name.toLowerCase().includes(searchTerm.value.toLowerCase())
)
.slice(0, 100);
});
const fetchCities = async () => {
if (!props.country) {
cities.value = [];
return;
}
try {
loading.value = true;
error.value = null;
const params = new URLSearchParams({
apikey: API_KEY,
country: props.country,
lang: 'en'
});
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.country, fetchCities);
onMounted(fetchCities);
</script>
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-cities-by-country',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<div>
<div *ngIf="loading">Cargando ciudades...</div>
<div *ngIf="error">Error: {{ error }}</div>
<div *ngIf="!loading && !error">
<h2>Ciudades en {{ country }}</h2>
<p>Total: {{ cities.length }} ciudades</p>
<input
type="text"
[(ngModel)]="searchTerm"
placeholder="Filtrar ciudades..."
/>
<ul>
<li *ngFor="let city of filteredCities">{{ city.city_name }}</li>
</ul>
</div>
</div>
`
})
export class CitiesByCountryComponent implements OnInit, OnChanges {
@Input() country!: string;
private readonly API_KEY = 'TU_CLAVE_API';
private readonly BASE_URL = 'https://api.countrydataapi.com/v1/cities/country';
cities: City[] = [];
loading = false;
error: string | null = null;
searchTerm = '';
constructor(private http: HttpClient) {}
get filteredCities(): City[] {
if (!this.searchTerm) {
return this.cities.slice(0, 100);
}
return this.cities
.filter(city =>
city.city_name.toLowerCase().includes(this.searchTerm.toLowerCase())
)
.slice(0, 100);
}
ngOnInit(): void {
this.fetchCities();
}
ngOnChanges(): void {
this.fetchCities();
}
private fetchCities(): void {
if (!this.country) {
this.cities = [];
return;
}
this.loading = true;
this.error = null;
const params = new HttpParams()
.set('apikey', this.API_KEY)
.set('country', this.country)
.set('lang', 'en');
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
$apiKey = 'TU_CLAVE_API';
$baseUrl = 'https://api.countrydataapi.com/v1/cities/country';
function getCitiesByCountry($countryName, $apiKey, $limitToken = 1000) {
$baseUrl = 'https://api.countrydataapi.com/v1/cities/country';
$params = http_build_query([
'apikey' => $apiKey,
'country' => $countryName,
'lang' => 'en',
'limitToken' => $limitToken
]);
$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);
}
// Uso
try {
$countryName = 'United States';
$cities = getCitiesByCountry($countryName, $apiKey);
echo "Ciudades en $countryName:\n";
echo "Total: " . count($cities) . " ciudades\n\n";
// Mostrar las primeras 20 ciudades
foreach (array_slice($cities, 0, 20) as $city) {
echo "- " . $city['city_name'] . "\n";
}
if (count($cities) > 20) {
echo "... y " . (count($cities) - 20) . " ciudades más\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
// Calcular uso de tokens
function calculateTokenUsage($cityCount) {
return ceil($cityCount / 5);
}
$cities = getCitiesByCountry('Spain', $apiKey);
echo "\nCiudades en España: " . count($cities) . "\n";
echo "Tokens consumidos: " . calculateTokenUsage(count($cities)) . "\n";
// Buscar ciudades por nombre dentro de un país
function searchCitiesInCountry($countryName, $searchTerm, $apiKey) {
$cities = getCitiesByCountry($countryName, $apiKey);
return array_filter($cities, function($city) use ($searchTerm) {
return stripos($city['city_name'], $searchTerm) !== false;
});
}
$results = searchCitiesInCountry('Germany', 'Berlin', $apiKey);
print_r($results);
?>
import requests
API_KEY = 'TU_CLAVE_API'
BASE_URL = 'https://api.countrydataapi.com/v1/cities/country'
def get_cities_by_country(country_name, limit_token=1000):
"""Obtener todas las ciudades de un país específico."""
params = {
'apikey': API_KEY,
'country': country_name,
'lang': 'en',
'limitToken': limit_token
}
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):
"""Calcular tokens consumidos (5 ciudades = 1 token)."""
return (city_count + 4) // 5
def search_cities_in_country(country_name, search_term):
"""Buscar ciudades que contengan un término específico dentro de un país."""
cities = get_cities_by_country(country_name)
return [
city for city in cities
if search_term.lower() in city['city_name'].lower()
]
# Uso
if __name__ == '__main__':
country = 'United States'
cities = get_cities_by_country(country)
print(f"Ciudades en {country}:")
print(f"Total: {len(cities)} ciudades")
print(f"Tokens consumidos: {calculate_token_usage(len(cities))}")
print("\nPrimeras 10 ciudades:")
for city in cities[:10]:
print(f" - {city['city_name']}")
# Ejemplo de búsqueda
print("\nBuscando 'New' en ciudades de EE.UU.:")
results = search_cities_in_country('United States', 'New')
for city in results[:5]:
print(f" - {city['city_name']}")
# Versión asíncrona con aiohttp
import aiohttp
import asyncio
async def get_cities_by_country_async(country_name):
"""Obtener ciudades por país de forma asíncrona."""
params = {
'apikey': API_KEY,
'country': country_name,
'lang': 'en'
}
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}')
# Obtener ciudades de múltiples países concurrentemente
async def get_cities_for_multiple_countries(countries):
"""Obtener ciudades de múltiples países concurrentemente."""
tasks = [get_cities_by_country_async(country) for country in countries]
results = await asyncio.gather(*tasks, return_exceptions=True)
return dict(zip(countries, results))
# Uso
# countries = ['United States', 'Spain', 'Germany', 'France']
# results = asyncio.run(get_cities_for_multiple_countries(countries))
# for country, cities in results.items():
# if isinstance(cities, list):
# print(f"{country}: {len(cities)} ciudades")
# Obtener ciudades de Estados Unidos
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=United%20States&lang=en"
# Obtener ciudades de España
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=Spain&lang=en"
# Con salida JSON formateada
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=Germany&lang=en" | json_pp
# Limitar uso de tokens
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=France&limitToken=500"
# Obtener ciudades por ID de país
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=8dd25479-067a-43b0-ac4a-8e7faf2bcafb&lang=en"
# Guardar respuesta en archivo
curl -X GET "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=Japan&lang=en" -o japan_cities.json
# Obtener ciudades de múltiples países
for country in "United States" Spain Germany France; do
echo "País: $country"
curl -s "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=$country" | json_pp | head -20
echo ""
done
# Contar ciudades por país
for country in "United States" Spain Germany; do
count=$(curl -s "https://api.countrydataapi.com/v1/cities/country?apikey=TU_CLAVE_API&country=$country" | jq '. | length')
echo "$country: $count ciudades"
done
La API puede devolver las siguientes respuestas de error:
| Código de estado | Descripción |
|---|---|
| 400 | Bad Request - Parámetros inválidos o país faltante |
| 401 | Unauthorized - Clave API inválida o faltante |
| 403 | Forbidden - Permisos insuficientes o saldo de tokens |
| 404 | Not Found - País no encontrado |
| 429 | Too Many Requests - Límite de tasa excedido |
| 500 | Internal Server Error |
{
"statusCode": 404,
"message": "Country not found",
"error": "Not Found"
}
Cada 5 ciudades retornadas consumirá 1 token. Por ejemplo:
Usa el parámetro limitToken para controlar tu uso de tokens, especialmente al consultar países con muchas ciudades.
limitToken para gestionar los costos.