Documentación de la API - Endpoints y Ejemplos

Buscar estados por país

Descripcion general

Este endpoint te permite obtener todos los estados que pertenecen a un país específico. Es perfecto para construir desplegables de país-estado, filtrar datos geográficos, o cuando necesitas mostrar todas las divisiones administrativas de un país en particular.

Country Data API proporciona información detallada sobre +200 países diferentes

Autenticación

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.


Petición

HTTP GET

https://api.countrydataapi.com/v1/states/country

Retorna los estados que pertenecen a ese país.

Algunos ejemplos de la estructura

País: EEUU, Estado: Colorado, Ciudad: Denver

País: España, Estado: Comunidad Valenciana, Ciudad: Valencia

Según los campos solicitados, habrá 3 tipos de peticiones:

  • BASIC: Retorna los campos id, state_name, lang Cada estado costará 1 token

  • NORMAL: Retorna el campo state_cities [Todos los IDs y nombres de ciudades del estado] Cada ciudad costará 1 token

  • ADVANCED: Retorna el campo state_zip_codes [Todos los códigos postales de la ciudad] Cada código postal cuesta 1 token

Parámetros de consulta


Parámetro Tipo Descripción
apikey requerido, token Clave de autenticación de la cuenta
country requerido, string Nombre del país del que se desean los estados
limitToken opcional, number 1000 (predeterminado). Número máximo de tokens que quieres gastar en esta petición
fields opcional, string id,lang,state_name (predeterminado). Campos esperados en la respuesta
lang opcional, lang en (predeterminado). Idioma esperado de la respuesta

Respuesta

Ejemplo de respuesta

[
  {
    "id": "8dd25479-067a-43b0-ac4a-8e7faf2bcafb",
    "state_name": "Takhar",
    "lang": "en",
    "state_cities": [
      {
        "id": "8dd25476-067a-43b0-ac4b-8e7faf2bcbfb",
        "city_name": "City"
      }
    ],
    "state_zip_codes": [
      "00000",
      "00001"
    ]
  }
]

Ejemplos de código

JavaScript (Fetch)

const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/country';

async function getStatesByCountry(countryName) {
  try {
    const params = new URLSearchParams({
      apikey: API_KEY,
      country: countryName,
      lang: 'en',
      fields: 'id,state_name,lang'
    });

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

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

    const states = await response.json();
    console.log(`Estados en ${countryName}:`, states);
    return states;
  } catch (error) {
    console.error('Error fetching states:', error);
    throw error;
  }
}

// Uso
getStatesByCountry('United States');
getStatesByCountry('Spain');

JavaScript (Axios)

import axios from 'axios';

const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/country';

async function getStatesByCountry(countryName) {
  try {
    const response = await axios.get(BASE_URL, {
      params: {
        apikey: API_KEY,
        country: countryName,
        lang: 'en',
        fields: 'id,state_name,lang'
      }
    });

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

// Uso
getStatesByCountry('Germany');

React

import { useState, useEffect } from 'react';

const API_KEY = 'TU_CLAVE_API';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/country';

function StatesByCountry({ country }) {
  const [states, setStates] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchStates = async () => {
      if (!country) return;

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

        const params = new URLSearchParams({
          apikey: API_KEY,
          country: country,
          lang: 'en',
          fields: 'id,state_name,lang'
        });

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

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

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

    fetchStates();
  }, [country]);

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

  return (
    <div>
      <h2>Estados en {country}</h2>
      <p>Total: {states.length} estados</p>
      <ul>
        {states.map((state) => (
          <li key={state.id}>{state.state_name}</li>
        ))}
      </ul>
    </div>
  );
}

// Selector de país con desplegable de estados
function CountryStateSelector() {
  const [selectedCountry, setSelectedCountry] = useState('');
  const [states, setStates] = useState([]);
  const [selectedState, setSelectedState] = useState('');
  const [loading, setLoading] = useState(false);

  const countries = ['United States', 'Spain', 'Germany', 'France', 'Mexico'];

  useEffect(() => {
    if (!selectedCountry) {
      setStates([]);
      return;
    }

    const fetchStates = async () => {
      setLoading(true);
      const params = new URLSearchParams({
        apikey: API_KEY,
        country: selectedCountry,
        lang: 'en',
        fields: 'id,state_name'
      });

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

    fetchStates();
  }, [selectedCountry]);

  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>

      <select
        value={selectedState}
        onChange={(e) => setSelectedState(e.target.value)}
        disabled={loading || !states.length}
      >
        <option value="">
          {loading ? 'Cargando...' : 'Seleccionar Estado'}
        </option>
        {states.map((s) => (
          <option key={s.id} value={s.id}>{s.state_name}</option>
        ))}
      </select>
    </div>
  );
}

export default StatesByCountry;

Vue 3

<template>
  <div>
    <div v-if="loading">Cargando estados...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else>
      <h2>Estados en {{ country }}</h2>
      <p>Total: {{ states.length }} estados</p>
      <ul>
        <li v-for="state in states" :key="state.id">
          {{ state.state_name }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, 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/states/country';

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

const fetchStates = async () => {
  if (!props.country) return;

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

    const params = new URLSearchParams({
      apikey: API_KEY,
      country: props.country,
      lang: 'en',
      fields: 'id,state_name,lang'
    });

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

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

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

watch(() => props.country, fetchStates);
onMounted(fetchStates);
</script>

Angular

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

interface State {
  id: string;
  state_name: string;
  lang: string;
  state_cities?: Array<{ id: string; city_name: string }>;
  state_zip_codes?: string[];
}

@Component({
  selector: 'app-states-by-country',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div>
      <div *ngIf="loading">Cargando estados...</div>
      <div *ngIf="error">Error: {{ error }}</div>
      <div *ngIf="!loading && !error">
        <h2>Estados en {{ country }}</h2>
        <p>Total: {{ states.length }} estados</p>
        <ul>
          <li *ngFor="let state of states">{{ state.state_name }}</li>
        </ul>
      </div>
    </div>
  `
})
export class StatesByCountryComponent implements OnInit, OnChanges {
  @Input() country!: string;

  private readonly API_KEY = 'TU_CLAVE_API';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1/states/country';

  states: State[] = [];
  loading = true;
  error: string | null = null;

  constructor(private http: HttpClient) {}

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

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

  private fetchStates(): void {
    if (!this.country) return;

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

    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('country', this.country)
      .set('lang', 'en')
      .set('fields', 'id,state_name,lang');

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

PHP

<?php

$apiKey = 'TU_CLAVE_API';
$baseUrl = 'https://api.countrydataapi.com/v1/states/country';

function getStatesByCountry($countryName, $apiKey) {
    $baseUrl = 'https://api.countrydataapi.com/v1/states/country';

    $params = http_build_query([
        'apikey' => $apiKey,
        'country' => $countryName,
        'lang' => 'en',
        'fields' => 'id,state_name,lang'
    ]);

    $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 {
    $states = getStatesByCountry('United States', $apiKey);

    echo "Estados en United States:\n";
    echo "Total: " . count($states) . " estados\n\n";

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

// Alternativa usando file_get_contents
function getStatesByCountrySimple($countryName, $apiKey) {
    $baseUrl = 'https://api.countrydataapi.com/v1/states/country';

    $params = http_build_query([
        'apikey' => $apiKey,
        'country' => $countryName,
        'lang' => 'en',
        'fields' => 'id,state_name,lang'
    ]);

    $response = file_get_contents($baseUrl . '?' . $params);

    if ($response === false) {
        throw new Exception('Failed to fetch states');
    }

    return json_decode($response, true);
}
?>

Python

import requests

API_KEY = 'TU_CLAVE_API'
BASE_URL = 'https://api.countrydataapi.com/v1/states/country'

def get_states_by_country(country_name):
    """Obtener todos los estados de un país específico."""
    params = {
        'apikey': API_KEY,
        'country': country_name,
        'lang': 'en',
        'fields': 'id,state_name,lang'
    }

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

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

# Uso
if __name__ == '__main__':
    country = 'United States'
    states = get_states_by_country(country)

    print(f"Estados en {country}:")
    print(f"Total: {len(states)} estados\n")

    for state in states[:10]:  # Primeros 10 estados
        print(f"  - {state['state_name']}")


# Versión asíncrona con aiohttp
import aiohttp
import asyncio

async def get_states_by_country_async(country_name):
    """Obtener estados de un país de forma asíncrona."""
    params = {
        'apikey': API_KEY,
        'country': country_name,
        'lang': 'en',
        'fields': 'id,state_name,lang'
    }

    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 estados de múltiples países en paralelo
async def get_states_for_multiple_countries(countries):
    """Obtener estados de múltiples países concurrentemente."""
    tasks = [get_states_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']
# results = asyncio.run(get_states_for_multiple_countries(countries))

cURL

# Obtener estados de Estados Unidos
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=United%20States&lang=en&fields=id,state_name,lang"

# Obtener estados de España
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=Spain&lang=en"

# Con salida JSON formateada
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=Germany&lang=en" | json_pp

# Obtener estados con información de ciudades (petición NORMAL)
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=France&fields=id,state_name,state_cities"

# Limitar uso de tokens
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=Mexico&limitToken=500"

# Guardar respuesta en archivo
curl -X GET "https://api.countrydataapi.com/v1/states/country?apikey=TU_CLAVE_API&country=Canada&lang=en" -o canada_states.json

Manejo de errores

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

Ejemplo de respuesta de error

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