Try it Live — No Signup

API Documentation

Complete US & Canadian postal code data with optional demographic, census, and geographic enrichments.

https://api.zip-codes.com
Download Postman Collection Download OpenAPI Spec

Introduction

The ZIP Codes API v2 provides comprehensive postal code data for the United States and Canada. Look up ZIP codes, calculate distances, search by radius, and enrich results with census demographics, political districts, school districts, and more.

All API endpoints live under the /v2/ prefix. Responses use a consistent JSON envelope with built-in error handling and credit tracking.

Key Features

  • US ZIP & ZIP+4 lookups with demographics, delivery points, and business data
  • Canadian FSA & postal code lookups with province-level data
  • Radius search with cross-border support (US + Canada)
  • Distance calculation between any combination of ZIP codes, FSAs, postal codes, and coordinates
  • 11 opt-in enrichments including ACS demographics, census boundaries, political districts, school districts, timezone, and more
  • Batch processing up to 100 items per request
Want to try it live? Use our Interactive Playground to make API calls directly from your browser.

Authentication

All API requests require a valid API key. You can pass it in two ways:

Option 1: HTTP Header (recommended)

Request Header
X-Api-Key: your_api_key

Option 2: Query Parameter

Query String
GET /v2/quick-zip?code=90210&key=your_api_key
The header method is recommended for production use as it keeps your API key out of server logs and browser history.

Request & Response Format

AspectDetails
Content-TypeAll responses are application/json; charset=utf-8. POST requests must send Content-Type: application/json.
POST BodyNon-batch endpoints accept GET query parameters or POST with a JSON body containing the same parameter names. Batch endpoints are POST-only.
CompressionThe API supports Brotli and Gzip response compression. Send Accept-Encoding: br or Accept-Encoding: gzip for smaller payloads.
CachingAll API responses include Cache-Control: no-store. Implement your own caching layer if needed.
CORSThe API allows cross-origin requests from all origins by default. Account holders can configure allowed CORS origins per API key through the API Admin panel. IP whitelisting and domain restrictions are planned.
Request IDEvery response includes an X-Request-Id header and meta.request_id field. Include this in support requests for faster troubleshooting.
include ParameterControls what data appears in the response. On /zip and /radius, it adds enrichment data (e.g. include=timezone,census). On /suggest, it filters which entity types are returned (e.g. include=zip,place) — all types are included by default.

Quick Start

Make your first API call in seconds:

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/quick-zip?code=90210"
Python
import requests

resp = requests.get(
    "https://api.zip-codes.com/v2/quick-zip",
    params={"code": "90210"},
    headers={"X-Api-Key": "YOUR_API_KEY"}
)
data = resp.json()
print(data["results"][0]["city"])  # Beverly Hills
JavaScript
const resp = await fetch(
  "https://api.zip-codes.com/v2/quick-zip?code=90210",
  { headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const data = await resp.json();
console.log(data.results[0].city); // Beverly Hills

Your Dashboard

The API Portal dashboard gives you full control over your account:

  • API Keys — Create, rotate, and configure keys with per-key IP whitelisting and CORS origin restrictions.
  • Usage Analytics — Daily and monthly usage charts, per-key breakdowns, and CSV export for your records.
  • Billing — Manage your subscription tier, purchase credit packs, and download invoices.
  • Settings — Update account details and notification preferences.

Free tier accounts start with 2,500 credits/day. Sign in to get started →

Response Format

Every API response follows a consistent envelope structure:

Response Envelope
{
  "success": true,
  "request": { "code": "90210", "include": ["timezone"] },
  "results": ["..."],
  "error": null,
  "meta": {
    "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "version": "2.0.0",
    "timing_ms": 45,
    "credits": { "used": 2, "remaining": 74998, "breakdown": { "base": 1, "enrichments": { "timezone": 1 } } },
    "notices": []
  }
}
FieldTypeDescription
successbooleanWhether the request succeeded
requestobjectEcho of parsed request parameters
resultsarrayArray of result objects (varies by endpoint)
errorobject|nullnull on success; {"code": "...", "message": "..."} on failure
meta.request_idstringUnique request identifier (also in X-Request-Id header)
meta.versionstringAPI version (currently "2.0.0")
meta.timing_msnumberTotal processing time in milliseconds
meta.creditsobjectCredit usage breakdown for this request
meta.noticesarrayInformational messages (see Notices)

Notices

The meta.notices array contains non-error informational messages about request processing:

CodeDescription
INPUT_NORMALIZEDInput was reformatted (e.g., whitespace trimmed, case corrected)
FALLBACK_USEDCanadian postal code not found; FSA-level data returned instead
ENRICHMENT_UNAVAILABLERequested enrichment not available for this country (no credit charged)
COORDINATES_USEDLatitude/longitude coordinates used as the search center
REVERSE_GEOCODECoordinate was reverse-geocoded to a postal code
BATCH_DUPLICATES_DETECTEDDuplicate items in batch were deduplicated

Address Matching BETA

Parse and validate a raw US street address against USPS ZIP+4 delivery-point data. Returns the standardized address, ZIP+4 code, address components, and delivery metadata. Handles partial input — city and state are optional when unambiguous.

GET /v2/address

Parameters

ParameterTypeRequiredDescription
addressstringRequiredRaw street address to match. Accepts full or partial addresses (e.g., 1600 Pennsylvania Ave NW, Washington DC 20500 or 350 5th Ave, New York).
Flexible input: The parser handles a wide range of address formats. You can omit ZIP code, state, or both — the engine resolves the address from city and street alone when unambiguous. However, providing more detail improves match accuracy.

Credit Cost

Fixed 1 credit per request, whether or not a match is found.

Calculate your cost

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/address?address=350+5th+Ave%2C+New+York+NY+10118"
Open in Playground

Example Response

Response
{
  "success": true,
  "request": { "address": "350 5th Ave, New York NY 10118" },
  "results": [{
    "input": "350 5th Ave, New York NY 10118",
    "success": true,
    "matches": [{
      "formatted_address": "350 5TH AVE, NEW YORK, NY 10118-0110",
      "address_line1": "350 5TH AVE",
      "address_line2": "NEW YORK, NY 10118-0110",
      "address_components": {
        "number": "350",
        "pre_directional": null,
        "street": "5TH",
        "street_pre_type": null,
        "suffix": "AVE",
        "post_directional": null,
        "secondary_type": null,
        "secondary_number": null,
        "city": "NEW YORK",
        "state": "NY",
        "zip": "10118",
        "plus4": "0110",
        "country": "US"
      },
      "match_info": {
        "confidence": "high",
        "match_path": "zip_street",
        "candidates_evaluated": 4
      },
      "details": {
        "record_type": "H",
        "record_type_description": "Highrise",
        "carrier_route": "C049",
        "county_fips": "36061",
        "congressional_district": "12",
        "building_name": "EMPIRE STATE BUILDING",
        "government_building": false
      }
    }]
  }],
  "meta": { "version": "2.0.0", "timing_ms": 3, "credits": { "used": 1, "remaining": 74999 }, "notices": [] }
}

Result Fields

FieldTypeDescription
inputstringThe raw address string you submitted
successbooleantrue if at least one match was found
matchesarrayArray of matched addresses (typically 1)

Match Object

FieldTypeDescription
formatted_addressstringUSPS-standardized full address with ZIP+4
address_line1stringStreet line (number, directional, street, suffix, secondary)
address_line2stringLast line (city, state, ZIP+4)
address_componentsobjectParsed address components (see table below)
match_infoobjectMatch quality metadata
detailsobjectUSPS delivery-point metadata

Address Components

FieldTypeDescription
numberstring|nullHouse/building number
pre_directionalstring|nullPrefix directional (e.g., N, SW)
streetstring|nullStreet name
street_pre_typestring|nullStreet pre-type (e.g., AVE in AVE OF THE AMERICAS)
suffixstring|nullStreet suffix (e.g., ST, AVE, BLVD)
post_directionalstring|nullPostfix directional (e.g., NW)
secondary_typestring|nullSecondary address type (e.g., APT, STE, UNIT)
secondary_numberstring|nullSecondary address number (e.g., 4B, 200)
citystringMatched city name
statestringTwo-letter state abbreviation
zipstring5-digit ZIP code
plus4string4-digit ZIP+4 suffix
countrystringCountry code (US)

Match Info

FieldTypeDescription
confidencestringMatch confidence level: high, medium, or low
match_pathstringInternal resolution path (e.g., zip_street, city_state_street, city_only)
candidates_evaluatedintegerNumber of ZIP+4 candidates considered during matching

Details (USPS Metadata)

FieldTypeDescription
record_typestring|nullUSPS record type code: S (Street), H (Highrise), P (PO Box), F (Firm), G (General Delivery), R (Rural Route)
record_type_descriptionstring|nullHuman-readable record type name
carrier_routestring|nullUSPS carrier route code
county_fipsstring|null5-digit county FIPS code
congressional_districtstring|nullCongressional district number
building_namestring|nullBuilding or firm name (when available)
government_buildingbooleanWhether this is a government building
No match? When no match is found, success is false and matches is an empty array. You are still charged 1 credit. Common reasons: misspelled street, address outside USPS delivery network, or a very new development not yet in the postal database.

Geographic Suggest

Typeahead search for geographic entities. Returns ZIP codes, cities/places, counties, metro areas (CBSAs), states/provinces, and Canadian FSAs matching a prefix query. Results include authoritative identifiers (FIPS, GEOID), coordinates, bounding boxes, and population data.

GET /v2/suggest
POST /v2/suggest

Parameters

ParameterTypeRequiredDescription
qstringRequiredSearch query (minimum 1 character). Case-insensitive.
limitintegerNoMax results to return. Default: 10. Free tier: max 15. Paid tiers: max 500.
includestringNoComma-separated entity types to include: zip, place, county, cbsa, fsa, state. Default: all types. Unlike /zip and /radius where include adds enrichment data, here it filters which entity types are returned.
statestringNoUS state or CA province abbreviation to filter results (e.g., CA, ON).
countrystringNoFilter by country: US or CA. Default: both.
proximitystringNoGeographic bias for ranking. Accepts multiple formats: lat,lon (coordinates), auto (caller IP), IP address, 5-digit ZIP, 3-char FSA, or 2-letter state/province. Nearby results rank higher (soft bias, not a filter).
Proximity bias uses source-dependent weighting. Direct coordinates get 55% proximity weight; ZIP/FSA centroids get 50%; state centroids get 30% (gentle nudge). IP-based proximity (auto or explicit IP) resolves coordinates for the response echo but does not currently influence scoring. Numeric queries (ZIP prefixes) now benefit from proximity bias.

Entity Types

TypeCountDescriptionType-Specific Fields
zip~42KUS ZIP codescity, classification
place~30KUS Census places (cities, towns, CDPs)fips, geoid, associated_zips
county~3.2KUS counties (includes parishes, boroughs)fips, geoid
cbsa~1KMetropolitan & micropolitan statistical areascbsa_code, geoid, metro_micro
fsa~1.6KCanadian Forward Sortation Areascity, province, postal_code_count
state~67US states/territories & CA provinces (with abbreviation aliases)(none)

Credit Cost

Limit RangeCreditsAvailable To
1–151All tiers (including free)
16–502Paid only
51–1503Paid only
151–5005Paid only

Billing based on requested limit, not results returned. Free tier requests above 15 are clamped with a FREE_TIER_LIMIT_CAPPED notice. Validation errors (missing q, invalid include) cost 0 credits.

Calculate your cost

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/suggest?q=spring&limit=3"

Example: With proximity bias

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/suggest?q=spring&proximity=40.7128,-74.006&limit=3"

Example: Filtered by type and state

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/suggest?q=cook&include=county&state=IL"

Example Response

Response
{
  "success": true,
  "request": { "q": "spring", "limit": 3 },
  "results": [{ "success": true, "data": { "total_matched": 127, "matches": [
    { "type": "place", "name": "Springfield", "state": "MO", "country": "US", "population": 169176, "location": { "lat": 37.209, "lon": -93.2923 } },
    { "type": "zip", "name": "77373", "state": "TX", "country": "US", "city": "Spring", "population": 54298 },
    { "type": "cbsa", "name": "Springfield, MO", "state": "MO", "cbsa_code": "44180", "population": 478315 }
  ] } }],
  "meta": { "version": "2.0.0", "timing_ms": 2, "credits": { "used": 1, "remaining": 74999 }, "notices": [] }
}

Match Object Fields

FieldTypeDescription
typestringEntity type: zip, place, county, cbsa, fsa, state
namestringDisplay name (ZIP code number, place name, county name, etc.)
statestringUS state abbreviation (or province for FSA)
countrystringUS or CA
populationintegerPopulation (ACS estimate for US, Census for CA)
locationobject{ lat, lon } — centroid coordinates
bboxobject{ min_lat, max_lat, min_lon, max_lon } — bounding box (null for ZIPs)
fipsstringFIPS code (places, counties only)
geoidstringCensus GEOID (places, counties, CBSAs)
associated_zipsarrayZIP codes within a place (places only)
cbsa_codestringCBSA code (CBSAs only)
metro_microstringMetropolitan or Micropolitan (CBSAs only)
citystringPrimary city name (ZIPs and FSAs only)
classificationstringZIP type: Standard, PO Box, Military, Unique (ZIPs only)
provincestringCA province abbreviation (FSAs and CA states only)

Quick ZIP Lookup

Fast postal code lookup returning basic location data with optional timezone enrichment. Supports US ZIP codes (5-digit), US ZIP+4 codes, Canadian FSAs (3-character), full Canadian postal codes (6-character), and latitude/longitude coordinates for reverse geocoding.

GET /v2/quick-zip
POST /v2/quick-zip

Parameters

ParameterTypeRequiredDescription
codestringRequiredZIP code, ZIP+4, FSA, Canadian postal code, or coordinates (lat,lon)
includestringOptionalComma-separated enrichment flags. Only timezone is supported on this endpoint.

Supported Code Types

TypeFormatExampleCountryBase Cost
ZIP5 digits90210US1 credit
ZIP+49 digits (with or without dash)90210-1234US2 credits
FSA3 alphanumeric (A1A)M5VCA1 credit
Postal6 alphanumeric (A1A1A1)M5V2H1CA2 credits
Coordinateslat,lon (decimal degrees)34.1030,-118.4105US + CA2 credits
Coordinate credits perform a reverse geocode to find the nearest postal code. The extra credit cost reflects the spatial search required. Pass coordinates directly in the code parameter as lat,lon.

Available Enrichments

FlagAdds to ResponseCostAvailability
timezoneIANA timezone name, UTC offsets, DST abbreviations+1US + CA

Credit Cost

ZIP and FSA = 1 base credit. ZIP+4 and Postal Code = 2 base credits. Coordinates add +1 to the resolved code’s cost. Each include flag adds +1 credit.

Calculate your cost

Response Fields

FieldTypeDescription
countrystring"US" or "CA"
codestringThe postal code
code_typestringZIP, FSA, or Postal
parent_codestring | nullParent 5-digit ZIP or FSA (null for base codes)
citystringPrimary city name
state / state_namestringState/province abbreviation and full name
state_fipsstring | null2-digit state FIPS code (US only)
county / county_fipsstring | nullCounty name and FIPS code (US only)
multi_countyboolean | nullWhether ZIP spans multiple counties (US only)
classificationstring | nullZIP type code (US only)
classification_namestring | nullZIP type name: General, PO Box, Military, Unique
municipalitystring | nullMunicipality name (where applicable)
locationobject{"lat": ..., "lon": ...}
detailobject | nullStreet-level detail for ZIP+4 / CA postal codes
timezoneobject | nullPresent when include=timezone
Canadian postal fallback: If a full Canadian postal code is not found, the API automatically falls back to FSA-level data and includes a FALLBACK_USED notice. No additional credit is charged.

ZIP+4 Detail Fields

When a ZIP+4 code is looked up, the detail object is populated with delivery-point data:

FieldTypeDescription
zip4stringThe 4-digit ZIP+4 suffix
record_typestringAddress record type (e.g., S = Street, P = PO Box, H = Highrise, F = Firm)
carrier_routestringUSPS carrier route code

Street Detail Fields

Street-level address range information within the detail.street object:

FieldTypeDescription
addr_lowstringLow end of primary address range
addr_highstringHigh end of primary address range
prefixstringStreet name prefix directional (e.g., N, SW)
namestringStreet name
suffixstringStreet suffix (e.g., St, Ave, Blvd)
postfixstringStreet name postfix directional
odd_evenstringAddress range parity: O (odd), E (even), B (both)
sec_addr_abbrstringSecondary address abbreviation (e.g., APT, STE, UNIT)
sec_addr_lowstringLow end of secondary address range
sec_addr_highstringHigh end of secondary address range
sec_addr_odd_evenstringSecondary address range parity: O, E, or B
building_namestringBuilding or firm name
addressstringFormatted full address line

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/quick-zip?code=90210&include=timezone"
Open in Playground

Example Response

Response — US ZIP
{
  "success": true,
  "request": { "code": "90210", "include": ["timezone"] },
  "results": [{
    "code": "90210", "code_type": "ZIP", "country": "US",
    "city": "Beverly Hills", "state": "CA", "state_name": "California",
    "county": "Los Angeles", "county_fips": "06037",
    "location": { "lat": 34.103131, "lon": -118.416253 },
    "timezone": { "iana_name": "America/Los_Angeles", "name": "Pacific", "abbreviation": "PST", "utc_offset": -8, "observes_dst": true }
  }],
  "meta": { "version": "2.0.0", "timing_ms": 23, "credits": { "used": 2, "remaining": 74998 }, "notices": [] }
}
Response — Canadian FSA
{
  "success": true,
  "request": { "code": "M5V", "include": ["timezone"] },
  "results": [{
    "code": "M5V", "code_type": "FSA", "country": "CA",
    "city": "Toronto", "state": "ON", "state_name": "Ontario",
    "location": { "lat": 43.638388, "lon": -79.40428 },
    "timezone": { "iana_name": "America/Toronto", "name": "Eastern", "utc_offset": -5, "observes_dst": true }
  }],
  "meta": { "version": "2.0.0", "timing_ms": 15, "credits": { "used": 2, "remaining": 74998 }, "notices": [] }
}
Response — Not Found
{
  "success": true,
  "request": { "code": "99999", "include": [] },
  "results": [],
  "error": { "code": "NOT_FOUND_ZIP", "message": "US ZIP code 99999 not found." },
  "meta": { "version": "2.0.0", "timing_ms": 8, "credits": { "used": 1, "remaining": 74999 }, "notices": [] }
}

ZIP Code Details

Comprehensive postal code lookup with rich data including demographics, business statistics, delivery points, and up to 11 optional enrichments. Returns detailed information for US ZIP codes and Canadian postal codes.

GET /v2/zip
POST /v2/zip

Parameters

ParameterTypeRequiredDescription
codestringRequiredUS ZIP code, Canadian postal code, or coordinates (lat,lon)
includestringOptionalComma-separated enrichment flags (see Data Enrichments)

Available Enrichments

FlagAdds to ResponseCostAvailability
timezoneIANA timezone name, UTC offsets, DST info. Multi-zone ZIPs return array with % coverage.+1US + CA
censusCounty, county subdivision, place, tract, block group, CBSA overlaps with % coverage+1US + CA
cdCongressional districts (US) / federal electoral districts (CA) with % coverage+1US + CA
state_legState senate (upper) and house (lower) legislative district overlaps+1US only
school_districtSchool districts (NCES) with office address, grade range, locale, area overlap+1US only
acs_demographicPopulation, sex, age distribution, race, ethnicity, citizenship (DP05 — 108 fields)+1US only
acs_socialHouseholds, education, language, ancestry, marital status, computers/internet (DP02 — 154 fields)+1US only
acs_economicEmployment, income, poverty, occupation, industry, health insurance, commute (DP03 — 137 fields)+1US only
acs_housingHousing units, occupancy, tenure, home value, rent, utilities, structure age (DP04 — 143 fields)+1US only
acs_{profile}_{YYYY}Historical ACS for any year from 2011–2024 (14 years). Append _YYYY to any ACS flag (e.g., acs_housing_2022). 528 fields in recent years, 394 in earliest. See ACS Data.+1 eachUS only
demographicsPopulation, race, age, households, income, and business establishment counts+1US only
medicareMedicare CBSA code/name/type, rating area ID, SSA state/county code+1US only
Canadian availability: Requesting US-only enrichments for Canadian codes returns null with an ENRICHMENT_UNAVAILABLE notice. No credit is charged.

Credit Cost

ZIP and FSA = 1 base credit. ZIP+4 and Postal Code = 2 base credits. Coordinates add +1 to the resolved code’s cost. Each include flag adds +1 credit. Example: include=timezone,census,cd on a ZIP = 4 credits.

Calculate your cost

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/zip?code=90210&include=timezone,demographics"
Open in Playground

Example Response

Response — Base + Timezone + Demographics
{
  "success": true,
  "request": { "code": "90210", "include": ["timezone", "demographics"] },
  "results": [{
    "country": "US", "code": "90210", "code_type": "ZIP",
    "city": "Beverly Hills", "state": "CA", "state_name": "California",
    "county": "Los Angeles", "county_fips": "06037",
    "location": { "lat": 34.102823, "lon": -118.414661 },
    "area_codes": ["310", "323", "424", "738"],
    "elevation": { "ft": 719, "m": 219 },
    "metro": { "region": "West", "division": "Pacific", "msa": "31080", "msa_name": "Los Angeles-Long Beach-Anaheim, CA" },
    "zip_info": { "classification": "G", "classification_name": "General", "land_area_sq_mi": 10.9748, "delivery_points": { "total_active": 10634 } },
    "demographics": { "population": { "total": 21134 }, "households": { "median_income": 190382 } },
    "timezone": { "zones": [{ "iana_name": "America/Los_Angeles", "name": "Pacific", "utc_offset": -8, "pct_of_zip": 100.0 }] }
  }],
  "meta": { "version": "2.0.0", "timing_ms": 87, "credits": { "used": 3, "remaining": 74997 }, "notices": [] }
}

Base Fields (always included)

FieldTypeDescription
countrystring"US" or "CA"
codestringThe postal code
code_typestringZIP, FSA, or Postal
parent_codestring | nullParent 5-digit ZIP (for ZIP+4 queries) or parent FSA (for CA postal queries). null for base codes.
citystringPrimary city name
state / state_namestringState/province abbreviation and full name
state_fipsstring | null2-digit state FIPS code (US only)
county / county_fipsstringCounty name and FIPS code (US only)
multi_countyboolean | nullWhether the ZIP spans multiple counties (US only)
municipalitystring | nullMunicipality name (where applicable)
locationobject{"lat": 34.10, "lon": -118.41}
area_codesstring[] | nullTelephone area codes overlapping this postal code
elevationobject | null{"ft": 719, "m": 219} — centroid elevation in feet and meters
metroobject | nullMSA/CBSA statistical area info (US only, see sub-fields below)
zip_infoobject | nullZIP classification, facility code, land/water area, delivery points (US only)
postal_infoobject | nullCanadian postal metadata: record type, address type, FSA stats (CA only)
city_aliasesarray | nullAlternative city names with mailing status and intro date
detailobject | nullZIP+4 / CA postal street-level overlay (null for 5-digit ZIP / FSA queries)

metro Sub-Fields (US only)

FieldTypeDescription
regionstring | nullCensus region (e.g., West, Northeast)
divisionstring | nullCensus division (e.g., Pacific, Middle Atlantic)
csa / csa_namestring | nullCombined Statistical Area code and name
msa / msa_namestring | nullMetropolitan Statistical Area code and name
pmsa / pmsa_namestring | nullPrimary MSA code and name (where applicable)

postal_info Sub-Fields (CA only)

FieldTypeDescription
record_typestringRecord type code
address_typestringAddress type classification
fsastringParent FSA (3-character)
delivery_postal_codestringDelivery postal code
fsa_populationnumberFSA population
fsa_dwellingsnumberTotal dwellings in FSA
fsa_dwellings_occupiednumberOccupied dwellings in FSA
fsa_postal_code_countnumberNumber of postal codes in the FSA

Radius Search

Find all postal codes within a given radius of a center point. Specify the center via a single code parameter (ZIP, FSA, Postal Code, or lat,lon coordinates). Cross-border searches automatically include Canadian FSAs. Supports donut searches (min radius) and result limiting.

GET /v2/radius
POST /v2/radius

Parameters

ParameterTypeRequiredDescription
codestringRequiredCenter point — US ZIP (5-digit), ZIP+4, Canadian FSA, Canadian Postal Code, or lat,lon coordinates (e.g. 41.878,-87.629)
maxnumber or stringRequiredMaximum radius in miles (e.g. 25), or "auto" (density-based) / "auto-commute" (commute-behavior-based). Numeric limits: centroid up to 500, spatial up to 250. See Auto Radius.
minnumberOptionalMinimum radius in miles for donut search. Default: 0
includestringOptionalComma-separated enrichment flags (see table below)
modestringOptionalcentroid (default) — fast haversine on centroids, returns US ZIP + CA Postal. spatial — precise boundary analysis with pct_inside, returns US ZIP + CA FSA.
limitnumberOptionalMaximum results to return

Available Enrichments

FlagAdds to ResponseCostAvailability
timezoneIANA timezone name, UTC offsets, DST abbreviations for each result+1US + CA
acs_demographicPopulation-weighted aggregate: population, sex, age, race, ethnicity (DP05)+1US only
acs_socialPopulation-weighted aggregate: households, education, language, ancestry (DP02)+1US only
acs_economicPopulation-weighted aggregate: employment, income, poverty, commute (DP03)+1US only
acs_housingPopulation-weighted aggregate: occupancy, tenure, home value, rent (DP04)+1US only
acs_{profile}_{YYYY}Historical ACS aggregate for any year from 2011–2024. Append _YYYY to any ACS flag (e.g., acs_economic_2019). See ACS Data for year-by-year coverage.+1 eachUS only
Territory enrichments not available on /radius. Boundary enrichments (census, cd, state_leg, school_district) are currently only available on /v2/zip. If requested on /v2/radius, these flags are silently ignored — no credit is charged and an ENRICHMENT_UNAVAILABLE notice is included in the response. Use /v2/zip for territory enrichments on individual codes.
How Radius Credits Are Calculated

Every radius search starts with a base cost determined by how far you're searching — bigger search = more work for the server.

Each enrichment you add (timezone, demographics, etc.) multiplies that base cost, because the API has to gather that data for every result in your radius.

Think of it as: “search cost × number of data layers”

Quick worked example

Searching 25 miles with timezone: base cost is 1 (short search) × 2 data layers (the search itself + timezone) = 2 credits.

Credit Cost

Centroid mode (default, faster): Wider bands — the first 100 miles costs 1 base credit, the next 100 costs 2, and so on up to 500 miles.

Spatial mode (precise boundaries): Narrower bands — the first 50 miles costs 1 base credit, the next 50 costs 2, and so on up to 250 miles.

Each enrichment flag you add multiplies the base.

Calculate your cost

Auto Radius

Instead of specifying a numeric radius, pass max=auto or max=auto-commute to let the API calculate an appropriate search radius for the center point. This requires a ZIP, FSA, or Postal code center (not lat/lon coordinates).

ModeBased OnRangeBest For
autoPopulation density: 341 ÷ density0.423–150 milesGeneral-purpose searches scaled to urbanity
auto-commuteACS commuting patterns: mean travel time × transport-weighted speed × 1.53–100 milesService-area and labor-market analysis
Fallback: If commute data is unavailable for a ZIP (no ACS coverage), auto-commute automatically falls back to density-based auto and includes an AUTO_COMMUTE_FALLBACK notice in the response. The resolved radius appears in results[].search.max and the resolution method in results[].search.auto_mode ("density" or "commute").

Credit cost: Using auto-radius counts as one additional data layer in the cost calculation. Example: max=auto with include=timezone = base × 3 data layers = 3 credits for a short-range search.

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/radius?code=48226&max=25&include=timezone"
Open in Playground

Example Response

Response — 25mi Radius
{
  "success": true,
  "request": { "code": "48226", "max": 25, "min": 0, "include": ["timezone"], "mode": "centroid" },
  "results": [{ "search": { "center": { "code": "48226", "city": "DETROIT", "state": "MI", "location": { "lat": 42.33, "lon": -83.05 } }, "max": 25, "mode": "centroid" },
    "matches": [
      { "country": "US", "code": "48226", "city": "Detroit", "state": "MI", "distance_miles": 0.0, "timezone": { "iana_name": "America/Detroit" } },
      { "country": "US", "code": "48233", "city": "Detroit", "state": "MI", "distance_miles": 0.47 },
      { "country": "CA", "code": "N9A", "city": "Windsor", "state": "ON", "distance_miles": 1.6 }
    ] }],
  "meta": { "version": "2.0.0", "timing_ms": 312, "credits": { "used": 2, "remaining": 74998 }, "notices": [] }
}

Search Fields

FieldTypeDescription
search.center.codestringResolved center postal code
search.center.code_typestringZIP, FSA, or Postal
search.center.citystringCenter city name
search.center.statestringCenter state/province abbreviation
search.center.locationobject{"lat": ..., "lon": ...} — center coordinates
search.maxnumberResolved maximum radius in miles (numeric value, even when auto was requested)
search.minnumberMinimum radius in miles (donut inner ring)
search.modestring"centroid" or "spatial"
search.auto_modestring | null"density" when max=auto, "commute" when max=auto-commute, null for numeric radius

Match Fields

FieldTypeDescription
countrystring"US" or "CA"
codestringPostal code
code_typestringZIP, FSA, or Postal
citystringCity name
statestringState/province abbreviation
countystring | nullCounty name (US only)
county_fipsstring | nullCounty FIPS code (US only)
classificationstring | nullZIP type code (US only, e.g., G, P, M, U)
classification_namestring | nullZIP type name (e.g., General, PO Box, Military, Unique)
locationobject{"lat": ..., "lon": ...}
distance_milesnumberDistance from center point in miles
pct_insidenumber | nullPercentage of the postal code area inside the search radius (spatial mode only; null in centroid mode)
area_sq_minumber | nullTotal area of the postal code in square miles (null for point-only codes)

Distance Calculation

Calculate the great-circle distance between two points. Supports any combination of ZIP codes, ZIP+4 codes, FSAs, full Canadian postal codes, and lat/lon coordinates. Timezone data is always included at no extra cost. Each endpoint in the response includes an input_type field ("code" or "coordinates") indicating how the point was resolved.

GET /v2/distance
POST /v2/distance

Parameters

ParameterTypeRequiredDescription
fromstringRequiredOrigin point. Accepts: US ZIP (90210), ZIP+4 (90210-1234), Canadian FSA (M5V), Canadian postal code (M5V2H1), or lat,lon coordinates (34.103,-118.410)
tostringRequiredDestination point. Accepts: US ZIP (90210), ZIP+4 (90210-1234), Canadian FSA (M5V), Canadian postal code (M5V2H1), or lat,lon coordinates (40.758,-73.986)
You can mix any input types. For example: from=90210-1234&to=40.758,-73.9855

Credit Cost

Fixed 1 credit per pair. Timezone is always included at no extra cost.

Calculate your cost

Example Request

cURL
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://api.zip-codes.com/v2/distance?from=90210&to=10001"
Open in Playground

Example Response

Response
{
  "success": true,
  "request": { "from": "90210", "to": "10001" },
  "results": [{
    "from": { "country": "US", "code": "90210", "city": "BEVERLY HILLS", "state": "CA", "location": { "lat": 34.1028, "lon": -118.4147 }, "timezone": { "iana_name": "America/Los_Angeles" } },
    "to": { "country": "US", "code": "10001", "city": "NEW YORK", "state": "NY", "location": { "lat": 40.7502, "lon": -73.9971 }, "timezone": { "iana_name": "America/New_York" } },
    "distance": { "miles": 2453.39, "km": 3948.3 },
    "bearing": 65.9
  }],
  "meta": { "version": "2.0.0", "timing_ms": 31, "credits": { "used": 1, "remaining": 74999 }, "notices": [] }
}

Health Check

Returns API and database health status. No authentication required.

GET /v2/health

Three-state health: healthy (normal), degraded (DB latency >500ms), unhealthy (DB unreachable, returns HTTP 503).

Response
{
  "success": true,
  "data": { "status": "healthy", "database": { "connected": true, "latency_ms": 3 }, "version": "2.0.0" },
  "meta": { "version": "2.0.0", "timing_ms": 5, "notices": [] }
}

Batch Requests

All four lookup endpoints support batch processing via POST. Send up to 100 items per request. Individual items can succeed or fail independently (the overall HTTP status is 200 even if some items fail).

Subscription required: Batch endpoints require a paid subscription (Developer tier or higher). Free tier accounts receive an AUTH_BATCH_REQUIRES_SUBSCRIPTION error.

Batch Response Meta

Batch Meta
{
  "meta": {
    "batch": { "requested": 3, "succeeded": 2, "failed": 1 },
    "credits": { "used": 3, "remaining": 74997 },
    "notices": []
  }
}
Duplicate detection: If the same code appears multiple times in a batch, duplicates are removed and a BATCH_DUPLICATES_DETECTED notice is included. You are only charged once per unique code. For distance batches, deduplication operates on the full from/to pair.

Batch Endpoints

EndpointURLBody Format
Quick ZIP POST /v2/quick-zip/batch {"codes": ["90210", "M5V"], "include": "timezone"}
ZIP Details POST /v2/zip/batch {"codes": ["90210", "10001"], "include": "timezone,census"}
Radius POST /v2/radius/batch {"searches": [{"code": "90210", "max": 25}]}
Distance POST /v2/distance/batch {"pairs": [{"from": "90210", "to": "10001"}]}

Example: Quick ZIP Batch

Request
curl -X POST "https://api.zip-codes.com/v2/quick-zip/batch" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"codes": ["90210", "M5V", "99999"], "include": "timezone"}'

Partial Failure

When some items fail, the overall HTTP status is still 200. Failed items appear in the results array with success: false and a per-item error object. The meta.batch summary tells you how many succeeded and failed:

Partial Failure Response
{
  "success": true,
  "results": [
    { "success": true, "code": "90210", "city": "Beverly Hills", "state": "CA", "..." : "..." },
    { "success": true, "code": "M5V", "city": "Toronto", "state": "ON", "...": "..." },
    { "success": false, "code": "99999", "error": { "code": "NOT_FOUND_ZIP", "message": "US ZIP code not found" } }
  ],
  "meta": { "batch": { "requested": 3, "succeeded": 2, "failed": 1 }, "credits": { "used": 3, "remaining": 74997 }, "notices": [] }
}

Data Enrichments

All enrichments are opt-in. Add them to the include parameter as a comma-separated list. Each enrichment adds 1 credit to the cost. Without any enrichment flags, you get base data only (1 credit).

About This Data

US ZIP code boundaries come from a commercial boundary provider, updated quarterly. The dataset includes ~33,400 polygon boundaries plus ~7,600 point-only entries (PO Box, Military, and Unique ZIP types that have no geographic area).

Census geographies (counties, tracts, places, etc.) are drawn independently of ZIP codes and almost never align. Where they overlap, each result includes two percentages: pct_of_zip and pct_of_area.

Understanding pct_of_zip vs. pct_of_area

pct_of_zip = intersection area ÷ ZIP area — "What percentage of this ZIP does the geography cover?" Use this for demographic weighting: if a county covers 60% of a ZIP, roughly 60% of that ZIP's population lives in that county.

pct_of_area = intersection area ÷ geography area — "What percentage of the geography falls within this ZIP?" Use this to gauge significance: a large county may overlap a ZIP but that ZIP is only a tiny sliver of the county.

Example: A county covers 40% of a ZIP (pct_of_zip = 40.0), but that overlap is only 2% of the county's total area (pct_of_area = 2.0). The county is meaningful to the ZIP, but the ZIP is insignificant to the county.

About This Data

Canadian FSAs (Forward Sortation Areas, ~1,643): The first 3 characters of a postal code. Polygon boundaries from Statistics Canada, updated with each census cycle (every 5 years).

Full Canadian postal codes (~876,000): All 6 characters. Point coordinates only — Canada Post provides centroids but postal code polygon boundaries are not publicly available. Included in /v2/radius centroid mode (default). Not available in spatial mode.

US ZIP+4 (~40M codes): Uses the parent 5-digit ZIP centroid. ZIP+4 areas change monthly with carrier route reassignment and have no stable polygon boundary.

FlagDescriptionEndpointsCostAvailability
timezoneIANA timezone with DST infoQuick ZIP, ZIP, Radius+1US + CA
censusCensus boundary overlapsZIP+1US + CA
cdCongressional districtsZIP+1US only
state_legState legislature districtsZIP+1US only
school_districtSchool district boundaries (NCES)ZIP+1US only
acs_demographicPopulation, age, sex, race (DP05)ZIP, Radius+1US only
acs_socialHouseholds, education, language (DP02)ZIP, Radius+1US only
acs_economicEmployment, income, industry (DP03)ZIP, Radius+1US only
acs_housingHousing units, occupancy, value (DP04)ZIP, Radius+1US only
acs_{profile}_{YYYY}Historical ACS for years 2011–2024. Append year to any ACS flag (e.g., acs_housing_2022). 4 profiles × 14 years = 56 flags. See ACS Data for year-by-year coverage.ZIP, Radius+1 eachUS only
demographicsPopulation, race, age, households, income, businessZIP+1US only
medicareMedicare CBSA, rating area, SSA codeZIP+1US only
Canadian availability: Requesting US-only enrichments for Canadian codes returns null with an ENRICHMENT_UNAVAILABLE notice. No credit is charged for unavailable enrichments.

Timezone

Returns IANA timezone data including standard and daylight saving abbreviations and UTC offsets. In the /v2/zip endpoint, returns an object with source and a zones array with percentage overlap when a ZIP code spans multiple timezones. On other endpoints, timezone is a flat object per result.

Fields Returned

FieldTypeDescription
sourcestringData source attribution
iana_namestringIANA timezone identifier (e.g., America/Los_Angeles)
namestringDisplay name (e.g., Pacific Standard Time)
abbreviationstringStandard time abbreviation (e.g., PST)
abbreviation_dststringDaylight saving abbreviation (e.g., PDT)
utc_offsetstringStandard UTC offset (e.g., -08:00)
utc_offset_dststringDST UTC offset (e.g., -07:00)
observes_dstbooleanWhether this timezone observes daylight saving time
pct_coveragenumber/v2/zip only — percentage of ZIP area in this timezone
On /v2/zip, the timezone object contains a zones[] array (sorted by coverage descending) and a primary shortcut. On other endpoints, a single timezone object is returned based on centroid point-in-polygon.
Timezone Object
{
  "source": "IANA Time Zone Database / timezone-boundary-builder",
  "zones": [{
    "iana_name": "America/Los_Angeles", "name": "Pacific",
    "abbreviation": "PST", "abbreviation_dst": "PDT",
    "utc_offset": -8, "utc_offset_dst": -7, "observes_dst": true, "pct_of_zip": 100.0
  }]
}

Census Boundaries

Returns all census geographic boundaries that overlap the ZIP code with percentage overlap calculations. Data sourced from Census Bureau TIGER/Line Cartographic Boundaries.

About This Data

Census boundaries are hierarchical areas defined for statistical reporting — they are not drawn to follow ZIP code boundaries. A single ZIP almost always overlaps multiple tracts, places, and other geographies.

FIPS code structure and geography details
GeographyFIPS LengthExample
State2 digits06 (California)
County5 digits06037 (Los Angeles Co.)
County Subdivision10 digits0603765000
Place7 digits0644000 (Los Angeles city)
Census Tract11 digits06037264000
Block Group12 digits060372640001
Congressional District4 digits0634

Counties (~3,200): Primary legal division of every state. Connecticut replaced its 8 counties with 9 Planning Regions in 2022 (Census Bureau adopted these starting with 2024 data). Louisiana has parishes, Alaska has boroughs, and some cities in Virginia and Maryland are independent of any county.

County Subdivisions: Minor Civil Divisions (MCDs) in ~29 states represent legal townships and towns. In other states, Census-defined County Divisions (CCDs) serve as statistical equivalents.

Places: Incorporated places (cities, towns, villages with legal boundaries) and Census Designated Places (CDPs — statistical areas for unincorporated communities).

Census Tracts (~85,000): Designed for 2,500–8,000 people with socioeconomic homogeneity. The tract code has an implied decimal: 046300 = tract 463.00.

Block Groups: The smallest geography with ACS data, containing 600–3,000 people. GEOID = parent tract code + 1 digit.

CBSAs: Metropolitan Statistical Areas (core city 50K+ population) or Micropolitan (10K–50K). Rural areas have no CBSA. Metropolitan Divisions subdivide the largest metros into component areas.

Included Boundary Types

BoundaryDescription
countyCounty boundaries with FIPS codes
county_subdivisionCounty subdivisions (CCDs, MCDs)
placeCensus-designated places and incorporated cities
tractCensus tracts with GEOID
block_groupCensus block groups
metro_micro_cbsa_statistical_areaMetropolitan/Micropolitan statistical areas
metropolitan_cbsa_divisionMetro divisions (where applicable)

Each boundary includes: geoid, name, land_area_sq_mi, water_area_sq_mi, pct_of_zip (% of ZIP this boundary covers), and pct_of_area (% of boundary this ZIP covers).

Census Boundary Object (excerpt)
{
  "census": {
    "county": [{ "geoid": "06037", "name": "Los Angeles County", "pct_of_zip": 100.0, "pct_of_area": 0.3 }],
    "place": [{ "geoid": "0606000", "name": "Beverly Hills city", "pct_of_zip": 49.3, "pct_of_area": 95.1 }],
    "tract": [{ "geoid": "06037700900", "name": "Census Tract 7009", "pct_of_zip": 10.2 }],
    "metro_micro_cbsa_statistical_area": [{ "geoid": "31080", "name": "Los Angeles-Long Beach-Anaheim, CA Metro Area", "pct_of_zip": 100.0 }]
  }
}

Congressional Districts

Returns congressional district overlaps for the current Congress session, with primary district identification and area percentages.

Fields Returned (US)

FieldTypeDescription
congressnumberCongressional session number (e.g., 119)
primary.geoidstringGEOID of the primary (highest overlap) district
primary.statestringState abbreviation
primary.district_numberstringDistrict number
districts[]arrayAll overlapping districts with geoid, name, state, district_number, land_area_sq_mi, water_area_sq_mi, pct_of_zip, pct_of_area

Fields Returned (CA)

Canadian codes return federal_electoral_district with uid, name, and pct_of_zip.

Congressional District Object
{
  "congressional_district": {
    "congress": 119,
    "districts": [
      { "geoid": "0632", "state": "CA", "district_number": 32, "name": "Congressional District 32", "pct_of_zip": 62.9 },
      { "geoid": "0636", "state": "CA", "district_number": 36, "name": "Congressional District 36", "pct_of_zip": 37.1 }
    ],
    "primary": { "geoid": "0632", "state": "CA", "district_number": 32 }
  }
}

State Legislature

Returns state senate (upper chamber) and assembly/house (lower chamber) district overlaps with area percentages. US only

Fields Returned

FieldTypeDescription
state_legislative_upper[]arrayState Senate district overlaps
state_legislative_lower[]arrayState House/Assembly district overlaps

Each district includes: geoid, name, district_code, state, state_fips, legislative_session_year, land_area_sq_mi, water_area_sq_mi, pct_of_zip, pct_of_area.

State Legislature Object
{
  "state_legislative_upper": [{ "geoid": "06024", "name": "24", "name_full": "State Senate District 24", "state": "CA", "pct_of_zip": 92.9 }],
  "state_legislative_lower": [{ "geoid": "06051", "name": "51", "name_full": "Assembly District 51", "state": "CA", "pct_of_zip": 63.5 }]
}

School Districts

Returns NCES school district data with boundary overlaps. US only

About This Data

District boundaries are from the National Center for Education Statistics (NCES). A single ZIP can overlap multiple school districts because different district types serve the same geographic area at different grade levels.

District type breakdown

Unified: Serves all grades K–12. The most common type nationwide.

Elementary / Secondary: Grade-banded districts that overlap geographically. Elementary districts cover lower grades (K–6 or K–8), while secondary districts cover upper grades (7–12 or 9–12).

Administrative: Supervisory unions (52 records, all in Vermont). The leaid field is a 7-character NCES Local Education Agency ID.

Locale codes: Range from 11 (City—Large) to 43 (Rural—Remote). Returned in the locale object as both a numeric code and description.

Fields Returned per District

FieldTypeDescription
leaidstringNCES Local Education Agency ID
namestringDistrict name
typestringDistrict type: unified, elementary, secondary, administrative, other
grade_low / grade_highstringGrade range served (e.g., PK to 12)
officeobjectOffice address, city, state, ZIP, county, lat/lon
localeobjectLocale classification code and description (city/suburb/town/rural)
pct_of_zip / pct_of_areanumberOverlap percentages
land_area_sq_minumberDistrict land area
School District Object
{
  "school_district": {
    "source": "National Center for Education Statistics (NCES)", "school_year": "2024-2025",
    "districts": [{
      "leaid": "0604830", "name": "Beverly Hills Unified School District",
      "type": "unified", "grade_low": "KG", "grade_high": "12",
      "pct_of_zip": 39.9, "pct_of_area": 72.8,
      "office": { "address": "624 N. Rexford Dr.", "city": "Beverly Hills", "state": "CA", "zip": "90210" },
      "locale": { "code": "21", "description": "Suburb - Large" }
    }]
  }
}

ACS Data

American Community Survey 5-year estimates from the Census Bureau. Four separate data profiles available, each activated by its own flag. US only

All ACS fields include an estimate (est) and margin of error (moe). Percentage fields also include pct and pct_moe. Suppressed Census values are returned as null.

Data freshness: Every ACS response includes a year field and a vintage field indicating the exact dataset. Current ACS flags (e.g., acs_demographic) return the most recent year (2020–2024). Historical flags (e.g., acs_demographic_2022) return the specified year's dataset. You can request current and historical simultaneously — they appear under acs.current and acs["2022"] respectively. 14 years available: 2011–2024.

acs_demographic — DP05 (108 fields)

SectionKey Fields
Sex and AgeTotal population, male/female counts, age brackets (under 5 through 85+), median age
RaceWhite, Black, American Indian, Asian, Pacific Islander, other, two or more races
Hispanic or Latino and RaceHispanic/Latino totals, breakdown by race within Hispanic/non-Hispanic
Citizen, Voting Age PopulationCitizens 18+, total voting age population
Total Housing UnitsHousing unit count

acs_social — DP02 (154 fields)

SectionKey Fields
Households by TypeTotal households, family/nonfamily, married-couple, single-parent, average size
RelationshipHouseholder, spouse, child, other relatives, nonrelatives, unmarried partner
Marital StatusNever married, now married, separated, widowed, divorced
FertilityWomen 15–50 who had a birth in the past 12 months
GrandparentsGrandparents living with grandchildren, responsible for care
School EnrollmentNursery through graduate school, public/private breakdown
Educational AttainmentLess than 9th grade through doctorate, high school+, bachelor's+
Veteran StatusCivilian veterans 18+
Disability StatusCivilian noninstitutionalized population with a disability
Residence 1 Year AgoSame house, different house (same county, state, abroad)
Place of BirthNative vs. foreign-born, state of birth, world region
Language Spoken at HomeEnglish only, Spanish, Asian/Pacific Island, other, English proficiency
AncestryTop ancestral origins reported
Computers and Internet UseHouseholds with computer, broadband, smartphone, no internet

acs_economic — DP03 (137 fields)

SectionKey Fields
Employment StatusLabor force, employed, unemployed, unemployment rate, armed forces
Commuting to WorkDrove alone, carpooled, public transit, walked, work from home, mean travel time
OccupationManagement, service, sales, construction, production, transportation
IndustryAgriculture, manufacturing, retail, healthcare, education, finance, tech
Class of WorkerPrivate wage, government, self-employed, unpaid family
Income and BenefitsMedian household/family income, per capita, with earnings/Social Security/retirement
Health Insurance CoverageWith/without coverage, private, public, by employment status
Poverty LevelFamilies and people below poverty, by age, family type, education

acs_housing — DP04 (143 fields)

SectionKey Fields
Housing OccupancyTotal units, occupied, vacant, homeowner vacancy rate, rental vacancy rate
Units in StructureSingle-family detached/attached, 2–4 units, 5–19, 20+, mobile home, boat/RV
Year Structure Built2020+, 2010–2019, 2000–2009, through 1939 or earlier
Rooms / Bedrooms1 room through 9+, median rooms, bedroom count distribution
Housing TenureOwner-occupied, renter-occupied, average household size by tenure
Year Householder Moved In2021+, 2018–2020, 2010–2017, through 1989 or earlier
Vehicles AvailableNo vehicle, 1, 2, 3+ vehicles
House Heating FuelGas, electric, fuel oil, coal, wood, solar, other, no fuel
Selected CharacteristicsLacking plumbing, lacking kitchen, no telephone service
ValueOwner-occupied home value distribution, median value
Mortgage StatusWith/without mortgage, second mortgage, home equity loan
Monthly Owner CostsCost distribution, median, as percentage of household income
Gross RentRent distribution, median rent, as percentage of household income

Historical ACS Data (2011–2024)

Append _YYYY to any ACS profile flag to request a specific year. Example: include=acs_housing_2022 returns the 2018–2022 5-Year Estimates for housing. You can request multiple years simultaneously (e.g., include=acs_economic,acs_economic_2019). Each flag costs +1 credit.

YearACS 5-Year EstimatesFieldsCoverage
2024 (current)2020–202452897.4%
20232019–2023528100%
20222018–202252198.7%
20212017–202151898.1%
20202016–202051898.1%
20192015–201951797.9%
20182014–201848692.0%
20172013–201748391.5%
20162012–201646387.7%
20152011–201546387.7%
20142010–201444183.5%
20132009–201344183.5%
20122008–201239474.6%
20112007–201139474.6%
Coverage is relative to the 528-field canonical maximum. Earlier years have fewer fields because Census added new questions over time (e.g., cohabiting couples in 2019, tribal detail in 2022). Fields not available for a given year return null. 394 “universal” fields are available across all 14 years.
On /v2/zip, ACS returns per-ZIP data under acs.current.{section} (or acs["2022"].{section} for historical). On /v2/radius, returns population-weighted aggregates under stats.acs.current.{section} — the stats object appears at the top level of each radius result alongside search, matches, and summary. Current dataset: 2020–2024 5-Year Estimates. Historical: 2011–2024 (14 years total).
ACS Data Structure
{
  "acs": {
    "geo_id": "860Z200US90210", "year": 2024,
    "product": "ACS 5-Year Estimates Data Profiles", "vintage": "2020-2024",
    "tables": { "demographic": "DP05", "social": "DP02", "economic": "DP03", "housing": "DP04" },
    "demographic": {
      "total_population": { "est": 21134, "moe": 82 },
      "sex_and_age": { "male": { "est": 10099, "pct": 47.8 }, "female": { "est": 11035, "pct": 52.2 }, "median_age": { "est": 49.3 } },
      "race": { "white": { "est": 17130, "pct": 81.1 }, "black_or_african_american": { "est": 366, "pct": 1.7 }, "asian": { "est": 1406, "pct": 6.7 } }
    }
  }
}

Demographics

Returns population, race, age, household, and business establishment data. Sourced from US Census Bureau and IRS Business Master File data.

Fields Returned

FieldTypeDescription
population
population.totalnumberTotal population (Census 2020)
population.estimatenumberCurrent population estimate
population.malenumberMale population
population.femalenumberFemale population
race
race.whitenumberWhite population
race.blacknumberBlack or African American population
race.hispanicnumberHispanic or Latino population
race.asiannumberAsian population
race.american_indiannumberAmerican Indian / Alaska Native population
race.hawaiian_pacific_islandernumberNative Hawaiian / Pacific Islander population
race.othernumberOther race population
age
age.mediannumberMedian age
age.median_malenumberMedian age (male)
age.median_femalenumberMedian age (female)
households
households.totalnumberTotal households
households.persons_per_householdnumberAverage persons per household
households.average_family_sizenumberAverage family size
households.median_incomenumberMedian household income (USD)
households.average_home_valuenumberAverage home value (USD)
business
business.establishmentsnumberNumber of business establishments
business.employeesnumberTotal employees
business.payroll_q1numberFirst quarter payroll (USD, thousands)
business.payroll_annualnumberAnnual payroll (USD, thousands)
business.employment_flagstringEmployment range flag when exact count is suppressed
This enrichment provides a compact demographic summary from Census and IRS data. For detailed survey-based estimates with margins of error, use the ACS enrichments.
Demographics Object
{
  "demographics": {
    "population": { "total": 21134, "estimate": 22943, "male": 10099, "female": 11035 },
    "race": { "white": 17130, "black": 366, "hispanic": 1296, "asian": 1406 },
    "age": { "median": 49.3 },
    "households": { "total": 8792, "median_income": 136490, "average_home_value": 1953100 },
    "business": { "establishments": 3142, "employees": 28853 }
  }
}

Medicare

Returns Medicare geographic identifiers used in healthcare pricing, insurance rating areas, and CMS administrative boundaries.

Fields Returned

FieldTypeDescription
cbsa_codestringCore Based Statistical Area code used by CMS for Medicare payment
cbsa_namestringCBSA name (e.g., “Los Angeles-Long Beach-Anaheim, CA”)
cbsa_typestringMetropolitan or Micropolitan (null if rural)
rating_area_idstringACA marketplace rating area identifier
ssa_state_county_codestringSSA state/county code used in Medicare administrative systems
multi_county_noticestringPresent only when a ZIP spans multiple counties with different Medicare assignments
Medicare Object
{
  "medicare": {
    "cbsa_code": "31080", "cbsa_name": "Los Angeles-Long Beach-Anaheim, CA",
    "cbsa_type": "Metropolitan", "rating_area_id": "16", "ssa_state_county_code": "05210"
  }
}

Credit Costs

How Credits Work

Every API call uses credits from your plan. Simple credits cost 1. Adding enrichments (extra data like demographics or timezone) adds to the cost. The radius endpoint scales with search distance. This section breaks down exactly what each call costs — no surprises.

EndpointBase Cost+ EnrichmentsPlain English
Address BETA1 per requestN/AAlways 1 credit
Quick ZIP1 (ZIP/FSA), 2 (ZIP+4/Postal/Coords)+1 per flag1–3 credits typical
ZIP Details1 (ZIP/FSA), 2 (ZIP+4/Postal/Coords)+1 per flag1–12 credits typical
Distance1 per pairtimezone freeAlways 1 credit
Suggest1–5 (by limit)N/A1 credit for ≤15 results
Radius1–5 (by distance)× (1 + flags)1–30 credits depending on distance + enrichments
BatchPer-item costSame as singleSum of individual items
Health0N/AAlways free
Address Matching

Fixed 1 credit per request, regardless of whether a match is found. No enrichment flags are available on this endpoint.

Quick ZIP & ZIP Details

Base cost depends on input type: ZIP or FSA = 1 credit, ZIP+4, Postal Code, or coordinates = 2 credits. Each enrichment flag adds +1.

Examples: ZIP with timezone = 2. ZIP+4 with timezone + demographics = 4.

Radius Search

Base cost scales with distance (banded pricing). Each enrichment multiplies the base rather than adding to it. Auto-radius counts as one additional data layer.

Examples: 25mi with no flags = 1. 25mi with timezone = 2. 200mi centroid with 4 ACS flags = 10.

Distance

Fixed 1 credit per pair. Timezone data is always included at no extra cost. Mix any input types freely.

Suggest

Cost scales with the requested limit: 1–15 results = 1 credit, 16–50 = 2, 51–150 = 3, 151–500 = 5. Billed on requested limit, not results returned.

Radius Credit Costs

Formula: base × (1 + enrichment_count). Base bands differ by mode.

Centroid Mode (default) — ceil(radius / 100), max 500mi
BandRadius RangeBaseNo Flags+ 1 flag+ 2 flags
11–100 mi1123
2101–200 mi2246
3201–300 mi3369
4301–400 mi44812
5401–500 mi551015
Spatial Mode — ceil(radius / 50), max 250mi
BandRadius RangeBaseNo Flags+ 1 flag+ 2 flags
11–50 mi1123
251–100 mi2246
3101–150 mi3369
4151–200 mi44812
5201–250 mi551015

Band boundaries are inclusive at the top: max=50 = band 1, max=51 = band 2. Decimal values are accepted: max=50.5 = band 2.

Formula Examples

  • 25mi centroid, no flags → ceil(25/100) × (1 + 0) = 1 credit
  • 25mi centroid, timezone → 1 × (1 + 1) = 2 credits
  • 100mi centroid, acs_demographic + timezone → 1 × (1 + 2) = 3 credits
  • 200mi centroid, 4 ACS flags → 2 × (1 + 4) = 10 credits
  • 500mi centroid, 4 ACS + timezone → 5 × (1 + 5) = 30 credits
  • 50mi spatial, no flags → ceil(50/50) × (1 + 0) = 1 credit
  • 100mi spatial, 2 ACS flags → 2 × (1 + 2) = 6 credits
  • 250mi spatial, 4 ACS + timezone → 5 × (1 + 5) = 30 credits

Credit Estimator

Select an endpoint and configure options to see exactly how many credits your API call will cost.

Your Estimate
Base credit1

Total per call1 credit
calls/day = 100 credits/day

Subscription Plans

PlanMonthly CreditsPrice
Free2,500 / dayFree
Developer75,000$49/mo
Professional250,000$149/mo
Business750,000$399/mo

Credit Packs

Pre-purchase credits that never expire. Works alongside any plan — free or paid. If you exceed your daily free allowance or monthly subscription, purchased credits kick in automatically.

PackCreditsPricePer 1,000
Starter10,000$10$1.00
Standard50,000$49$0.98
Growth100,000$79$0.79
Pro (best value)250,000$179$0.72
Enterprise1,000,000$499$0.50

Purchased credits are used only after your free or subscription allowance is exhausted. Need a custom volume? Contact us.

Format validation failures are free. If input doesn't match a recognized format (e.g., not a 5-digit ZIP, 9-digit ZIP+4, or Canadian ANA NAN pattern), no credit is charged (HTTP 400). If the format is valid but the code doesn't exist in our database, 1 credit is charged — the API still has to verify it.

Error Codes

Authentication Errors

CodeHTTPDescription
AUTH_MISSING_KEY401No API key provided
AUTH_INVALID_KEY401API key not recognized
AUTH_INACTIVE_KEY403API key has been deactivated
AUTH_INACTIVE_ACCOUNT403Account is suspended
AUTH_IP_RESTRICTED403Request IP not in key's allowlist
AUTH_ORIGIN_RESTRICTED403Request origin not in key's domain list
AUTH_IP_BLOCKED403IP temporarily blocked (excessive invalid key attempts)
AUTH_TEST_KEY_RESTRICTED403Test key limited to demo codes only
AUTH_TEST_KEY_RADIUS_EXCEEDED403Radius exceeds the limit allowed for test keys
AUTH_FREE_TIER_RADIUS_EXCEEDED403Radius exceeds the free tier limit (centroid: 100mi, spatial: 50mi)
AUTH_BATCH_REQUIRES_SUBSCRIPTION403Batch endpoints require a paid subscription (Developer tier or higher)

Validation Errors

CodeHTTPDescription
VALIDATION_MISSING_PARAM400Required parameter is missing
VALIDATION_INVALID_PARAM400Parameter value is invalid
VALIDATION_INVALID_ZIP400ZIP/postal code format not recognized
VALIDATION_INVALID_FORMAT400Input format not recognized (not a valid postal code or coordinate pair)
VALIDATION_INVALID_COORDINATES400Coordinates are not valid (latitude must be −90 to 90, longitude −180 to 180)
VALIDATION_INVALID_COORDINATES_FROM400The from coordinate pair is invalid (distance endpoint)
VALIDATION_INVALID_COORDINATES_TO400The to coordinate pair is invalid (distance endpoint)
VALIDATION_INVALID_RADIUS400Radius must be a positive number within mode limits
VALIDATION_INVALID_RADIUS_RANGE400Min radius must be less than max radius
VALIDATION_UNKNOWN_ENRICHMENT400Unrecognized enrichment flag in include parameter
VALIDATION_ACS_YEAR_NOT_AVAILABLE400Requested ACS year is not available (valid range: 2011–2024)
VALIDATION_BATCH_TOO_LARGE400Batch exceeds 100 items
VALIDATION_BATCH_EMPTY400Batch contains no items
VALIDATION_INVALID_REQUEST400Malformed or unreadable request body (invalid JSON, wrong field types)
MISSING_VERSION400Request path must start with /v2/

Credit & Rate Limit Errors

CodeHTTPDescription
CREDIT_INSUFFICIENT402Not enough credits remaining
CREDIT_DAILY_LIMIT402Free tier daily limit reached
RATE_LIMIT_MINUTE429Per-minute rate limit exceeded
RATE_LIMIT_HOUR429Per-hour rate limit exceeded

Framework Errors

CodeHTTPDescription
METHOD_NOT_ALLOWED405HTTP method not supported for this endpoint
REQUEST_TOO_LARGE413Request body exceeds the maximum allowed size
UNSUPPORTED_MEDIA_TYPE415POST requests must use Content-Type: application/json

Service Errors

CodeHTTPDescription
SERVICE_POOL_EXHAUSTED503All database connections are in use; retry shortly
SERVICE_TIMEOUT504Database query exceeded the timeout threshold
SERVICE_MAINTENANCE503Service is temporarily unavailable for maintenance

Per-Item Not Found (HTTP 200)

CodeDescription
NOT_FOUND_ZIPUS ZIP code not found
NOT_FOUND_ZIP4US ZIP+4 code not found (parent ZIP exists)
NOT_FOUND_FSACanadian FSA not found
NOT_FOUND_POSTALCanadian postal code not found
NOT_FOUND_CENTERRadius search center code not found
NOT_FOUND_COORDS_NO_BOUNDARYCoordinates do not fall within any known postal code boundary

Error Response Format

Error Response
{
  "success": false,
  "results": [],
  "error": { "code": "AUTH_MISSING_KEY", "message": "API key is required. Provide via X-Api-Key header or ?key= parameter." },
  "meta": { "version": "2.0.0", "timing_ms": 1, "notices": [] }
}

Rate Limiting

All responses include rate limit headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
X-RateLimit-WindowRate limit window period: always minute

Limits by Plan

PlanPer MinutePer Hour
Free (no subscription)603,600
Developer ($49/mo)30018,000
Professional ($149/mo)30018,000
Business ($399/mo)60036,000
EnterpriseCustom (contact sales)

When rate-limited (HTTP 429), the response includes a Retry-After header with seconds to wait:

429 Response Body
{
  "success": false,
  "error": { "code": "RATE_LIMIT_MINUTE", "message": "Rate limit exceeded. Try again in 45 seconds." },
  "meta": { "version": "2.0.0", "timing_ms": 0, "rate_limit": { "limit": 120, "window": "1 minute", "retry_after": 45 }, "notices": [] }
}

Supported Countries

CountryCode TypesCensus BoundariesACS DataPolitical Districts
United States ZIP (5-digit), ZIP+4 (9-digit) Full (county, tract, block group, place, CBSA) Full (DP02–DP05) Congressional, State Senate, State House
Canada FSA (3-char), Postal (6-char) Provincial boundaries Not available Not available

HTTP Status Codes

Summary of all HTTP status codes the API can return:

CodeMeaningWhen
200OKSuccessful request. Batch requests return 200 even if individual items fail.
400Bad RequestMissing or invalid parameters, malformed JSON body, empty batch
401UnauthorizedMissing API key, invalid key, or disabled account
402Payment RequiredInsufficient credits or daily limit reached
403ForbiddenAPI key lacks permission for the requested resource
405Method Not AllowedWrong HTTP method (e.g., PUT on a GET/POST endpoint)
415Unsupported Media TypePOST without Content-Type: application/json
429Too Many RequestsRate limit exceeded. Check Retry-After header.
500Internal Server ErrorUnexpected server error. Include X-Request-Id when reporting.
503Service UnavailableServer maintenance or temporary overload

Versioning

The API uses path-based versioning. All current endpoints are under /v2/. The version is also returned in every response as meta.version.

  • Backward-compatible changes (new fields, new enrichments, new endpoints) are added without a version bump.
  • Breaking changes (removed fields, changed response structure) will only occur in a new version (e.g., /v3/).
  • The current version (v2) is stable and actively maintained. There are no plans to deprecate it.
  • If a future version is released, v2 will continue to operate for a minimum of 12 months after deprecation notice.
  • See our Service Level Agreement and Terms of Service for uptime and usage commitments.

OpenAPI Specification

A machine-readable OpenAPI 3.0 specification is auto-generated from the API and always reflects the current endpoints, parameters, and response schemas.

ResourceURLUse For
Swagger UI /swagger Interactive exploration and testing
OpenAPI JSON /swagger/v2/swagger.json Import into Postman, generate SDKs, AI coding tools
Download Spec /v2/openapi.json Download the OpenAPI spec file directly
Import the OpenAPI spec into Postman (File → Import → Link) to get a ready-made collection with all endpoints, parameters, and authentication pre-configured.

Changelog

Notable API changes, data updates, and new features.

March 2026

  • New endpoint: /v2/address — Address matching (beta). Parse and validate raw US street addresses against USPS ZIP+4 delivery-point data. Returns standardized address, ZIP+4, parsed components, and delivery metadata. Fixed 1 credit per request.

Frequently Asked Questions

Do you use ZCTA boundaries?
No. Our ZIP code boundaries come are a commerical product that is generated from direct USPS mailing data and postal patterns. Boundaries are updated quarterly and reflect current USPS delivery routes, not Census-derived approximations. ZCTAs (ZIP Code Tabulation Areas) are Census Bureau constructs used only for geographic joins when mapping ACS demographic data to ZIP codes. The boundaries you see in our API are real, current ZIP code boundaries.
How often is the data updated?
Different data layers update on different schedules: US ZIP base data is updated monthly, ZIP boundaries quarterly, ACS census data annually (each December/January release), Canadian postal codes monthly, and school districts yearly. When data is updated, it is reflected in the API without any action needed on your part.
Can I try the API without signing up?
Yes. Our interactive demo let's you see the functionality of the API. Get a free API Key for 2,500 credits/day, no credit card, no committment. Finally, our Interactive Playground lets you work with all functionality of the API with full access to every endpoint and enrichment so you can evaluate the API before committing.
Do you support Canadian postal codes?
Yes. We support both FSA (Forward Sortation Area, 3 characters like M5V) and full postal codes (6 characters like M5V2H1) across all endpoints. Canadian codes work with timezone enrichment, and radius searches automatically include cross-border results. Some enrichments (ACS demographic data, congressional districts, school districts) are US-only and return null for Canadian codes with no credit charged.
What is the difference between Quick ZIP and ZIP Details?
Quick ZIP (/v2/quick-zip) is a lightweight lookup returning core postal code info (city, state, coordinates, code type) with only timezone as an optional enrichment. It is optimized for fast, high-volume lookups like form validation or address autocomplete. ZIP Details (/v2/zip) returns comprehensive data including demographics, business statistics, delivery points, and up to 11 enrichments (census boundaries, ACS data, congressional districts, school districts, and more).
How are credit costs calculated?
Every request has a base cost determined by input type: ZIP and FSA = 1 credit, ZIP+4 and Postal Code = 2 credits, coordinates add +1. Each enrichment flag in the include parameter adds +1 credit. For radius searches, the base cost depends on the search radius (banded pricing: 1/2/3/4/5 credits per 100-mile centroid band, or per 50 mile spatial band), multiplied by (1 + enrichment_count). Distance calculations are always 1 credit per pair with timezone included free. The Suggest endpoiint is based on tiers: 1–15 = 1 credit · 16–50 = 2 · 51–150 = 3 · 151–500 = 5. See the Credit Costs section for full details.
What happens if I exceed my rate limit?
You will receive an HTTP 429 response with a Retry-After header indicating how many seconds to wait. Rate limits are enforced on a per-minute window and vary by subscription tier. Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are included in every response so you can monitor usage proactively.
Can I do reverse geocoding with coordinates?
Yes. Pass coordinates as lat,lon in the code parameter (e.g., code=34.1030,-118.4105) on any lookup endpoint. The API uses a two-step spatial search: first, it identifies which ZIP or FSA boundary polygon contains the coordinate (not just the nearest centroid — a point in rural Montana will correctly resolve to the ZIP that actually covers that location, not a distant one). Then, it finds the closest ZIP+4 or full postal code centroid within that parent boundary for precise sub-code resolution. Coordinate credits add +1 to the base cost. This works in both the US and Canada.
What ACS data years are available?
We offer 14 years of ACS 5-Year Estimates (2011–2024) across all four profiles: Demographic (DP05), Social (DP02), Economic (DP03), and Housing (DP04). The default acs_* flags return the most recent year (2024, covering 2020–2024 estimates). To request a specific historical year, append _YYYY to any ACS flag (e.g., include=acs_demographic_2022). You can request multiple years in the same call. Field coverage is 100% for recent years and 74.6% for the earliest years (2011–2012), as Census added new questions over time. New ACS releases are added annually, typically within weeks of the Census Bureau publication.
Is there a batch/bulk endpoint?
Yes. All five lookup endpoints (Suggest, Radius, Quick ZIP, ZIP Details, Distance) support batch processing via POST. Send up to 100 items per request. The free tier excludes batch requests however. Each item succeeds or fails independently, and duplicates are automatically deduplicated (you are only charged once per unique code). See the Batch Requests section for body formats and examples.
Why does one ZIP return multiple counties, tracts, or school districts?
ZIP code boundaries and census/administrative boundaries are drawn independently — they almost never align. A single ZIP frequently spans multiple counties (even states), dozens of census tracts, and several school districts. The pct_of_zip and pct_of_area fields on each overlap quantify how much of each area is shared.
What is the difference between centroid and spatial mode on /radius?
Centroid (default) uses haversine distance between centroids — fast, supports up to 500mi, returns US ZIP codes + full Canadian postal codes. pct_inside and area_sq_mi are null. Spatial uses precise polygon intersection (STBuffer/STIntersects) — slower but includes pct_inside and area_sq_mi, supports up to 250mi, returns US ZIP codes + Canadian FSAs (no full postal codes). Use mode=spatial when you need overlap precision.