Documentación de la API - Endpoints y Ejemplos

Buscar pais por estado

Descripcion general

El endpoint de busqueda de pais por estado te permite encontrar paises que contienen un estado o division administrativa especifica. Esto es particularmente util para aplicaciones basadas en ubicacion, sistemas de validacion de direcciones y analisis de datos geograficos.

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/state?apikey=YOUR_API_KEY&state=Colorado

Peticion

HTTP GET

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

Retorna el pais que tiene ese estado.

Algunos ejemplos de la estructura

Pais: EEUU, Estado: Colorado, Ciudad: Denver

Pais: Espana, Estado: Comunidad Valenciana, Ciudad: Valencia

Informacion relevante

Ten en cuenta que hay muchas ciudades con el mismo nombre.

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
state requerido, string Estado del pais 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 state name
curl -X GET "https://api.countrydataapi.com/v1/countries/state?apikey=YOUR_API_KEY&state=Colorado"

# With specific fields (BASIC)
curl -X GET "https://api.countrydataapi.com/v1/countries/state?apikey=YOUR_API_KEY&state=California&fields=id,lang,country_name,country_cca2"

# With NORMAL fields
curl -X GET "https://api.countrydataapi.com/v1/countries/state?apikey=YOUR_API_KEY&state=Bavaria&fields=id,lang,country_name,country_flag_png,country_capital"

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

JavaScript (Fetch)

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

// Search country by state
async function searchCountryByState(stateName, options = {}) {
  const params = new URLSearchParams({
    apikey: API_KEY,
    state: stateName,
    ...options
  });

  try {
    const response = await fetch(`${BASE_URL}/state?${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 state:', error);
    throw error;
  }
}

// Usage examples
searchCountryByState('Colorado')
  .then(countries => {
    console.log('Countries with Colorado state:', countries);
  });

// With specific fields
searchCountryByState('Texas', {
  fields: 'id,lang,country_name,country_flag_png,country_capital'
})
  .then(countries => {
    console.log('Texas state results:', countries);
  });

// Search European state
searchCountryByState('Bavaria', { lang: 'de' })
  .then(countries => {
    console.log('Bavaria results (German):', 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 state
async function searchCountryByState(stateName, options = {}) {
  try {
    const response = await apiClient.get('/state', {
      params: {
        state: stateName,
        ...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;
  }
}

// State lookup service
const stateLookupService = {
  async findCountryByState(stateName) {
    return searchCountryByState(stateName);
  },

  async getStateCountryDetails(stateName) {
    return searchCountryByState(stateName, {
      fields: 'id,lang,country_name,country_flag_png,country_capital,country_region,country_subregion'
    });
  },

  async searchStateInLanguage(stateName, lang) {
    return searchCountryByState(stateName, { lang });
  }
};

// Usage
stateLookupService.findCountryByState('New York')
  .then(result => console.log('New York state country:', result));

React

import { useState, useCallback } from 'react';

const API_KEY = 'YOUR_API_KEY';

function useStateSearch() {
  const [countries, setCountries] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const searchByState = useCallback(async (stateName, options = {}) => {
    if (!stateName.trim()) {
      setCountries([]);
      return;
    }

    setLoading(true);
    setError(null);

    const params = new URLSearchParams({
      apikey: API_KEY,
      state: stateName,
      fields: 'id,lang,country_name,country_flag_png,country_capital,country_region',
      ...options
    });

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

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

      const data = await response.json();
      setCountries(data);
    } catch (err) {
      setError(err.message);
      setCountries([]);
    } finally {
      setLoading(false);
    }
  }, []);

  return { countries, loading, error, searchByState };
}

function StateSearchComponent() {
  const [stateInput, setStateInput] = useState('');
  const { countries, loading, error, searchByState } = useStateSearch();

  const handleSearch = (e) => {
    e.preventDefault();
    searchByState(stateInput);
  };

  return (
    <div className="state-search-container">
      <h2>Find Country by State</h2>

      <form onSubmit={handleSearch} className="search-form">
        <input
          type="text"
          value={stateInput}
          onChange={(e) => setStateInput(e.target.value)}
          placeholder="Enter state name (e.g., California, Bavaria)"
        />
        <button type="submit" disabled={loading || !stateInput.trim()}>
          {loading ? 'Searching...' : 'Search'}
        </button>
      </form>

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

      {countries.length > 0 && (
        <div className="results">
          <h3>Results for "{stateInput}"</h3>
          {countries.map((country) => (
            <div key={country.id} className="country-card">
              <img src={country.country_flag_png} alt={`${country.country_name} flag`} />
              <div className="country-info">
                <h4>{country.country_name}</h4>
                <p>Capital: {country.country_capital?.join(', ') || 'N/A'}</p>
                <p>Region: {country.country_region}</p>
              </div>
            </div>
          ))}
        </div>
      )}

      {!loading && countries.length === 0 && stateInput && (
        <p className="no-results">No countries found with that state.</p>
      )}
    </div>
  );
}

export default StateSearchComponent;

Vue 3

<template>
  <div class="state-search">
    <h2>Find Country by State</h2>

    <form @submit.prevent="handleSearch" class="search-form">
      <input
        v-model="stateInput"
        type="text"
        placeholder="Enter state name (e.g., Texas, Catalonia)"
      />
      <button type="submit" :disabled="loading || !stateInput.trim()">
        {{ loading ? 'Searching...' : 'Search' }}
      </button>
    </form>

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

    <div v-if="countries.length > 0" class="results">
      <h3>Results for "{{ lastSearch }}"</h3>
      <div v-for="country in countries" :key="country.id" class="country-card">
        <img :src="country.country_flag_png" :alt="`${country.country_name} flag`" />
        <div class="country-details">
          <h4>{{ country.country_name }}</h4>
          <p><strong>Capital:</strong> {{ formatCapital(country.country_capital) }}</p>
          <p><strong>Region:</strong> {{ country.country_region }}</p>
        </div>
      </div>
    </div>

    <p v-if="!loading && searchPerformed && countries.length === 0" class="no-results">
      No countries found with state "{{ lastSearch }}".
    </p>
  </div>
</template>

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

const API_KEY = 'YOUR_API_KEY';

const stateInput = ref('');
const lastSearch = ref('');
const countries = ref([]);
const loading = ref(false);
const error = ref(null);
const searchPerformed = ref(false);

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

const handleSearch = async () => {
  if (!stateInput.value.trim()) return;

  loading.value = true;
  error.value = null;
  searchPerformed.value = true;
  lastSearch.value = stateInput.value;

  const params = new URLSearchParams({
    apikey: API_KEY,
    state: stateInput.value,
    fields: 'id,lang,country_name,country_flag_png,country_capital,country_region,country_subregion'
  });

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

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

    countries.value = await response.json();
  } catch (err) {
    error.value = err.message;
    countries.value = [];
  } 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_region?: string;
  country_subregion?: string;
}

@Component({
  selector: 'app-state-search',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <div class="state-search-container">
      <h2>Find Country by State</h2>

      <form (ngSubmit)="searchState()" class="search-form">
        <input
          type="text"
          [(ngModel)]="stateInput"
          name="stateInput"
          placeholder="Enter state name (e.g., Florida, Ontario)"
        />
        <button type="submit" [disabled]="loading() || !stateInput.trim()">
          {{ loading() ? 'Searching...' : 'Search' }}
        </button>
      </form>

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

      <div *ngIf="countries().length > 0" class="results">
        <h3>Results for "{{ lastSearch() }}"</h3>
        <div *ngFor="let country of countries()" class="country-card">
          <img [src]="country.country_flag_png" [alt]="country.country_name + ' flag'" />
          <div class="country-info">
            <h4>{{ country.country_name }}</h4>
            <p><strong>Capital:</strong> {{ formatCapital(country.country_capital) }}</p>
            <p><strong>Region:</strong> {{ country.country_region }}</p>
          </div>
        </div>
      </div>

      <p *ngIf="!loading() && searchPerformed() && countries().length === 0" class="no-results">
        No countries found with state "{{ lastSearch() }}".
      </p>
    </div>
  `
})
export class StateSearchComponent {
  private http = inject(HttpClient);
  private readonly API_KEY = 'YOUR_API_KEY';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1/countries';

  stateInput = '';
  countries = signal<Country[]>([]);
  loading = signal(false);
  error = signal<string | null>(null);
  searchPerformed = signal(false);
  lastSearch = signal('');

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

  searchState(): void {
    if (!this.stateInput.trim()) return;

    this.loading.set(true);
    this.error.set(null);
    this.searchPerformed.set(true);
    this.lastSearch.set(this.stateInput);

    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('state', this.stateInput)
      .set('fields', 'id,lang,country_name,country_flag_png,country_capital,country_region,country_subregion');

    this.http.get<Country[]>(`${this.BASE_URL}/state`, { params }).subscribe({
      next: (data) => {
        this.countries.set(data);
        this.loading.set(false);
      },
      error: (err) => {
        this.error.set(err.message);
        this.countries.set([]);
        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 StateSearchResult:
    """Represents a country found by state search"""
    id: str
    name: str
    flag_url: str
    capital: List[str]
    region: str
    subregion: str

def search_country_by_state(
    state_name: str,
    fields: Optional[str] = None,
    lang: str = "en",
    limit_token: int = 1000
) -> List[Dict[str, Any]]:
    """
    Search for countries by state name.

    Args:
        state_name: The state name to search for
        fields: Comma-separated list of fields to return
        lang: Language for the response (default: "en")
        limit_token: Maximum number of results (default: 1000)

    Returns:
        List of countries containing the specified state
    """
    params = {
        "apikey": API_KEY,
        "state": state_name,
        "lang": lang,
        "limitToken": limit_token
    }

    if fields:
        params["fields"] = fields

    try:
        response = requests.get(f"{BASE_URL}/state", 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 get_country_by_state_with_details(state_name: str) -> List[StateSearchResult]:
    """
    Get detailed country information by state name.

    Args:
        state_name: The state name to search for

    Returns:
        List of StateSearchResult objects
    """
    fields = "id,lang,country_name,country_flag_png,country_capital,country_region,country_subregion"

    countries = search_country_by_state(state_name, fields=fields)

    results = []
    for country in countries:
        results.append(StateSearchResult(
            id=country.get("id", ""),
            name=country.get("country_name", ""),
            flag_url=country.get("country_flag_png", ""),
            capital=country.get("country_capital", []),
            region=country.get("country_region", ""),
            subregion=country.get("country_subregion", "")
        ))

    return results

# Example usage
if __name__ == "__main__":
    # Basic search
    print("Searching for countries with 'California' state...")
    countries = search_country_by_state("California")
    for country in countries:
        print(f"  - {country.get('country_name')}")

    # Search with detailed results
    print("\nSearching for countries with 'Bavaria' state...")
    results = get_country_by_state_with_details("Bavaria")
    for result in results:
        print(f"  - {result.name}")
        print(f"    Capital: {', '.join(result.capital)}")
        print(f"    Region: {result.region}")

PHP

<?php

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

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

    /**
     * Search for countries by state name
     */
    public function searchByState(string $stateName, array $options = []): array
    {
        $params = array_merge([
            'apikey' => $this->apiKey,
            'state' => $stateName
        ], $options);

        $url = $this->baseUrl . '/state?' . 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) ?? [];
    }

    /**
     * Get detailed country information by state
     */
    public function getCountryDetailsByState(string $stateName): array
    {
        return $this->searchByState($stateName, [
            'fields' => 'id,lang,country_name,country_flag_png,country_capital,country_region,country_subregion'
        ]);
    }
}

// Example usage
$apiKey = 'YOUR_API_KEY';
$stateSearch = new CountryStateSearch($apiKey);

try {
    // Basic search
    echo "Searching for countries with 'Texas' state:\n";
    $countries = $stateSearch->searchByState('Texas');
    foreach ($countries as $country) {
        echo "  - " . $country['country_name'] . "\n";
    }

    // Search with details
    echo "\nSearching for 'Ontario' with details:\n";
    $details = $stateSearch->getCountryDetailsByState('Ontario');
    foreach ($details as $country) {
        echo "  - " . $country['country_name'] . "\n";
        echo "    Capital: " . implode(', ', $country['country_capital'] ?? []) . "\n";
        echo "    Region: " . ($country['country_region'] ?? 'N/A') . "\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 estado invalido o faltante
401 No autorizado - Clave API invalida o faltante
404 No encontrado - No se encontraron paises con ese estado
429 Demasiadas solicitudes - Limite de tasa excedido
500 Error interno del servidor - Error del lado del servidor