API Documentation - Endpoints & Examples

All Postal Codes

Country Data API provides detailed information about +200 different countries

Overview

The /v1/zipcodes/all endpoint returns a comprehensive list of all postal codes from all cities worldwide. This endpoint is ideal for applications that need to populate databases with complete postal code information.

Endpoint

GET https://api.countrydataapi.com/v1/zipcodes/all

Authentication

Include your API key as a query parameter:

?apikey=your-api-key

Your API key is like a password, keep it secure. Get your key from the account dashboard.

Query Parameters

Parameter Type Required Description
apikey string Yes Your API authentication key
lang string No Language code for response (default: en)
limitToken number No Maximum tokens to spend on this request (default: 1000)

Supported Languages

  • en - English (default)
  • es - Spanish
  • pt - Portuguese
  • fr - French
  • de - German
  • it - Italian

Token Usage

Each returned postal code will cost 1 token.

Important: This endpoint can return a large amount of data. Use limitToken to control costs and implement pagination for large datasets.

Response Format

Success Response

[
  {
    "id": "8dd25479-067a-43b0-ac4a-8e7faf2bcaf",
    "country_name": "Algeria",
    "state_names": [
      {
        "id": "8dd25479-067a-43b0-ac4a-8e7faf2bcad",
        "name": "Oran",
        "postal_code": [
          "31004",
          "31016",
          "31019",
          "31020"
        ]
      }
    ]
  },
  {
    "id": "9ae35480-178b-54c1-bd5b-9f8gbf3cdeg",
    "country_name": "United States",
    "state_names": [
      {
        "id": "9ae35480-178b-54c1-bd5b-9f8gbf3cdeh",
        "name": "California",
        "postal_code": [
          "90001",
          "90002",
          "90003"
        ]
      }
    ]
  }
]

Response Fields

Field Type Description
id string Unique country identifier
country_name string Country name in the requested language
state_names array Array of state objects containing postal codes
state_names[].id string Unique state identifier
state_names[].name string State/province name
state_names[].postal_code array Array of postal codes for this state

Error Response

{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The provided API key is invalid"
  }
}

See the Error Codes documentation for all possible error codes.

Code Examples

cURL

curl -X GET "https://api.countrydataapi.com/v1/zipcodes/all?apikey=your-api-key&lang=en&limitToken=100"

JavaScript (Fetch)

const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';

async function getAllZipcodes(limitToken = 1000) {
  try {
    const response = await fetch(
      `${BASE_URL}/zipcodes/all?apikey=${API_KEY}&lang=en&limitToken=${limitToken}`
    );

    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:', error);
    throw error;
  }
}

// Usage
const zipcodes = await getAllZipcodes(100);
console.log(zipcodes);

JavaScript (Axios)

import axios from 'axios';

const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';

async function getAllZipcodes(limitToken = 1000) {
  try {
    const response = await axios.get(`${BASE_URL}/zipcodes/all`, {
      params: {
        apikey: API_KEY,
        lang: 'en',
        limitToken: limitToken
      }
    });

    return response.data;
  } catch (error) {
    console.error('Error fetching zipcodes:', error.response?.data || error.message);
    throw error;
  }
}

// Usage
const zipcodes = await getAllZipcodes(100);
console.log(zipcodes);

React

import { useState, useEffect } from 'react';

const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';

function useAllZipcodes(limitToken = 1000) {
  const [zipcodes, setZipcodes] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchZipcodes() {
      try {
        setLoading(true);
        const response = await fetch(
          `${BASE_URL}/zipcodes/all?apikey=${API_KEY}&lang=en&limitToken=${limitToken}`
        );

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

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

    fetchZipcodes();
  }, [limitToken]);

  return { zipcodes, loading, error };
}

// Component Example
function ZipcodeList() {
  const { zipcodes, loading, error } = useAllZipcodes(100);

  if (loading) return <div>Loading postal codes...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <h2>All Postal Codes</h2>
      {zipcodes.map(country => (
        <div key={country.id}>
          <h3>{country.country_name}</h3>
          {country.state_names.map(state => (
            <div key={state.id}>
              <h4>{state.name}</h4>
              <p>{state.postal_code.join(', ')}</p>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}

export default ZipcodeList;

Vue 3

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

const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';

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

async function fetchAllZipcodes(limitToken = 1000) {
  try {
    loading.value = true;
    const response = await fetch(
      `${BASE_URL}/zipcodes/all?apikey=${API_KEY}&lang=en&limitToken=${limitToken}`
    );

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

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

onMounted(() => fetchAllZipcodes(100));
</script>

<template>
  <div>
    <div v-if="loading">Loading postal codes...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else>
      <h2>All Postal Codes</h2>
      <div v-for="country in zipcodes" :key="country.id">
        <h3>{{ country.country_name }}</h3>
        <div v-for="state in country.state_names" :key="state.id">
          <h4>{{ state.name }}</h4>
          <p>{{ state.postal_code.join(', ') }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

Angular

// 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 ZipcodeResponse {
  id: string;
  country_name: string;
  state_names: State[];
}

@Injectable({
  providedIn: 'root'
})
export class ZipcodeService {
  private readonly API_KEY = 'your-api-key';
  private readonly BASE_URL = 'https://api.countrydataapi.com/v1';

  constructor(private http: HttpClient) {}

  getAllZipcodes(limitToken: number = 1000): Observable<ZipcodeResponse[]> {
    const params = new HttpParams()
      .set('apikey', this.API_KEY)
      .set('lang', 'en')
      .set('limitToken', limitToken.toString());

    return this.http.get<ZipcodeResponse[]>(
      `${this.BASE_URL}/zipcodes/all`,
      { params }
    );
  }
}

// zipcode-list.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ZipcodeService } from './zipcode.service';

@Component({
  selector: 'app-zipcode-list',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div *ngIf="loading">Loading postal codes...</div>
    <div *ngIf="error">Error: {{ error }}</div>
    <div *ngIf="!loading && !error">
      <h2>All Postal Codes</h2>
      <div *ngFor="let country of zipcodes">
        <h3>{{ country.country_name }}</h3>
        <div *ngFor="let state of country.state_names">
          <h4>{{ state.name }}</h4>
          <p>{{ state.postal_code.join(', ') }}</p>
        </div>
      </div>
    </div>
  `
})
export class ZipcodeListComponent implements OnInit {
  zipcodes: any[] = [];
  loading = true;
  error: string | null = null;

  constructor(private zipcodeService: ZipcodeService) {}

  ngOnInit() {
    this.zipcodeService.getAllZipcodes(100).subscribe({
      next: (data) => {
        this.zipcodes = data;
        this.loading = false;
      },
      error: (err) => {
        this.error = err.message;
        this.loading = false;
      }
    });
  }
}

PHP

<?php
$apiKey = 'your-api-key';
$limitToken = 100;
$url = "https://api.countrydataapi.com/v1/zipcodes/all?apikey={$apiKey}&lang=en&limitToken={$limitToken}";

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

if ($httpCode === 200) {
    $zipcodes = json_decode($response, true);

    foreach ($zipcodes as $country) {
        echo "Country: " . $country['country_name'] . "\n";
        foreach ($country['state_names'] as $state) {
            echo "  State: " . $state['name'] . "\n";
            echo "  Postal Codes: " . implode(', ', $state['postal_code']) . "\n";
        }
    }
} else {
    echo "Error: HTTP {$httpCode}\n";
    echo $response;
}

// Alternative using file_get_contents
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => 'Accept: application/json'
    ]
]);

$response = file_get_contents($url, false, $context);
$zipcodes = json_decode($response, true);
?>

Python

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

API_KEY = 'your-api-key'
BASE_URL = 'https://api.countrydataapi.com/v1'

def get_all_zipcodes(limit_token: int = 1000, lang: str = 'en') -> List[Dict[str, Any]]:
    """
    Fetch all postal codes from all countries.

    Args:
        limit_token: Maximum tokens to spend on this request
        lang: Language code for response

    Returns:
        List of countries with their postal codes
    """
    try:
        response = requests.get(
            f'{BASE_URL}/zipcodes/all',
            params={
                'apikey': API_KEY,
                'lang': lang,
                'limitToken': limit_token
            },
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f'Error fetching zipcodes: {e}')
        raise

# Usage
if __name__ == '__main__':
    zipcodes = get_all_zipcodes(limit_token=100)

    for country in zipcodes:
        print(f"Country: {country['country_name']}")
        for state in country['state_names']:
            print(f"  State: {state['name']}")
            print(f"  Postal Codes: {', '.join(state['postal_code'][:5])}...")

# Using aiohttp for async requests
import aiohttp
import asyncio

async def get_all_zipcodes_async(limit_token: int = 1000) -> List[Dict[str, Any]]:
    """Async version using aiohttp"""
    async with aiohttp.ClientSession() as session:
        async with session.get(
            f'{BASE_URL}/zipcodes/all',
            params={
                'apikey': API_KEY,
                'lang': 'en',
                'limitToken': limit_token
            }
        ) as response:
            return await response.json()

# Run async
# zipcodes = asyncio.run(get_all_zipcodes_async(100))

Error Handling

Always implement proper error handling in your application:

async function getAllZipcodesWithErrorHandling() {
  try {
    const response = await fetch(
      'https://api.countrydataapi.com/v1/zipcodes/all?apikey=your-api-key'
    );

    if (!response.ok) {
      if (response.status === 401) {
        throw new Error('Invalid API key');
      } else if (response.status === 429) {
        throw new Error('Rate limit exceeded. Please try again later.');
      } else if (response.status === 402) {
        throw new Error('Insufficient tokens. Please upgrade your plan.');
      }
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();

    if (!Array.isArray(data)) {
      throw new Error('Invalid response format');
    }

    return data;
  } catch (error) {
    console.error('Failed to fetch zipcodes:', error.message);
    // Handle error appropriately (show user message, retry, etc.)
    throw error;
  }
}

Common Error Codes

Error Code Description Solution
INVALID_API_KEY API key is invalid Check your API key in account dashboard
QUOTA_EXCEEDED Daily token limit reached Upgrade plan or wait for reset
RATE_LIMITED Too many requests Implement rate limiting in your app
INVALID_LANGUAGE Language code not supported Use one of the supported language codes

Performance Tips

  1. Use limitToken: Control the amount of data returned to manage costs
  2. Cache results: Postal codes don't change frequently; cache for 24+ hours
  3. Paginate: For large datasets, use multiple requests with different limits
  4. Filter client-side: If you only need specific data, filter after fetching

Rate Limits

  • Free tier: 100 requests/day
  • Basic tier: 1,000 requests/day
  • Pro tier: 10,000 requests/day
  • Enterprise tier: Unlimited

Check our pricing page for more details.

Related Endpoints

Need Help?