El endpoint /v1/zipcodes/country devuelve todos los códigos postales de un país específico, organizados por estado/provincia. Es perfecto para aplicaciones que necesitan cobertura completa de códigos postales para un país específico.
GET https://api.countrydataapi.com/v1/zipcodes/country
Incluye tu clave API como parámetro de consulta:
?apikey=tu-clave-api
Tu clave API es como una contraseña, mantenla segura. Obtén tu clave desde el panel de cuenta.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
apikey |
string | Sí | Tu clave de autenticación API |
country |
string | Sí | ID del país, código ISO (ej. "US", "DE"), o nombre |
lang |
string | No | Código de idioma para la respuesta (predeterminado: en) |
limitToken |
number | No | Máximo de tokens a gastar en esta petición (predeterminado: 1000) |
en - Inglés (predeterminado)es - Españolpt - Portuguésfr - Francésde - Alemánit - ItalianoCada código postal devuelto costará 1 token.
Nota: Países grandes como Estados Unidos o Alemania tienen miles de códigos postales. Usa
limitTokenpara controlar costos.
[
{
"id": "8dd25479-067a-43b0-ac4a-8e7faf2bcaf",
"country_name": "United States",
"state_names": [
{
"id": "8dd25479-067a-43b0-ac4a-8e7faf2bcad",
"name": "California",
"postal_code": [
"90001",
"90002",
"90003",
"90004"
]
},
{
"id": "9ae35480-178b-54c1-bd5b-9f8gbf3cdeh",
"name": "Texas",
"postal_code": [
"73301",
"73344",
"75001"
]
}
]
}
]
| Campo | Tipo | Descripción |
|---|---|---|
id |
string | Identificador único del país |
country_name |
string | Nombre del país en el idioma solicitado |
state_names |
array | Array de objetos de estado que contienen códigos postales |
state_names[].id |
string | Identificador único del estado |
state_names[].name |
string | Nombre del estado/provincia |
state_names[].postal_code |
array | Array de códigos postales para este estado |
{
"success": false,
"error": {
"code": "MISSING_PARAMETER",
"message": "Required parameter 'country' is missing"
}
}
Consulta la documentación de códigos de error para todos los códigos de error posibles.
# Buscar por nombre de país
curl -X GET "https://api.countrydataapi.com/v1/zipcodes/country?apikey=tu-clave-api&country=Germany&lang=en"
# Buscar por código ISO
curl -X GET "https://api.countrydataapi.com/v1/zipcodes/country?apikey=tu-clave-api&country=US&lang=en&limitToken=500"
# Buscar por ID de país
curl -X GET "https://api.countrydataapi.com/v1/zipcodes/country?apikey=tu-clave-api&country=66c7a6c9e4bda21f4ab10fd5&lang=en"
const API_KEY = 'tu-clave-api';
const BASE_URL = 'https://api.countrydataapi.com/v1';
async function getZipcodesByCountry(country, limitToken = 1000) {
try {
const params = new URLSearchParams({
apikey: API_KEY,
country: country,
lang: 'en',
limitToken: limitToken.toString()
});
const response = await fetch(`${BASE_URL}/zipcodes/country?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching zipcodes by country:', error);
throw error;
}
}
// Ejemplos de uso
// Por nombre de país
const germanyZipcodes = await getZipcodesByCountry('Germany');
console.log(germanyZipcodes);
// Por código ISO
const usZipcodes = await getZipcodesByCountry('US', 500);
console.log(usZipcodes);
// Por ID de país
const mexicoZipcodes = await getZipcodesByCountry('66c7a6c9e4bda21f4ab10fa8');
console.log(mexicoZipcodes);
import axios from 'axios';
const API_KEY = 'tu-clave-api';
const BASE_URL = 'https://api.countrydataapi.com/v1';
async function getZipcodesByCountry(country, limitToken = 1000) {
try {
const response = await axios.get(`${BASE_URL}/zipcodes/country`, {
params: {
apikey: API_KEY,
country: country,
lang: 'en',
limitToken: limitToken
}
});
return response.data;
} catch (error) {
if (error.response) {
console.error('API Error:', error.response.data);
throw new Error(error.response.data.error?.message || 'API Error');
} else {
console.error('Network Error:', error.message);
throw error;
}
}
}
// Uso
const data = await getZipcodesByCountry('France', 500);
console.log(`Encontrados códigos postales para ${data[0]?.state_names?.length || 0} estados`);
import { useState, useEffect } from 'react';
const API_KEY = 'tu-clave-api';
const BASE_URL = 'https://api.countrydataapi.com/v1';
function useCountryZipcodes(country, limitToken = 1000) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!country) {
setData(null);
return;
}
async function fetchZipcodes() {
try {
setLoading(true);
setError(null);
const params = new URLSearchParams({
apikey: API_KEY,
country: country,
lang: 'en',
limitToken: limitToken.toString()
});
const response = await fetch(`${BASE_URL}/zipcodes/country?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result[0] || null);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchZipcodes();
}, [country, limitToken]);
return { data, loading, error };
}
// Ejemplo de componente
function CountryZipcodeExplorer() {
const [selectedCountry, setSelectedCountry] = useState('');
const { data, loading, error } = useCountryZipcodes(selectedCountry, 500);
const countries = [
{ code: 'US', name: 'Estados Unidos' },
{ code: 'DE', name: 'Alemania' },
{ code: 'FR', name: 'Francia' },
{ code: 'ES', name: 'España' },
{ code: 'MX', name: 'México' }
];
const totalZipcodes = data?.state_names?.reduce(
(sum, state) => sum + state.postal_code.length,
0
) || 0;
return (
<div>
<h2>Explorar Códigos Postales por País</h2>
<select
value={selectedCountry}
onChange={(e) => setSelectedCountry(e.target.value)}
>
<option value="">Selecciona un país...</option>
{countries.map(c => (
<option key={c.code} value={c.code}>{c.name}</option>
))}
</select>
{loading && <p>Cargando códigos postales...</p>}
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
{data && (
<div>
<h3>{data.country_name}</h3>
<p>Total de estados: {data.state_names.length}</p>
<p>Total de códigos postales cargados: {totalZipcodes}</p>
<div style={{ maxHeight: '400px', overflow: 'auto' }}>
{data.state_names.map(state => (
<details key={state.id}>
<summary>
{state.name} ({state.postal_code.length} códigos)
</summary>
<p style={{ fontSize: '0.9em', color: '#666' }}>
{state.postal_code.slice(0, 20).join(', ')}
{state.postal_code.length > 20 && '...'}
</p>
</details>
))}
</div>
</div>
)}
</div>
);
}
export default CountryZipcodeExplorer;
<script setup>
import { ref, watch, computed } from 'vue';
const API_KEY = 'tu-clave-api';
const BASE_URL = 'https://api.countrydataapi.com/v1';
const selectedCountry = ref('');
const countryData = ref(null);
const loading = ref(false);
const error = ref(null);
const countries = [
{ code: 'US', name: 'Estados Unidos' },
{ code: 'DE', name: 'Alemania' },
{ code: 'FR', name: 'Francia' },
{ code: 'ES', name: 'España' },
{ code: 'MX', name: 'México' }
];
const totalZipcodes = computed(() => {
if (!countryData.value?.state_names) return 0;
return countryData.value.state_names.reduce(
(sum, state) => sum + state.postal_code.length,
0
);
});
watch(selectedCountry, async (newCountry) => {
if (!newCountry) {
countryData.value = null;
return;
}
try {
loading.value = true;
error.value = null;
const params = new URLSearchParams({
apikey: API_KEY,
country: newCountry,
lang: 'en',
limitToken: '500'
});
const response = await fetch(`${BASE_URL}/zipcodes/country?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
countryData.value = data[0] || null;
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
});
</script>
<template>
<div>
<h2>Explorar Códigos Postales por País</h2>
<select v-model="selectedCountry">
<option value="">Selecciona un país...</option>
<option v-for="c in countries" :key="c.code" :value="c.code">
{{ c.name }}
</option>
</select>
<div v-if="loading">Cargando códigos postales...</div>
<div v-else-if="error" style="color: red;">Error: {{ error }}</div>
<div v-else-if="countryData">
<h3>{{ countryData.country_name }}</h3>
<p>Total de estados: {{ countryData.state_names.length }}</p>
<p>Total de códigos postales cargados: {{ totalZipcodes }}</p>
<div style="max-height: 400px; overflow: auto;">
<details v-for="state in countryData.state_names" :key="state.id">
<summary>
{{ state.name }} ({{ state.postal_code.length }} códigos)
</summary>
<p style="font-size: 0.9em; color: #666;">
{{ state.postal_code.slice(0, 20).join(', ') }}
<span v-if="state.postal_code.length > 20">...</span>
</p>
</details>
</div>
</div>
</div>
</template>
// zipcode.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
interface State {
id: string;
name: string;
postal_code: string[];
}
interface CountryZipcode {
id: string;
country_name: string;
state_names: State[];
}
@Injectable({
providedIn: 'root'
})
export class ZipcodeService {
private readonly API_KEY = 'tu-clave-api';
private readonly BASE_URL = 'https://api.countrydataapi.com/v1';
constructor(private http: HttpClient) {}
getZipcodesByCountry(
country: string,
limitToken: number = 1000
): Observable<CountryZipcode[]> {
const params = new HttpParams()
.set('apikey', this.API_KEY)
.set('country', country)
.set('lang', 'en')
.set('limitToken', limitToken.toString());
return this.http.get<CountryZipcode[]>(
`${this.BASE_URL}/zipcodes/country`,
{ params }
);
}
}
// country-zipcode-explorer.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ZipcodeService } from './zipcode.service';
interface Country {
code: string;
name: string;
}
@Component({
selector: 'app-country-zipcode-explorer',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<div>
<h2>Explorar Códigos Postales por País</h2>
<select [(ngModel)]="selectedCountry" (ngModelChange)="onCountryChange()">
<option value="">Selecciona un país...</option>
<option *ngFor="let c of countries" [value]="c.code">
{{ c.name }}
</option>
</select>
<div *ngIf="loading">Cargando códigos postales...</div>
<div *ngIf="error" style="color: red;">Error: {{ error }}</div>
<div *ngIf="countryData && !loading">
<h3>{{ countryData.country_name }}</h3>
<p>Total de estados: {{ countryData.state_names.length }}</p>
<p>Total de códigos postales cargados: {{ getTotalZipcodes() }}</p>
<div style="max-height: 400px; overflow: auto;">
<details *ngFor="let state of countryData.state_names">
<summary>
{{ state.name }} ({{ state.postal_code.length }} códigos)
</summary>
<p style="font-size: 0.9em; color: #666;">
{{ state.postal_code.slice(0, 20).join(', ') }}
<span *ngIf="state.postal_code.length > 20">...</span>
</p>
</details>
</div>
</div>
</div>
`
})
export class CountryZipcodeExplorerComponent {
countries: Country[] = [
{ code: 'US', name: 'Estados Unidos' },
{ code: 'DE', name: 'Alemania' },
{ code: 'FR', name: 'Francia' },
{ code: 'ES', name: 'España' },
{ code: 'MX', name: 'México' }
];
selectedCountry = '';
countryData: any = null;
loading = false;
error: string | null = null;
constructor(private zipcodeService: ZipcodeService) {}
onCountryChange() {
if (!this.selectedCountry) {
this.countryData = null;
return;
}
this.loading = true;
this.error = null;
this.zipcodeService.getZipcodesByCountry(this.selectedCountry, 500).subscribe({
next: (data) => {
this.countryData = data[0] || null;
this.loading = false;
},
error: (err) => {
this.error = err.message;
this.loading = false;
}
});
}
getTotalZipcodes(): number {
if (!this.countryData?.state_names) return 0;
return this.countryData.state_names.reduce(
(sum: number, state: any) => sum + state.postal_code.length,
0
);
}
}
<?php
$apiKey = 'tu-clave-api';
$country = 'Germany'; // Puede ser nombre de país, código ISO o ID
$limitToken = 500;
$url = "https://api.countrydataapi.com/v1/zipcodes/country?" . http_build_query([
'apikey' => $apiKey,
'country' => $country,
'lang' => 'en',
'limitToken' => $limitToken
]);
// Usando cURL
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Accept: application/json'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
die("cURL Error: {$curlError}");
}
if ($httpCode === 200) {
$data = json_decode($response, true);
if (!empty($data)) {
$countryData = $data[0];
echo "País: " . $countryData['country_name'] . "\n";
echo "Total de Estados: " . count($countryData['state_names']) . "\n";
$totalZipcodes = 0;
foreach ($countryData['state_names'] as $state) {
$totalZipcodes += count($state['postal_code']);
echo "\n Estado: " . $state['name'] . "\n";
echo " Códigos Postales: " . count($state['postal_code']) . "\n";
echo " Muestra: " . implode(', ', array_slice($state['postal_code'], 0, 5)) . "...\n";
}
echo "\nTotal de Códigos Postales: {$totalZipcodes}\n";
} else {
echo "No se encontraron códigos postales para el país: {$country}\n";
}
} else {
echo "Error: HTTP {$httpCode}\n";
$error = json_decode($response, true);
echo "Mensaje: " . ($error['error']['message'] ?? 'Error desconocido') . "\n";
}
// Función reutilizable
function getZipcodesByCountry($apiKey, $country, $lang = 'en', $limitToken = 1000) {
$url = "https://api.countrydataapi.com/v1/zipcodes/country?" . http_build_query([
'apikey' => $apiKey,
'country' => $country,
'lang' => $lang,
'limitToken' => $limitToken
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API Error: HTTP {$httpCode}");
}
return json_decode($response, true);
}
// Uso
try {
// Por código ISO
$usData = getZipcodesByCountry($apiKey, 'US', 'en', 100);
print_r($usData);
// Por nombre de país en español
$spainData = getZipcodesByCountry($apiKey, 'Spain', 'es', 200);
print_r($spainData);
} catch (Exception $e) {
echo $e->getMessage();
}
?>
import requests
from typing import List, Dict, Any, Optional
API_KEY = 'tu-clave-api'
BASE_URL = 'https://api.countrydataapi.com/v1'
def get_zipcodes_by_country(
country: str,
lang: str = 'en',
limit_token: int = 1000
) -> List[Dict[str, Any]]:
"""
Obtener códigos postales de un país específico.
Args:
country: Nombre del país, código ISO o ID
lang: Código de idioma para la respuesta
limit_token: Máximo de tokens a gastar en esta petición
Returns:
Lista conteniendo datos del país con estados y códigos postales
"""
try:
response = requests.get(
f'{BASE_URL}/zipcodes/country',
params={
'apikey': API_KEY,
'country': country,
'lang': lang,
'limitToken': limit_token
},
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f'HTTP Error: {e.response.status_code}')
print(f'Response: {e.response.text}')
raise
except requests.exceptions.RequestException as e:
print(f'Request Error: {e}')
raise
def count_total_zipcodes(country_data: Dict[str, Any]) -> int:
"""Contar total de códigos postales en datos de país"""
return sum(
len(state['postal_code'])
for state in country_data.get('state_names', [])
)
# Ejemplos de uso
if __name__ == '__main__':
# Buscar por nombre de país
germany_data = get_zipcodes_by_country('Germany', limit_token=500)
if germany_data:
country = germany_data[0]
print(f"País: {country['country_name']}")
print(f"Total de estados: {len(country['state_names'])}")
print(f"Total de códigos postales: {count_total_zipcodes(country)}")
for state in country['state_names'][:3]:
print(f"\n Estado: {state['name']}")
print(f" Códigos: {', '.join(state['postal_code'][:5])}...")
# Buscar por código ISO
print("\n--- Francia (por código ISO) ---")
france_data = get_zipcodes_by_country('FR', limit_token=300)
if france_data:
print(f"Total de códigos postales: {count_total_zipcodes(france_data[0])}")
# Buscar en español
print("\n--- México (en español) ---")
mexico_data = get_zipcodes_by_country('Mexico', lang='es', limit_token=200)
if mexico_data:
for state in mexico_data[0]['state_names'][:3]:
print(f" Estado: {state['name']}")
# Versión asíncrona usando aiohttp
import aiohttp
import asyncio
async def get_zipcodes_by_country_async(
country: str,
lang: str = 'en',
limit_token: int = 1000
) -> List[Dict[str, Any]]:
"""Versión asíncrona usando aiohttp"""
async with aiohttp.ClientSession() as session:
async with session.get(
f'{BASE_URL}/zipcodes/country',
params={
'apikey': API_KEY,
'country': country,
'lang': lang,
'limitToken': limit_token
}
) as response:
if response.status != 200:
text = await response.text()
raise Exception(f'API Error: {response.status} - {text}')
return await response.json()
# Obtener múltiples países en paralelo
async def get_multiple_countries(countries: List[str]) -> Dict[str, Any]:
"""Obtener códigos postales de múltiples países en paralelo"""
tasks = [
get_zipcodes_by_country_async(country, limit_token=100)
for country in countries
]
results = await asyncio.gather(*tasks, return_exceptions=True)
return dict(zip(countries, results))
# Ejecutar async
# data = asyncio.run(get_multiple_countries(['US', 'DE', 'FR']))
Siempre implementa un manejo de errores adecuado:
async function getZipcodesWithErrorHandling(country) {
try {
const response = await fetch(
`https://api.countrydataapi.com/v1/zipcodes/country?apikey=tu-clave-api&country=${encodeURIComponent(country)}`
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
switch (response.status) {
case 400:
throw new Error(errorData.error?.message || 'Parámetros de petición inválidos');
case 401:
throw new Error('Clave API inválida');
case 402:
throw new Error('Tokens insuficientes. Por favor actualiza tu plan.');
case 404:
throw new Error(`País "${country}" no encontrado`);
case 429:
throw new Error('Límite de tasa excedido. Por favor intenta más tarde.');
default:
throw new Error(`HTTP error! status: ${response.status}`);
}
}
const data = await response.json();
if (!Array.isArray(data) || data.length === 0) {
console.warn(`No se encontraron códigos postales para el país: ${country}`);
return null;
}
return data[0];
} catch (error) {
console.error('Error al obtener códigos postales del país:', error.message);
throw error;
}
}
| Código de Error | Descripción | Solución |
|---|---|---|
INVALID_API_KEY |
La clave API es inválida | Verifica tu clave API en el panel de cuenta |
MISSING_PARAMETER |
Falta el parámetro country |
Incluye nombre del país, código ISO o ID |
COUNTRY_NOT_FOUND |
El país no existe | Verifica el nombre del país o usa un código ISO válido |
QUOTA_EXCEEDED |
Límite diario de tokens alcanzado | Actualiza tu plan o espera el reinicio |
async function populateAddressForm(countryCode) {
const data = await getZipcodesByCountry(countryCode);
if (!data) return;
const stateSelect = document.getElementById('state');
stateSelect.innerHTML = '<option value="">Selecciona estado...</option>';
data.state_names.forEach(state => {
const option = new Option(state.name, state.id);
option.dataset.zipcodes = JSON.stringify(state.postal_code);
stateSelect.add(option);
});
}
async function validatePostalCode(countryCode, postalCode) {
const data = await getZipcodesByCountry(countryCode);
if (!data) {
return { valid: false, message: 'País no encontrado' };
}
for (const state of data.state_names) {
if (state.postal_code.includes(postalCode)) {
return {
valid: true,
state: state.name,
message: `Código postal válido para ${state.name}`
};
}
}
return { valid: false, message: 'Código postal inválido para este país' };
}
// Uso
const result = await validatePostalCode('DE', '10115');
console.log(result); // { valid: true, state: 'Berlin', message: '...' }
limitToken: Controla el tamaño de datos para países con muchos códigos postalesConsulta nuestra página de precios para más detalles.