Documentación de la API - Endpoints y Ejemplos

Buscar pais por codigo postal

Descripcion general

El endpoint de busqueda de pais por codigo postal te permite encontrar el pais que contiene un codigo postal especifico. Esto es esencial para validacion de direcciones, envios de comercio electronico y servicios basados en ubicacion.

Country Data API proporciona informacion detallada sobre +200 paises diferentes

Autenticacion

Todas las solicitudes de API requieren autenticacion mediante una clave API pasada como parametro de consulta.

https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=10001

Peticion

HTTP GET

https://api.countrydataapi.com/v1/countries/zipCode

Retorna el pais que contiene el codigo postal

Hay 4 tipos de operaciones:

  • BASIC: Retorna los campos id, lang, country_name, country_short_iso, country_phone_code, country_cca2, country_ccn3, country_cca3, country_cioc.

  • NORMAL: Retorna los campos anteriores y agrega country_independent, country_status, country_unMember, country_flag, country_map_googleMaps, country_map_openStreetMaps, country_fifa, country_flag_png, country_flag_svg, country_flag_alt, country_coatOfArms_png, country_coatOfArms_svg, country_startofWeek, country_continent_code, country_current_currency, country_GDP, country_location, country_land, country_terrain, country_climate, country_natural_hazards, country_note, country_history, country_GDP_per_capita_PPP, country_life_expectancy, country_median_age, country_birth_rate, country_death_rate, country_sex_ratio, country_literacy, country_roadways, country_airports, country_railways, country_waterways, country_heliports, country_airports_paved, country_wikipedia_url.

  • ADVANCED: Retorna los campos anteriores y agrega country_car_info, _country_idd_info.

  • ALL: Retorna los campos anteriores y agrega country_tld, country_capital, country_altSpellings, country_latLng, country_borders, country_timezones, country_continents, country_currencies, country_languages, country_translations, country_capital_info, country_demonyms, country_name.nativeName.

Cada pais retornado con el metodo BASIC costara 1 tokens.

Cada pais retornado con el metodo NORMAL costara 2 tokens.

Cada pais retornado con el metodo ADVANCED costara 3 tokens.

Cada pais retornado con el metodo ALL costara 4 tokens.

Parametros de consulta


Parametro Tipo Descripcion
apikey requerido, token Clave de autenticacion de la cuenta
postalCode requerido, string Codigo postal que deseas buscar
limitToken opcional, number 1000 (por defecto). Numero maximo de paises a retornar
lang opcional, lang en (por defecto). Idioma esperado de la respuesta
fields opcional, string id,lang,country_name (por defecto). Campos esperados en la respuesta

Respuesta

Ejemplo de respuesta

[
  {
    "id": "33be30c5-80fc-429d-bf10-bd11f2e3e84c",
    "lang": "en",
    "country_name": "United States",
    "country_short_iso": "US",
    "country_phone_code": "1",
    "country_cca2": "US",
    "country_ccn3": "840",
    "country_cca3": "USA",
    "country_cioc": "USA",
    "country_independent": true,
    "country_status": "officially-assigned",
    "country_unMember": true,
    "country_capital": ["Washington, D.C."],
    "country_region": "Americas",
    "country_subregion": "Northern America",
    "country_flag": "flag-emoji",
    "country_flag_png": "https://flagcdn.com/w320/us.png",
    "country_flag_svg": "https://flagcdn.com/us.svg"
  }
]

Ejemplos de codigo

cURL

# Search country by postal code (US ZIP)
curl -X GET "https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=10001"

# Search by UK postal code
curl -X GET "https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=SW1A"

# Search by German postal code
curl -X GET "https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=10115"

# With specific fields (NORMAL level)
curl -X GET "https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=75001&fields=id,lang,country_name,country_flag_png,country_capital"

# Search with different language response
curl -X GET "https://api.countrydataapi.com/v1/countries/zipCode?apikey=YOUR_API_KEY&postalCode=28001&lang=es"

JavaScript (Fetch)

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

// Search country by postal code
async function searchCountryByPostalCode(postalCode, options = {}) {
  const params = new URLSearchParams({
    apikey: API_KEY,
    postalCode: postalCode,
    ...options
  });

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

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

    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error searching country by postal code:', error);
    throw error;
  }
}

// Usage examples
// US ZIP code
searchCountryByPostalCode('10001')
  .then(countries => {
    console.log('Country for ZIP 10001:', countries[0]?.country_name);
  });

// UK postal code
searchCountryByPostalCode('SW1A', {
  fields: 'id,lang,country_name,country_flag_png,country_capital'
})
  .then(countries => {
    console.log('UK postal code result:', countries);
  });

// French postal code with French response
searchCountryByPostalCode('75001', { lang: 'fr' })
  .then(countries => {
    console.log('French result:', countries);
  });

JavaScript (Axios)

import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://api.countrydataapi.com/v1/countries',
  params: {
    apikey: 'YOUR_API_KEY'
  }
});

// Search country by postal code
async function searchCountryByPostalCode(postalCode, options = {}) {
  try {
    const response = await apiClient.get('/zipCode', {
      params: {
        postalCode: postalCode,
        ...options
      }
    });
    return response.data;
  } catch (error) {
    if (error.response) {
      console.error('API Error:', error.response.status, error.response.data);
    } else {
      console.error('Network Error:', error.message);
    }
    throw error;
  }
}

// Address validation service
const addressValidationService = {
  async validatePostalCode(postalCode) {
    const countries = await searchCountryByPostalCode(postalCode, {
      fields: 'id,lang,country_name,country_cca2,country_flag_png'
    });

    return {
      isValid: countries.length > 0,
      country: countries[0] || null
    };
  },

  async getCountryFromPostalCode(postalCode) {
    return searchCountryByPostalCode(postalCode, {
      fields: 'id,lang,country_name,country_flag_png,country_capital,country_phone_code'
    });
  }
};

// Usage
addressValidationService.validatePostalCode('90210')
  .then(result => {
    if (result.isValid) {
      console.log(`Valid postal code for ${result.country.country_name}`);
    }
  });

React

import { useState, useCallback } from 'react';

const API_KEY = 'YOUR_API_KEY';

function usePostalCodeSearch() {
  const [country, setCountry] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [isValid, setIsValid] = useState(null);

  const searchByPostalCode = useCallback(async (postalCode) => {
    if (!postalCode.trim()) {
      setCountry(null);
      setIsValid(null);
      return;
    }

    setLoading(true);
    setError(null);

    const params = new URLSearchParams({
      apikey: API_KEY,
      postalCode: postalCode,
      fields: 'id,lang,country_name,country_flag_png,country_capital,country_phone_code,country_cca2'
    });

    try {
      const response = await fetch(
        `https://api.countrydataapi.com/v1/countries/zipCode?${params}`
      );

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

      const data = await response.json();

      if (data.length > 0) {
        setCountry(data[0]);
        setIsValid(true);
      } else {
        setCountry(null);
        setIsValid(false);
      }
    } catch (err) {
      setError(err.message);
      setCountry(null);
      setIsValid(false);
    } finally {
      setLoading(false);
    }
  }, []);

  return { country, loading, error, isValid, searchByPostalCode };
}

function PostalCodeValidator() {
  const [postalCode, setPostalCode] = useState('');
  const { country, loading, error, isValid, searchByPostalCode } = usePostalCodeSearch();

  const handleSubmit = (e) => {
    e.preventDefault();
    searchByPostalCode(postalCode);
  };

  return (
    <div className="postal-code-validator">
      <h2>Postal Code Validator</h2>

      <form onSubmit={handleSubmit} className="search-form">
        <input
          type="text"
          value={postalCode}
          onChange={(e) => setPostalCode(e.target.value)}
          placeholder="Enter postal code (e.g., 10001, SW1A, 75001)"
        />
        <button type="submit" disabled={loading || !postalCode.trim()}>
          {loading ? 'Validating...' : 'Validate'}
        </button>
      </form>

      {error && <div className="error-message">Error: {error}</div>}

      {isValid === true && country && (
        <div className="result valid">
          <div className="status-badge success">Valid Postal Code</div>
          <div className="country-card">
            <img src={country.country_flag_png} alt={`${country.country_name} flag`} />
            <div className="country-details">
              <h3>{country.country_name}</h3>
              <p><strong>Code:</strong> {country.country_cca2}</p>
              <p><strong>Capital:</strong> {country.country_capital?.join(', ')}</p>
            </div>
          </div>
        </div>
      )}

      {isValid === false && !loading && (
        <div className="result invalid">
          <div className="status-badge error">Invalid Postal Code</div>
          <p>No country found for postal code "{postalCode}"</p>
        </div>
      )}
    </div>
  );
}

export default PostalCodeValidator;

Vue 3

<template>
  <div class="postal-code-validator">
    <h2>Postal Code Validator</h2>

    <form @submit.prevent="handleSubmit" class="search-form">
      <input
        v-model="postalCode"
        type="text"
        placeholder="Enter postal code (e.g., 10001, SW1A, 75001)"
      />
      <button type="submit" :disabled="loading || !postalCode.trim()">
        {{ loading ? 'Validating...' : 'Validate' }}
      </button>
    </form>

    <div v-if="error" class="error-message">{{ error }}</div>

    <div v-if="isValid === true && country" class="result valid">
      <div class="status-badge success">Valid Postal Code</div>
      <div class="country-card">
        <img :src="country.country_flag_png" :alt="`${country.country_name} flag`" />
        <div class="country-details">
          <h3>{{ country.country_name }}</h3>
          <p><strong>Code:</strong> {{ country.country_cca2 }}</p>
          <p><strong>Capital:</strong> {{ formatCapital(country.country_capital) }}</p>
        </div>
      </div>
    </div>

    <div v-if="isValid === false && !loading" class="result invalid">
      <div class="status-badge error">Invalid Postal Code</div>
      <p>No country found for postal code "{{ searchedCode }}"</p>
    </div>
  </div>
</template>

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

const API_KEY = 'YOUR_API_KEY';

const postalCode = ref('');
const searchedCode = ref('');
const country = ref(null);
const loading = ref(false);
const error = ref(null);
const isValid = ref(null);

const formatCapital = (capital) => capital?.join(', ') || 'N/A';

const handleSubmit = async () => {
  if (!postalCode.value.trim()) return;

  loading.value = true;
  error.value = null;
  searchedCode.value = postalCode.value;

  const params = new URLSearchParams({
    apikey: API_KEY,
    postalCode: postalCode.value,
    fields: 'id,lang,country_name,country_flag_png,country_capital,country_phone_code,country_cca2'
  });

  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/countries/zipCode?${params}`
    );

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

    const data = await response.json();

    if (data.length > 0) {
      country.value = data[0];
      isValid.value = true;
    } else {
      country.value = null;
      isValid.value = false;
    }
  } catch (err) {
    error.value = err.message;
    country.value = null;
    isValid.value = false;
  } finally {
    loading.value = false;
  }
};
</script>

Angular

import { Component, inject, signal } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

interface Country {
  id: string;
  country_name: string;
  country_flag_png?: string;
  country_capital?: string[];
  country_phone_code?: string;
  country_cca2?: string;
}

@Component({
  selector: 'app-postal-code-validator',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <div class="postal-code-validator">
      <h2>Postal Code Validator</h2>

      <form (ngSubmit)="validatePostalCode()" class="search-form">
        <input
          type="text"
          [(ngModel)]="postalCode"
          name="postalCode"
          placeholder="Enter postal code (e.g., 10001, SW1A, 75001)"
        />
        <button type="submit" [disabled]="loading() || !postalCode.trim()">
          {{ loading() ? 'Validating...' : 'Validate' }}
        </button>
      </form>

      <div *ngIf="error()" class="error-message">{{ error() }}</div>

      <div *ngIf="isValid() === true && country()" class="result valid">
        <div class="status-badge success">Valid Postal Code</div>
        <div class="country-card">
          <img [src]="country()!.country_flag_png" [alt]="country()!.country_name + ' flag'" />
          <div class="country-details">
            <h3>{{ country()!.country_name }}</h3>
            <p><strong>Code:</strong> {{ country()!.country_cca2 }}</p>
            <p><strong>Capital:</strong> {{ formatCapital(country()!.country_capital) }}</p>
          </div>
        </div>
      </div>

      <div *ngIf="isValid() === false && !loading()" class="result invalid">
        <div class="status-badge error">Invalid Postal Code</div>
        <p>No country found for postal code "{{ searchedCode() }}"</p>
      </div>
    </div>
  `
})
export class PostalCodeValidatorComponent {
  private http = inject(HttpClient);
  private readonly API_KEY = 'YOUR_API_KEY';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1/countries';

  postalCode = '';
  country = signal<Country | null>(null);
  loading = signal(false);
  error = signal<string | null>(null);
  isValid = signal<boolean | null>(null);
  searchedCode = signal('');

  formatCapital(capital?: string[]): string {
    return capital?.join(', ') || 'N/A';
  }

  validatePostalCode(): void {
    if (!this.postalCode.trim()) return;

    this.loading.set(true);
    this.error.set(null);
    this.searchedCode.set(this.postalCode);

    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('postalCode', this.postalCode)
      .set('fields', 'id,lang,country_name,country_flag_png,country_capital,country_phone_code,country_cca2');

    this.http.get<Country[]>(`${this.BASE_URL}/zipCode`, { params }).subscribe({
      next: (data) => {
        if (data.length > 0) {
          this.country.set(data[0]);
          this.isValid.set(true);
        } else {
          this.country.set(null);
          this.isValid.set(false);
        }
        this.loading.set(false);
      },
      error: (err) => {
        this.error.set(err.message);
        this.country.set(null);
        this.isValid.set(false);
        this.loading.set(false);
      }
    });
  }
}

Python

import requests
from typing import Optional, List, Dict, Any
from dataclasses import dataclass

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.countrydataapi.com/v1/countries"

@dataclass
class PostalCodeResult:
    """Represents a postal code lookup result"""
    is_valid: bool
    country_name: str
    country_code: str
    flag_url: str
    capital: List[str]
    phone_code: str

def search_country_by_postal_code(
    postal_code: str,
    fields: Optional[str] = None,
    lang: str = "en"
) -> List[Dict[str, Any]]:
    """
    Search for countries by postal code.

    Args:
        postal_code: The postal code to search for
        fields: Comma-separated list of fields to return
        lang: Language for the response (default: "en")

    Returns:
        List of countries containing the postal code
    """
    params = {
        "apikey": API_KEY,
        "postalCode": postal_code,
        "lang": lang
    }

    if fields:
        params["fields"] = fields

    try:
        response = requests.get(f"{BASE_URL}/zipCode", params=params)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.HTTPError as e:
        print(f"HTTP Error: {e}")
        raise
    except requests.exceptions.RequestException as e:
        print(f"Request Error: {e}")
        raise

def validate_postal_code(postal_code: str) -> PostalCodeResult:
    """
    Validate a postal code and get country information.

    Args:
        postal_code: The postal code to validate

    Returns:
        PostalCodeResult with validation status and country info
    """
    fields = "id,lang,country_name,country_flag_png,country_capital,country_phone_code,country_cca2"

    try:
        countries = search_country_by_postal_code(postal_code, fields=fields)

        if not countries:
            return PostalCodeResult(
                is_valid=False,
                country_name="",
                country_code="",
                flag_url="",
                capital=[],
                phone_code=""
            )

        country = countries[0]
        return PostalCodeResult(
            is_valid=True,
            country_name=country.get("country_name", ""),
            country_code=country.get("country_cca2", ""),
            flag_url=country.get("country_flag_png", ""),
            capital=country.get("country_capital", []),
            phone_code=country.get("country_phone_code", "")
        )
    except Exception:
        return PostalCodeResult(
            is_valid=False,
            country_name="",
            country_code="",
            flag_url="",
            capital=[],
            phone_code=""
        )

# Example usage
if __name__ == "__main__":
    # Basic validation
    print("Validating postal codes...")

    # US ZIP code
    us_result = validate_postal_code("10001")
    if us_result.is_valid:
        print(f"10001 (NYC): {us_result.country_name} ({us_result.country_code})")

    # UK postal code
    uk_result = validate_postal_code("SW1A")
    if uk_result.is_valid:
        print(f"SW1A (London): {uk_result.country_name} ({uk_result.country_code})")

    # German postal code
    de_result = validate_postal_code("10115")
    if de_result.is_valid:
        print(f"10115 (Berlin): {de_result.country_name} ({de_result.country_code})")

PHP

<?php

class PostalCodeService
{
    private string $apiKey;
    private string $baseUrl = 'https://api.countrydataapi.com/v1/countries';

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
    }

    /**
     * Search for countries by postal code
     */
    public function searchByPostalCode(string $postalCode, array $options = []): array
    {
        $params = array_merge([
            'apikey' => $this->apiKey,
            'postalCode' => $postalCode
        ], $options);

        $url = $this->baseUrl . '/zipCode?' . http_build_query($params);

        $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);
        curl_close($ch);

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

        return json_decode($response, true) ?? [];
    }

    /**
     * Validate a postal code
     */
    public function validatePostalCode(string $postalCode): array
    {
        try {
            $countries = $this->searchByPostalCode($postalCode, [
                'fields' => 'id,lang,country_name,country_flag_png,country_capital,country_phone_code,country_cca2'
            ]);

            return [
                'isValid' => !empty($countries),
                'country' => $countries[0] ?? null
            ];
        } catch (Exception $e) {
            return [
                'isValid' => false,
                'country' => null,
                'error' => $e->getMessage()
            ];
        }
    }
}

// Example usage
$apiKey = 'YOUR_API_KEY';
$postalCodeService = new PostalCodeService($apiKey);

try {
    // US ZIP code
    $usResult = $postalCodeService->validatePostalCode('10001');
    if ($usResult['isValid']) {
        echo "10001 (NYC): " . $usResult['country']['country_name'] . "\n";
    }

    // UK postal code
    $ukResult = $postalCodeService->validatePostalCode('SW1A');
    if ($ukResult['isValid']) {
        echo "SW1A (London): " . $ukResult['country']['country_name'] . "\n";
    }

    // French postal code
    $frResult = $postalCodeService->validatePostalCode('75001');
    if ($frResult['isValid']) {
        echo "75001 (Paris): " . $frResult['country']['country_name'] . "\n";
    }
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>

Manejo de errores

Codigo de estado Descripcion
200 Exito - Retorna array de paises
400 Solicitud incorrecta - Parametro de codigo postal invalido o faltante
401 No autorizado - Clave API invalida o faltante
404 No encontrado - No se encontraron paises con ese codigo postal
429 Demasiadas solicitudes - Limite de tasa excedido
500 Error interno del servidor - Error del lado del servidor