Skip to main content

Python SDK for USPS Web Tools v3 REST API — OAuth 2.0, address validation, tracking, labels, prices

Project description

usps-v3

Python SDK for the USPS Web Tools v3 REST API — the replacement for the retired XML-based Web Tools.

Direct USPS integration. OAuth 2.0. No middleman. No per-label fees.

Install

pip install usps-v3

Quick Start

from usps_v3 import Client

# Credentials from USPS Business Customer Gateway
client = Client(client_id="your-id", client_secret="your-secret")
# Or set USPS_CLIENT_ID and USPS_CLIENT_SECRET environment variables:
# client = Client()

# Validate an address (FREE)
result = client.addresses.validate(
    street_address="1600 Pennsylvania Ave NW",
    city="Washington",
    state="DC",
    zip_code="20500",
)
print(result["address"]["ZIPPlus4"])  # "0005"

# Track a package (FREE)
info = client.tracking.track("9400111899223033005282")
print(info["statusCategory"])  # "Delivered"

# Get delivery time estimates (FREE)
standards = client.standards.estimates("10001", "90210")

# Find drop-off locations (FREE)
locations = client.locations.dropoff("20500", mail_class="PRIORITY_MAIL")

# Get rate quotes
rates = client.prices.domestic("10001", "90210", weight=2.5)
print(rates["rates"]["rateOptions"][0]["totalPrice"])

# International rates
intl = client.prices.international("10001", "CA", weight=3.0)

# Create shipping labels (requires USPS enrollment + COP claims)
label = client.labels.create(
    from_address={"streetAddress": "123 Sender St", "city": "New York", "state": "NY", "ZIPCode": "10001"},
    to_address={"streetAddress": "456 Recipient Ave", "city": "LA", "state": "CA", "ZIPCode": "90001"},
    mail_class="PRIORITY_MAIL",
    weight=2.0,
)
print(label["trackingNumber"])

# Void a label
client.labels.void("9400111899223033005282")

Features

Feature Endpoint Auth Required
Address Validation addresses.validate() OAuth only
City/State Lookup addresses.city_state() OAuth only
Package Tracking tracking.track() OAuth only
Service Standards standards.estimates() OAuth only
Drop-off Locations locations.dropoff() OAuth only
Domestic Prices prices.domestic() OAuth only
International Prices prices.international() OAuth only
Label Creation labels.create() OAuth + Payment Auth
Label Void labels.void() OAuth only

Authentication

The SDK handles OAuth 2.0 token lifecycle automatically:

  • Token caching: Tokens are cached in memory and on disk (~/.usps-v3/tokens.json)
  • Auto-refresh: Tokens refresh automatically 30 minutes before expiry
  • Thread-safe: Safe for concurrent use across threads

Getting Credentials

  1. Register at USPS Business Customer Gateway
  2. Create an application in the API developer portal
  3. Note your client_id and client_secret

For label creation, you also need:

  • CRID (Customer Registration ID)
  • MIDs (Mailer IDs — master + label owner)
  • EPA (Enterprise Payment Account)
  • COP claims linking at cop.usps.com
client = Client(
    client_id="...",
    client_secret="...",
    crid="56982563",
    master_mid="904128936",
    label_mid="904128937",
    epa_account="1000405525",
)

Error Handling

from usps_v3 import Client, AuthError, ValidationError, RateLimitError, APIError

try:
    result = client.addresses.validate(street_address="123 Main St")
except ValidationError as e:
    print(f"Bad input: {e} (field: {e.field})")
except RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except AuthError as e:
    print(f"Auth failed: {e}")
except APIError as e:
    print(f"USPS error ({e.status_code}): {e}")

USPS Rate Limits

The v3 API defaults to 60 requests/hour (down from unlimited in Web Tools). The SDK does not enforce this limit — USPS returns 429 when exceeded.

To request a higher limit, contact USPS at emailus.usps.com.

Migration from Web Tools

If you're migrating from the retired USPS Web Tools XML API:

Web Tools (XML) v3 SDK (Python)
<AddressValidateRequest> client.addresses.validate(...)
<CityStateLookupRequest> client.addresses.city_state(...)
<TrackFieldRequest> client.tracking.track(...)
<RateV4Request> client.prices.domestic(...)
User ID auth OAuth 2.0 (automatic)
XML response parsing Python dicts (automatic)
Unlimited requests 60/hr default (request increase)

Development

git clone https://github.com/revereveal/usps-v3.git
cd usps-v3
pip install -e ".[dev]"
pytest -v

License

MIT — see LICENSE.

Built by RevAddress — direct USPS API integration for developers.

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

usps_v3-1.0.0.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

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

usps_v3-1.0.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

Details for the file usps_v3-1.0.0.tar.gz.

File metadata

  • Download URL: usps_v3-1.0.0.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for usps_v3-1.0.0.tar.gz
Algorithm Hash digest
SHA256 53934da893d8acbfe957298c565d4d7f7049199ec9e6d7ed2f619b4e18b0a457
MD5 82f214f75db57bcbd8eddbcff153fdf8
BLAKE2b-256 fec6518216e7cb2c6d2bda7dcc9344c7dd1ef809644173bb125c2ac468702c7b

See more details on using hashes here.

File details

Details for the file usps_v3-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: usps_v3-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for usps_v3-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56f2c3b139db5b10c8828268769f90150bf8cf1be50caf4e9c3b61485f6726f9
MD5 54a55c9f6c6ebc315fdf32160dd3903d
BLAKE2b-256 31fe3bd21d86357b9bdf43e3075571472347b6ecae1c4dc07a484d183bc61e28

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