Skip to main content

Python client for the ZIP Codes API: US ZIP and Canadian postal data with 14 years of US Census ACS demographics, radius search, address validation, and distance.

Project description

zip-codes-api

Python client for the ZIP Codes API — US ZIP and Canadian postal data with 14 years of US Census ACS demographics (2011–2024), radius search (centroid + spatial coverage-weighting), address validation with ZIP+4, distance, and typo-tolerant autocomplete.

pip install zip-codes-api          # core
pip install 'zip-codes-api[pandas]'  # + DataFrame helpers for research

Quickstart

from zip_codes_api import ZipCodesClient

# Public demo key works for demo ZIPs (90210, 10001, ...). Any ZIP: get a free
# key at https://www.zip-codes.com/api/signup (2,500 credits/day, no card).
client = ZipCodesClient("zc_test_DEMOAPIKEY000000000000")

bh = client.zip("90210", include=["acs_demographic", "timezone"])
print(bh["city"])  # Beverly Hills
print(client.last_meta["credits"]["used"])  # credits this call cost

Single-target methods (zip, quick_zip, radius, distance, address, suggest) return the first result object. Batch methods return the list of per-item results. Pass raw=True for the full response envelope. client.last_meta always holds the most recent response's meta (including credits).

14 years of demographics as a DataFrame

The reason most researchers reach for this API — a longitudinal ZIP-level series in one call, with the year-to-year Census variable drift and the 2020 GEO_ID change already normalized:

df = client.acs_timeseries("90210", profile="demographic", years=range(2011, 2025))
print(df[["sex_and_age.total_population", "sex_and_age.median_age"]])
#       sex_and_age.total_population  sex_and_age.median_age
# year
# 2011                        21719                    45.7
# ...
# 2024                        19004                    51.9

profile is one of demographic (DP05), social (DP02), economic (DP03), housing (DP04).

Coverage-weighted radius aggregation (no GIS)

/radius in spatial mode intersects your radius with actual ZIP/FSA boundary polygons and weights the ACS aggregate by each ZIP's pct_inside — a ZIP 30% inside contributes 30% of its population, not all-or-nothing:

r = client.radius("90210", max_radius=10, mode="spatial", include="acs_demographic")
pop = r["stats"]["acs"]["current"]["demographic"]["sex_and_age"]["total_population"]["est"]
print(f"{pop:,} people within 10 miles (coverage-weighted)")

matches = client.radius_dataframe("90210", max_radius=10, mode="spatial")  # pandas
print(matches[["code", "city", "pct_inside", "distance_miles"]].head())

Other endpoints

client.quick_zip("M5V")                       # Canadian FSA: city/province/coords
client.distance("90210", "10001")             # great-circle distance + bearing
client.address("200 N Spring St, Los Angeles, CA 90012")  # validate + ZIP+4
client.suggest("9021")                         # autocomplete -> result["matches"]

# Batch (up to 100; requires a paid subscription key)
client.zip_batch(["90210", "10001", "M5V"], include="timezone")

Errors

Failures raise typed exceptions carrying the API's code, status, and request_id:

from zip_codes_api import InsufficientCreditsError, RateLimitError, NotFoundError

try:
    client.zip("90210", include=["acs_economic"])
except RateLimitError as e:
    print("retry after", e.retry_after, "seconds")
except InsufficientCreditsError:
    ...
except NotFoundError:
    ...

ZipCodesClient retries 429 / 5xx automatically (honoring Retry-After), up to max_retries (default 2).

Links

License

MIT. Underlying demographic data is US Census Bureau ACS (public domain). Suggested acknowledgement:

Demographic data: US Census Bureau ACS 5-Year Estimates, accessed via ZIP Codes API (Zip-Codes.com), https://www.zip-codes.com/api/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zip_codes_api-0.1.0.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zip_codes_api-0.1.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file zip_codes_api-0.1.0.tar.gz.

File metadata

  • Download URL: zip_codes_api-0.1.0.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for zip_codes_api-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1176d357b988a2c3a431c918cafb9f2aa50c47882577efaaf6e69d3b54eb2c5d
MD5 c2927b27acdd037b5bab3a120fd43d37
BLAKE2b-256 c82ebfbfd7e9a04101a26649bd8e9e9b8c015fd6eb3092b8df0ec2251bc135fb

See more details on using hashes here.

File details

Details for the file zip_codes_api-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zip_codes_api-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for zip_codes_api-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cedff75d699ab0db532963e796258092fc68f964000c064bf08dc1e9c45c9fa
MD5 61dd4abf5caf82746d184e2158d21fb2
BLAKE2b-256 e6fa0fca6ca7df7972039f5e64820c4b2c3211980981074cd95c70726d47978d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page