API Reference

Documentation for the PostalDataPI API endpoints. Built in the USA, serving 240+ countries and territories worldwide.

Looking for the full developer docs?

This page is a quick reference. For tutorials, integration patterns, error-handling guides, country codes, and SDK deep-dives, visit docs.postaldatapi.com →

Base URL

https://postaldatapi.com/api

SDKs

Get started quickly with official client libraries:

Python

pip install postaldatapi
from postaldatapi import PostalDataPI

client = PostalDataPI(api_key="YOUR_API_KEY")
result = client.lookup("90210")

Node.js

npm install postaldatapi
import { PostalDataPI } from "postaldatapi";

const client = new PostalDataPI({ apiKey: "YOUR_API_KEY" });
const result = await client.lookup("90210");

Authentication

Every request must include your API key in the apiKey field of the JSON request body.

Country Parameter

All endpoints accept an optional country parameter — an ISO 3166-1 alpha-2 code (e.g., "US", "DE", "GB", "JP"). Defaults to "US" if omitted.

Endpoints

Standard response envelope

Every successful response also carries balance (USD remaining), performance (per-stage timings), and rateLimit (window status). Examples below show endpoint-specific fields only — assume the envelope is always present.

POST /api/lookup

Returns city, state/region, and coordinates for a postal code.

Request (US)

{
  "zipcode": "90210",
  "apiKey": "YOUR_API_KEY"
}

Request (Germany)

{
  "zipcode": "10115",
  "country": "DE",
  "apiKey": "YOUR_API_KEY"
}

Response

{
  "city": "Beverly Hills",
  "state": "California",
  "ST": "CA",
  "latitude": 34.1031,
  "longitude": -118.4163
}

Errors: 400 (missing/invalid), 401 (unauthorized), 404 (not found), 429 (rate limit)

POST /api/city

Returns a list of postal codes for a given city. For US queries, state or ST is required.

Request (US)

{
  "city": "Beverly Hills",
  "ST": "CA",
  "apiKey": "YOUR_API_KEY"
}

Request (Germany)

{
  "city": "Berlin",
  "country": "DE",
  "apiKey": "YOUR_API_KEY"
}

Response

{
  "zipcodes": ["90209", "90210", "90211", "90212", "90213"]
}

Errors: 400 (missing/invalid), 404 (not found)

POST /api/validate

Checks if a postal code exists. Returns { "valid": true } or { "valid": false }.

Request (US)

{
  "zipcode": "90210",
  "apiKey": "YOUR_API_KEY"
}

Request (UK)

{
  "zipcode": "SW1A",
  "country": "GB",
  "apiKey": "YOUR_API_KEY"
}

Response

{
  "valid": true,
  "zipcode": "90210"
}

Errors: 400 (missing/invalid), 401 (unauthorized)

POST /api/validate-bulk

Validate up to 1,000 postal codes in a single request. Mixed countries supported. Same flat per-record price as /api/validate ($0.000028 per record) — no bulk discount or premium. Per-record errors are reported in results, not as request-level failures.

Field naming: this endpoint uses modern postalCode / countryCode. The single-record endpoints above preserve the legacy zipcode / country naming.

Request (mixed countries)

{
  "apiKey": "YOUR_API_KEY",
  "records": [
    { "postalCode": "90210", "countryCode": "US" },
    { "postalCode": "SW1A 1AA", "countryCode": "GB" },
    { "postalCode": "10115", "countryCode": "DE" }
  ]
}

Response

{
  "results": [
    { "postalCode": "90210",    "countryCode": "US", "valid": true,  "normalized": "90210", "reason": null },
    { "postalCode": "SW1A 1AA", "countryCode": "GB", "valid": true,  "normalized": "SW1A",  "reason": null },
    { "postalCode": "10115",    "countryCode": "DE", "valid": true,  "normalized": "10115", "reason": null }
  ],
  "totalCost": 0.000084
}

Per-record reason: null when valid, otherwise "not_found", "invalid_format", or "unknown_country". normalized is the canonical key when valid (e.g. SW1A for GB outcode-only datasets), null when invalid.

Limits: max 1,000 records per request. Errors: 400 (empty records, >1000 records, malformed body), 401 (unauthorized), 402 (insufficient balance for full batch — entire request rejected, no partial billing), 429 (rate limit would be exceeded by N records).

POST /api/metazip

Returns all available metadata for a postal code: coordinates, timezone, elevation, and country-specific administrative-region fields. The exact set of fields varies by country and data source — every populated field for that record is returned.

Request

{
  "zipcode": "90210",
  "apiKey": "YOUR_API_KEY"
}

Response (US)

{
  "meta": {
    "zipcode": "90210",
    "city": "Beverly Hills",
    "state": "California",
    "stateAbbrev": "CA",
    "county": "Los Angeles County",
    "latitude": 34.1031,
    "longitude": -118.4163,
    "timezone": "America/Los_Angeles"
  }
}

Response (Mexico — rich 18-field example)

{
  "meta": {
    "postalCode": "06000",
    "country": "MX",
    "placeName": "Centro (Área 1)",
    "latitude": 19.4364,
    "longitude": -99.1553,
    "adminLevel1": "Ciudad de México",
    "adminLevel2": "Cuauhtémoc",
    "timezone": "America/Mexico_City",
    "admin_name1": "Distrito Federal",
    "admin_code1": "09",
    "admin_name2": "Cuauhtémoc",
    "admin_code2": "015",
    "admin_name3": "Ciudad de México",
    "admin_code3": "06",
    "elevation": 2239,
    "state": "Ciudad de México",
    "municipality": "Cuauhtémoc",
    "city": "Ciudad de México"
  }
}

Response (Germany — typical 12-field non-US)

{
  "meta": {
    "postalCode": "10115",
    "country": "DE",
    "placeName": "Berlin",
    "latitude": 52.5323,
    "longitude": 13.3846,
    "timezone": "Europe/Berlin",
    "admin_name1": "Berlin",
    "admin_code1": "BE",
    "admin_code2": "00",
    "admin_name3": "Berlin, Stadt",
    "admin_code3": "11000",
    "elevation": 34
  }
}

Response (Japan)

{
  "meta": {
    "postalCode": "1000001",
    "country": "JP",
    "placeName": "Chiyoda",
    "latitude": 35.6841,
    "longitude": 139.7521,
    "timezone": "Asia/Tokyo",
    "admin_name1": "Tokyo To",
    "admin_code1": "40",
    "admin_name2": "Chiyoda Ku",
    "admin_code2": "1864529",
    "elevation": 32
  }
}

Field count varies by country. Mexico and a handful of other rich-schema countries currently return up to 18 fields per postal code. Most countries return 10-13. PostalDataPI returns every populated field for that record — missing fields are simply omitted, not nulled.

US fields: zipcode, city, state, stateAbbrev, county, timezone, latitude, longitude.

Common non-US fields: postalCode, country, placeName, latitude, longitude, timezone, elevation, plus the multi-level snake_case admin schema (admin_name1/admin_code1, admin_name2/admin_code2, admin_name3/admin_code3).

Additional rich-schema fields (Mexico, Brazil, etc.): adminLevel1, adminLevel2 (camelCase aliases), state, municipality, city.

Errors: 400 (missing/invalid), 404 (not found)

POST /api/aboutapi

Returns API version, coverage, and usage information. A lightweight self-describing endpoint suitable for health checks and discovery.

Request

{
  "apiKey": "YOUR_API_KEY"
}

Response

{
  "About": "PostalDataPI provides postal code lookup, validation, city search, and metadata endpoints for 240+ countries and territories.",
  "version": "2.0.0",
  "coverage": "240+ countries and territories with sub-5ms response times. US ZIP codes, UK postcodes, German PLZ, and more.",
  "usage": "See docs.postaldatapi.com for authentication, rate limits, and endpoint usage."
}

Errors: 400 (missing apiKey), 401 (invalid apiKey)

Error Codes

StatusMeaning
400Missing or invalid parameters
401Invalid API key
402Insufficient balance
404Postal code or city not found
429Rate limit exceeded
500Internal server error
API Reference | PostalDataPI