Skip to main content

Python SDK

Official Python client for PostalDataPI.

Installation

pip install postaldatapi

Requires Python 3.8+. The only runtime dependency is requests.

Quick Start

from postaldatapi import PostalDataPI

client = PostalDataPI(api_key="YOUR_API_KEY")

# Look up a US ZIP code
result = client.lookup("90210")
print(result.city) # Beverly Hills
print(result.state) # California
print(result.state_abbreviation) # CA

# Look up a German postal code
de = client.lookup("10115", country="DE")
print(de.city) # Berlin

Configuration

client = PostalDataPI(
api_key="YOUR_API_KEY",
base_url="https://staging.postaldatapi.com", # override for staging
timeout=30, # seconds (default: 10)
)

Methods

client.lookup(postal_code, country=None)

Returns city and state/region for a postal code.

result = client.lookup("90210")
print(result.city) # Beverly Hills
print(result.state) # California
print(result.state_abbreviation) # CA
print(result.balance) # 4.99
print(result.raw) # full API response dict

Returns: LookupResult with fields: city, state, state_abbreviation, balance, rate_limit, raw

client.validate(postal_code, country=None)

Checks whether a postal code exists.

result = client.validate("90210")
print(result.valid) # True
print(result.postal_code) # 90210

Returns: ValidateResult with fields: valid, postal_code, balance, raw

client.search_city(city, state=None, country=None)

Finds postal codes for a city name. state is required for US queries.

result = client.search_city("Beverly Hills", state="CA")
print(result.postal_codes) # ['90209', '90210', '90211', ...]

Returns: CitySearchResult with fields: postal_codes, matched_city, matched_state, balance, raw

client.metazip(postal_code, country=None)

Returns all available metadata for a postal code.

result = client.metazip("90210")
print(result.city) # Beverly Hills
print(result.postal_code) # 90210
print(result.latitude) # 34.1031
print(result.longitude) # -118.4163
print(result.meta["county"]) # Los Angeles County
print(result.meta["timezone"]) # America/Los_Angeles

Returns: MetazipResult with fields: city, postal_code, latitude, longitude, meta, balance, raw

Error Handling

from postaldatapi import (
PostalDataPI,
PostalDataPIError,
AuthenticationError, # 401
NotFoundError, # 404
ValidationError, # 400
RateLimitError, # 429
InsufficientBalanceError, # 402
ServerError, # 5xx
)

client = PostalDataPI(api_key="YOUR_API_KEY")

try:
result = client.lookup("00000")
except NotFoundError:
print("Not found")
except PostalDataPIError as e:
print(f"Error {e.status_code}: {e.message}")

Tracking Balance

Every response includes the current account balance:

result = client.lookup("90210")
print(f"Remaining balance: ${result.balance:.2f}")

Source Code

GitHub