API Documentation - Endpoints & Examples

Search country by name

Overview

The Countries by Name endpoint allows you to search for countries using their name or partial name. This is useful for implementing country search functionality, autocomplete features, and country lookup tools.


Authentication

All requests require an API key passed as a query parameter. You can obtain your API key by registering at CountryDataAPI.

Request

HTTP GET

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

Returns a list of all countries that match the search criteria.

There are 4 types of operations:

  • BASIC: Returns the fields id, lang, country_name, country_short_iso, country_phone_code, country_cca2, country_ccn3, country_cca3, country_cioc.

  • NORMAL: Returns the previous fields and adds 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: Returns the previous fields and adds country_car_info, _country_idd_info.

  • ALL: Returns the previous fields and adds 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.

Each country returned with the BASIC method will cost 1 tokens.

Each country returned with the NORMAL method will cost 2 tokens.

Each country returned with the ADVANCED method will cost 3 tokens.

Each country returned with the ALL method will cost 4 tokens.

Query Params


Parameter Type Description
apikey required, token Authentication key of the account
name required, string Name of the country being searched
limitToken optional, number 1000 (default). Maximum number of countries to be returned
lang optional, lang en (default). Expected language of the response
type optional, string basic (default), normal, advanced or all

Response

Example Response

[
  {
    "id": "f7a8b9c0-1234-5678-90ab-cdef12345678",
    "lang": "en",
    "country_name": "Spain",
    "country_short_iso": "ES",
    "country_phone_code": "34",
    "country_cca2": "ES",
    "country_ccn3": "724",
    "country_cca3": "ESP",
    "country_cioc": "ESP"
  }
]

Code Examples

cURL

# Search for countries with "Spain" in the name
curl -X GET "https://api.countrydataapi.com/v1/countries/name?apikey=YOUR_API_KEY&name=Spain"

# Search for countries starting with "United"
curl -X GET "https://api.countrydataapi.com/v1/countries/name?apikey=YOUR_API_KEY&name=United"

JavaScript (Fetch)

const API_KEY = 'YOUR_API_KEY';

async function searchCountryByName(name) {
  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/countries/name?apikey=${API_KEY}&name=${encodeURIComponent(name)}`
    );

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

    const countries = await response.json();
    console.log(`Countries matching "${name}":`, countries);
    return countries;
  } catch (error) {
    console.error('Error searching countries:', error);
    throw error;
  }
}

// Search for Spain
searchCountryByName('Spain');

// Search for countries with "land" in the name
searchCountryByName('land');

JavaScript (Axios)

import axios from 'axios';

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

async function searchCountryByName(name, type = 'basic') {
  try {
    const { data } = await axios.get(`${BASE_URL}/countries/name`, {
      params: {
        apikey: API_KEY,
        name: name,
        type: type
      }
    });

    console.log(`Countries matching "${name}":`, data);
    return data;
  } catch (error) {
    console.error('Error searching countries:', error.response?.data || error.message);
    throw error;
  }
}

// Search with different detail levels
searchCountryByName('France', 'basic');
searchCountryByName('France', 'all');

React

import { useState, useEffect, useCallback } from 'react';
import debounce from 'lodash/debounce';

const API_KEY = 'YOUR_API_KEY';

function CountrySearch() {
  const [searchTerm, setSearchTerm] = useState('');
  const [countries, setCountries] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const searchCountries = useCallback(
    debounce(async (name) => {
      if (!name.trim()) {
        setCountries([]);
        return;
      }

      setLoading(true);
      setError(null);

      try {
        const response = await fetch(
          `https://api.countrydataapi.com/v1/countries/name?apikey=${API_KEY}&name=${encodeURIComponent(name)}`
        );

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

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

  useEffect(() => {
    searchCountries(searchTerm);
  }, [searchTerm, searchCountries]);

  return (
    <div className="country-search">
      <h2>Search Countries by Name</h2>

      <input
        type="text"
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
        placeholder="Type a country name..."
        className="search-input"
      />

      {loading && <div className="loading">Searching...</div>}
      {error && <div className="error">Error: {error}</div>}

      {countries.length > 0 && (
        <div className="results">
          <h3>Results ({countries.length})</h3>
          <ul>
            {countries.map((country) => (
              <li key={country.id}>
                <img src={country.country_flag_png} alt={country.country_name} width="24" />
                <span>{country.country_name}</span>
                <span className="code">({country.country_cca2})</span>
              </li>
            ))}
          </ul>
        </div>
      )}

      {searchTerm && !loading && countries.length === 0 && (
        <div className="no-results">No countries found matching "{searchTerm}"</div>
      )}
    </div>
  );
}

export default CountrySearch;

Vue 3

<script setup>
import { ref, watch } from 'vue';
import { useDebounceFn } from '@vueuse/core';

const API_KEY = 'YOUR_API_KEY';

const searchTerm = ref('');
const countries = ref([]);
const loading = ref(false);
const error = ref(null);

const searchCountries = useDebounceFn(async (name) => {
  if (!name.trim()) {
    countries.value = [];
    return;
  }

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

  try {
    const response = await fetch(
      `https://api.countrydataapi.com/v1/countries/name?apikey=${API_KEY}&name=${encodeURIComponent(name)}`
    );

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

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

watch(searchTerm, (newValue) => {
  searchCountries(newValue);
});
</script>

<template>
  <div class="country-search">
    <h2>Search Countries by Name</h2>

    <input
      v-model="searchTerm"
      type="text"
      placeholder="Type a country name..."
      class="search-input"
    />

    <div v-if="loading" class="loading">Searching...</div>
    <div v-if="error" class="error">Error: {{ error }}</div>

    <div v-if="countries.length > 0" class="results">
      <h3>Results ({{ countries.length }})</h3>
      <ul>
        <li v-for="country in countries" :key="country.id">
          <img :src="country.country_flag_png" :alt="country.country_name" width="24" />
          <span>{{ country.country_name }}</span>
          <span class="code">({{ country.country_cca2 }})</span>
        </li>
      </ul>
    </div>

    <div v-if="searchTerm && !loading && countries.length === 0" class="no-results">
      No countries found matching "{{ searchTerm }}"
    </div>
  </div>
</template>

Angular

import { Component, inject, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Subject, debounceTime, distinctUntilChanged, switchMap, of } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

interface Country {
  id: string;
  country_name: string;
  country_short_iso: string;
  country_cca2: string;
  country_flag_png?: string;
}

@Component({
  selector: 'app-country-search',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <div class="country-search">
      <h2>Search Countries by Name</h2>

      <input
        [(ngModel)]="searchTerm"
        (ngModelChange)="onSearchChange($event)"
        type="text"
        placeholder="Type a country name..."
        class="search-input"
      />

      <div *ngIf="loading" class="loading">Searching...</div>
      <div *ngIf="error" class="error">Error: {{ error }}</div>

      <div *ngIf="countries.length > 0" class="results">
        <h3>Results ({{ countries.length }})</h3>
        <ul>
          <li *ngFor="let country of countries">
            <img [src]="country.country_flag_png" [alt]="country.country_name" width="24" />
            <span>{{ country.country_name }}</span>
            <span class="code">({{ country.country_cca2 }})</span>
          </li>
        </ul>
      </div>

      <div *ngIf="searchTerm && !loading && countries.length === 0" class="no-results">
        No countries found matching "{{ searchTerm }}"
      </div>
    </div>
  `
})
export class CountrySearchComponent implements OnInit, OnDestroy {
  private http = inject(HttpClient);
  private readonly API_KEY = 'YOUR_API_KEY';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1';

  private searchSubject = new Subject<string>();
  private destroy$ = new Subject<void>();

  searchTerm = '';
  countries: Country[] = [];
  loading = false;
  error: string | null = null;

  ngOnInit(): void {
    this.searchSubject.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      switchMap((term) => {
        if (!term.trim()) {
          return of([]);
        }
        this.loading = true;
        this.error = null;
        return this.http.get<Country[]>(
          `${this.BASE_URL}/countries/name`,
          { params: { apikey: this.API_KEY, name: term } }
        );
      }),
      takeUntil(this.destroy$)
    ).subscribe({
      next: (data) => {
        this.countries = data;
        this.loading = false;
      },
      error: (err) => {
        this.error = err.message;
        this.loading = false;
      }
    });
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  onSearchChange(term: string): void {
    this.searchSubject.next(term);
  }
}

Python

import requests
from urllib.parse import quote

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

def search_country_by_name(name, data_type='basic'):
    """Search for countries by name."""
    try:
        response = requests.get(
            f'{BASE_URL}/countries/name',
            params={
                'apikey': API_KEY,
                'name': name,
                'type': data_type
            }
        )
        response.raise_for_status()

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

# Usage
if __name__ == '__main__':
    # Search for Spain
    results = search_country_by_name('Spain')
    print(f"Search results for 'Spain' ({len(results)} found):")
    for country in results:
        print(f"  - {country['country_name']} ({country['country_short_iso']})")

    print()

    # Search for countries with "United" in the name
    results = search_country_by_name('United')
    print(f"Search results for 'United' ({len(results)} found):")
    for country in results:
        print(f"  - {country['country_name']} ({country['country_short_iso']})")

    print()

    # Search for countries with "land" in the name
    results = search_country_by_name('land')
    print(f"Search results for 'land' ({len(results)} found):")
    for country in results:
        print(f"  - {country['country_name']} ({country['country_short_iso']})")

PHP

<?php

$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://api.countrydataapi.com/v1';

function searchCountryByName($apiKey, $baseUrl, $name, $type = 'basic') {
    $url = sprintf(
        '%s/countries/name?apikey=%s&name=%s&type=%s',
        $baseUrl,
        urlencode($apiKey),
        urlencode($name),
        urlencode($type)
    );

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        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);
}

// Usage
try {
    // Search for Spain
    $results = searchCountryByName($apiKey, $baseUrl, 'Spain');
    echo "Search results for 'Spain' (" . count($results) . " found):\n";
    foreach ($results as $country) {
        echo sprintf("  - %s (%s)\n", $country['country_name'], $country['country_short_iso']);
    }

    echo "\n";

    // Search for countries with "United" in the name
    $results = searchCountryByName($apiKey, $baseUrl, 'United');
    echo "Search results for 'United' (" . count($results) . " found):\n";
    foreach ($results as $country) {
        echo sprintf("  - %s (%s)\n", $country['country_name'], $country['country_short_iso']);
    }

    echo "\n";

    // Search for countries with "land" in the name
    $results = searchCountryByName($apiKey, $baseUrl, 'land');
    echo "Search results for 'land' (" . count($results) . " found):\n";
    foreach ($results as $country) {
        echo sprintf("  - %s (%s)\n", $country['country_name'], $country['country_short_iso']);
    }
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}

Error Handling

Status Code Description
200 Success - Returns array of matching countries
400 Bad Request - Missing required name parameter
401 Unauthorized - Invalid or missing API key
404 Not Found - No countries found matching the search
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Something went wrong on our end

Error Response Example

{
  "statusCode": 404,
  "message": "No countries found matching: xyz",
  "error": "Not Found"
}

Notes

  • Partial Matching: The search performs partial matching, so searching for "land" will return countries like "Finland", "Iceland", "Ireland", etc.
  • Case Insensitive: Searches are case-insensitive.
  • Special Characters: Country names with special characters (accents, umlauts) should be URL-encoded.