The /v1/zipcodes/state endpoint returns all postal codes for a specific state or province. This is ideal for applications that need to populate address forms or validate postal codes within a specific state.
GET https://api.countrydataapi.com/v1/zipcodes/state
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
apikey |
string | Yes | Your API authentication key |
state |
string | Yes | Name of the state or state ID being searched |
lang |
string | No | Language code for response (default: en) |
limitToken |
number | No | Maximum tokens to spend on this request (default: 1000) |
en - English (default)es - Spanishpt - Portuguesefr - Frenchde - Germanit - ItalianEach returned postal code will cost 1 token.
[
{
"id": "8dd25479-067a-43b0-ac4a-8e7faf2bcad",
"name": "California",
"postal_code": [
"90001",
"90002",
"90003",
"90004",
"90005"
]
}
]
| Field | Type | Description |
|---|---|---|
id |
string | Unique state identifier |
name |
string | State/province name in the requested language |
postal_code |
array | Array of postal codes for this state |
{
"success": false,
"error": {
"code": "MISSING_PARAMETER",
"message": "Required parameter 'state' is missing"
}
}
See the Error Codes documentation for all possible error codes.
# Search by state name
curl -X GET "https://api.countrydataapi.com/v1/zipcodes/state?apikey=your-api-key&state=California&lang=en"
# Search by state ID
curl -X GET "https://api.countrydataapi.com/v1/zipcodes/state?apikey=your-api-key&state=66c7a6cae4bda21f4ab11d1a&lang=en"
const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';
async function getZipcodesByState(state, limitToken = 1000) {
try {
const params = new URLSearchParams({
apikey: API_KEY,
state: state,
lang: 'en',
limitToken: limitToken.toString()
});
const response = await fetch(`${BASE_URL}/zipcodes/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 fetching zipcodes by state:', error);
throw error;
}
}
// Usage
const californiaZipcodes = await getZipcodesByState('California');
console.log(californiaZipcodes);
// Or by state ID
const texasZipcodes = await getZipcodesByState('66c7a6cbe4bda21f4ab11f55');
console.log(texasZipcodes);
import axios from 'axios';
const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';
async function getZipcodesByState(state, limitToken = 1000) {
try {
const response = await axios.get(`${BASE_URL}/zipcodes/state`, {
params: {
apikey: API_KEY,
state: state,
lang: 'en',
limitToken: limitToken
}
});
return response.data;
} catch (error) {
if (error.response) {
console.error('API Error:', error.response.data);
} else {
console.error('Network Error:', error.message);
}
throw error;
}
}
// Usage
const zipcodes = await getZipcodesByState('California');
console.log(`Found ${zipcodes[0]?.postal_code?.length || 0} postal codes`);
import { useState, useEffect } from 'react';
const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';
function useStateZipcodes(stateName) {
const [zipcodes, setZipcodes] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!stateName) {
setZipcodes([]);
return;
}
async function fetchZipcodes() {
try {
setLoading(true);
setError(null);
const params = new URLSearchParams({
apikey: API_KEY,
state: stateName,
lang: 'en'
});
const response = await fetch(`${BASE_URL}/zipcodes/state?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setZipcodes(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchZipcodes();
}, [stateName]);
return { zipcodes, loading, error };
}
// Component Example
function StateZipcodeSearch() {
const [selectedState, setSelectedState] = useState('');
const { zipcodes, loading, error } = useStateZipcodes(selectedState);
const states = ['California', 'Texas', 'New York', 'Florida'];
return (
<div>
<h2>Search Postal Codes by State</h2>
<select
value={selectedState}
onChange={(e) => setSelectedState(e.target.value)}
>
<option value="">Select a state...</option>
{states.map(state => (
<option key={state} value={state}>{state}</option>
))}
</select>
{loading && <p>Loading postal codes...</p>}
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
{zipcodes.length > 0 && (
<div>
<h3>{zipcodes[0].name}</h3>
<p>Total postal codes: {zipcodes[0].postal_code.length}</p>
<div style={{ maxHeight: '200px', overflow: 'auto' }}>
{zipcodes[0].postal_code.slice(0, 100).map(code => (
<span key={code} style={{ margin: '2px', display: 'inline-block' }}>
{code}
</span>
))}
{zipcodes[0].postal_code.length > 100 && (
<span>...and {zipcodes[0].postal_code.length - 100} more</span>
)}
</div>
</div>
)}
</div>
);
}
export default StateZipcodeSearch;
<script setup>
import { ref, watch, computed } from 'vue';
const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.countrydataapi.com/v1';
const selectedState = ref('');
const zipcodes = ref([]);
const loading = ref(false);
const error = ref(null);
const states = ['California', 'Texas', 'New York', 'Florida'];
const postalCodes = computed(() => {
return zipcodes.value[0]?.postal_code || [];
});
watch(selectedState, async (newState) => {
if (!newState) {
zipcodes.value = [];
return;
}
try {
loading.value = true;
error.value = null;
const params = new URLSearchParams({
apikey: API_KEY,
state: newState,
lang: 'en'
});
const response = await fetch(`${BASE_URL}/zipcodes/state?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
zipcodes.value = await response.json();
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
});
</script>
<template>
<div>
<h2>Search Postal Codes by State</h2>
<select v-model="selectedState">
<option value="">Select a state...</option>
<option v-for="state in states" :key="state" :value="state">
{{ state }}
</option>
</select>
<div v-if="loading">Loading postal codes...</div>
<div v-else-if="error" style="color: red;">Error: {{ error }}</div>
<div v-else-if="postalCodes.length > 0">
<h3>{{ zipcodes[0].name }}</h3>
<p>Total postal codes: {{ postalCodes.length }}</p>
<div style="max-height: 200px; overflow: auto;">
<span
v-for="code in postalCodes.slice(0, 100)"
:key="code"
style="margin: 2px; display: inline-block;"
>
{{ code }}
</span>
<span v-if="postalCodes.length > 100">
...and {{ postalCodes.length - 100 }} more
</span>
</div>
</div>
</div>
</template>
// zipcode.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
interface StateZipcode {
id: string;
name: string;
postal_code: string[];
}
@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) {}
getZipcodesByState(
state: string,
limitToken: number = 1000
): Observable<StateZipcode[]> {
const params = new HttpParams()
.set('apikey', this.API_KEY)
.set('state', state)
.set('lang', 'en')
.set('limitToken', limitToken.toString());
return this.http.get<StateZipcode[]>(
`${this.BASE_URL}/zipcodes/state`,
{ params }
);
}
}
// state-zipcode-search.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ZipcodeService } from './zipcode.service';
@Component({
selector: 'app-state-zipcode-search',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<div>
<h2>Search Postal Codes by State</h2>
<select [(ngModel)]="selectedState" (ngModelChange)="onStateChange()">
<option value="">Select a state...</option>
<option *ngFor="let state of states" [value]="state">
{{ state }}
</option>
</select>
<div *ngIf="loading">Loading postal codes...</div>
<div *ngIf="error" style="color: red;">Error: {{ error }}</div>
<div *ngIf="zipcodes.length > 0 && !loading">
<h3>{{ zipcodes[0].name }}</h3>
<p>Total postal codes: {{ zipcodes[0].postal_code.length }}</p>
<div style="max-height: 200px; overflow: auto;">
<span
*ngFor="let code of zipcodes[0].postal_code.slice(0, 100)"
style="margin: 2px; display: inline-block;"
>
{{ code }}
</span>
<span *ngIf="zipcodes[0].postal_code.length > 100">
...and {{ zipcodes[0].postal_code.length - 100 }} more
</span>
</div>
</div>
</div>
`
})
export class StateZipcodeSearchComponent {
states = ['California', 'Texas', 'New York', 'Florida'];
selectedState = '';
zipcodes: any[] = [];
loading = false;
error: string | null = null;
constructor(private zipcodeService: ZipcodeService) {}
onStateChange() {
if (!this.selectedState) {
this.zipcodes = [];
return;
}
this.loading = true;
this.error = null;
this.zipcodeService.getZipcodesByState(this.selectedState).subscribe({
next: (data) => {
this.zipcodes = data;
this.loading = false;
},
error: (err) => {
this.error = err.message;
this.loading = false;
}
});
}
}
<?php
$apiKey = 'your-api-key';
$state = 'California'; // Can be state name or ID
$url = "https://api.countrydataapi.com/v1/zipcodes/state?" . http_build_query([
'apikey' => $apiKey,
'state' => $state,
'lang' => 'en',
'limitToken' => 1000
]);
// 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);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
die("cURL Error: {$curlError}");
}
if ($httpCode === 200) {
$data = json_decode($response, true);
if (!empty($data)) {
$stateData = $data[0];
echo "State: " . $stateData['name'] . "\n";
echo "Total Postal Codes: " . count($stateData['postal_code']) . "\n";
echo "Sample Codes: " . implode(', ', array_slice($stateData['postal_code'], 0, 10)) . "...\n";
} else {
echo "No postal codes found for state: {$state}\n";
}
} else {
echo "Error: HTTP {$httpCode}\n";
$error = json_decode($response, true);
echo "Message: " . ($error['error']['message'] ?? 'Unknown error') . "\n";
}
// Function wrapper for reusability
function getZipcodesByState($apiKey, $state, $lang = 'en', $limitToken = 1000) {
$url = "https://api.countrydataapi.com/v1/zipcodes/state?" . http_build_query([
'apikey' => $apiKey,
'state' => $state,
'lang' => $lang,
'limitToken' => $limitToken
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API Error: HTTP {$httpCode}");
}
return json_decode($response, true);
}
// Usage
try {
$zipcodes = getZipcodesByState($apiKey, 'Texas');
print_r($zipcodes);
} catch (Exception $e) {
echo $e->getMessage();
}
?>
import requests
from typing import List, Dict, Any, Optional
API_KEY = 'your-api-key'
BASE_URL = 'https://api.countrydataapi.com/v1'
def get_zipcodes_by_state(
state: str,
lang: str = 'en',
limit_token: int = 1000
) -> List[Dict[str, Any]]:
"""
Fetch postal codes for a specific state.
Args:
state: State name or ID
lang: Language code for response
limit_token: Maximum tokens to spend on this request
Returns:
List containing state data with postal codes
"""
try:
response = requests.get(
f'{BASE_URL}/zipcodes/state',
params={
'apikey': API_KEY,
'state': state,
'lang': lang,
'limitToken': limit_token
},
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f'HTTP Error: {e.response.status_code}')
print(f'Response: {e.response.text}')
raise
except requests.exceptions.RequestException as e:
print(f'Request Error: {e}')
raise
# Usage examples
if __name__ == '__main__':
# Search by state name
california_data = get_zipcodes_by_state('California')
if california_data:
state = california_data[0]
print(f"State: {state['name']}")
print(f"Total postal codes: {len(state['postal_code'])}")
print(f"Sample codes: {', '.join(state['postal_code'][:10])}...")
# Search by state ID
texas_data = get_zipcodes_by_state('66c7a6cbe4bda21f4ab11f55')
if texas_data:
print(f"\nTexas has {len(texas_data[0]['postal_code'])} postal codes")
# Async version using aiohttp
import aiohttp
import asyncio
async def get_zipcodes_by_state_async(
state: str,
lang: str = 'en'
) -> List[Dict[str, Any]]:
"""Async version using aiohttp"""
async with aiohttp.ClientSession() as session:
async with session.get(
f'{BASE_URL}/zipcodes/state',
params={
'apikey': API_KEY,
'state': state,
'lang': lang
}
) as response:
if response.status != 200:
text = await response.text()
raise Exception(f'API Error: {response.status} - {text}')
return await response.json()
# Run async
# data = asyncio.run(get_zipcodes_by_state_async('California'))
Always implement proper error handling:
async function getZipcodesWithErrorHandling(state) {
try {
const response = await fetch(
`https://api.countrydataapi.com/v1/zipcodes/state?apikey=your-api-key&state=${encodeURIComponent(state)}`
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
switch (response.status) {
case 400:
throw new Error(errorData.error?.message || 'Invalid request parameters');
case 401:
throw new Error('Invalid API key');
case 402:
throw new Error('Insufficient tokens. Please upgrade your plan.');
case 404:
throw new Error(`State "${state}" not found`);
case 429:
throw new Error('Rate limit exceeded. Please try again later.');
default:
throw new Error(`HTTP error! status: ${response.status}`);
}
}
const data = await response.json();
if (!Array.isArray(data) || data.length === 0) {
console.warn(`No postal codes found for state: ${state}`);
return [];
}
return data;
} catch (error) {
console.error('Failed to fetch state zipcodes:', error.message);
throw error;
}
}
| Error Code | Description | Solution |
|---|---|---|
INVALID_API_KEY |
API key is invalid | Check your API key in account dashboard |
MISSING_PARAMETER |
state parameter missing |
Include state name or ID in request |
STATE_NOT_FOUND |
State does not exist | Verify state name or use valid state ID |
QUOTA_EXCEEDED |
Daily token limit reached | Upgrade plan or wait for reset |
async function validateZipcode(state, zipcode) {
const data = await getZipcodesByState(state);
if (data.length === 0) {
return { valid: false, message: 'State not found' };
}
const validZipcodes = data[0].postal_code;
const isValid = validZipcodes.includes(zipcode);
return {
valid: isValid,
message: isValid ? 'Valid postal code' : 'Invalid postal code for this state'
};
}
// Usage
const result = await validateZipcode('California', '90210');
console.log(result); // { valid: true, message: 'Valid postal code' }
async function getZipcodeAutocomplete(state, query) {
const data = await getZipcodesByState(state);
if (data.length === 0) return [];
return data[0].postal_code.filter(code =>
code.startsWith(query)
).slice(0, 10);
}
// Usage
const suggestions = await getZipcodeAutocomplete('California', '902');
console.log(suggestions); // ['90201', '90202', '90210', ...]
Check our pricing page for more details.