USPS API Rate Limits: From 6,000/min to 60/hour — What Happened and How to Fix It
USPS replaced their Web Tools XML API with a v3 REST API in January 2026. One thing nobody expected: they dropped rate limits from ~6,000 requests/minute to 60 requests/hour for new applications.
If you're hitting 429s on the USPS v3 API, here's what's actually happening and five architecture patterns to handle it.
What Changed
Old API (Web Tools XML):
- ~6,000 requests/minute
- No formal documentation on limits
- Generous in practice
New API (v3 REST):
- 60 requests/hour (new applications)
- 5 requests/minute burst
- Enforced with HTTP 429
That's a 99% reduction in throughput. A shipping operation doing 1,000 validations/day now needs a fundamentally different architecture.
Why It Happened
USPS's v3 API serves consumer-facing apps (Informed Delivery, etc.) on the same infrastructure. Rate limits protect shared infrastructure. Enterprise shippers get higher limits via the USPS API team, but new applications start at 60/hour.
You can request a rate limit increase through the USPS Developer Portal, but approval takes 2-4 weeks and requires a business justification.
Pattern 1: Response Cache
Most address validation results don't change. Cache responses with a TTL:
import hashlib
import json
def cached_validate(address, cache, client):
key = hashlib.sha256(
json.dumps(address, sort_keys=True).encode()
).hexdigest()
cached = cache.get(key)
if cached:
return json.loads(cached)
result = client.addresses.validate(**address)
cache.set(key, json.dumps(result), ex=86400) # 24h TTL
return result
Impact: If 40% of your addresses are repeats (common in B2B), you cut API calls by 40%.
Pattern 2: Request Queue with Rate Smoothing
Don't burst — spread requests evenly across the rate window:
class RateLimiter {
constructor(maxPerHour = 60) {
this.interval = (3600 / maxPerHour) * 1000; // ms between requests
this.queue = [];
this.processing = false;
}
async add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
this.process();
});
}
async process() {
if (this.processing || !this.queue.length) return;
this.processing = true;
const { fn, resolve, reject } = this.queue.shift();
try {
resolve(await fn());
} catch (e) {
reject(e);
}
setTimeout(() => {
this.processing = false;
this.process();
}, this.interval);
}
}
Pattern 3: Batch Pre-validation
Validate addresses at import time, not checkout time:
- Customer uploads CSV of shipping addresses
- Background job validates all addresses over hours (staying under rate limit)
- Cache results
- At label creation time, pull from cache — no API call needed
This works if you have advance notice of addresses (most B2B shippers do).
Pattern 4: Multi-Key Rotation
If you have multiple USPS API credentials (separate business units, departments), rotate between them:
import itertools
keys = itertools.cycle([
{"client_id": "key1_id", "client_secret": "key1_secret"},
{"client_id": "key2_id", "client_secret": "key2_secret"},
])
def get_next_client():
creds = next(keys)
return USPSClient(**creds)
Warning: USPS terms require each application to have its own credentials. This is only valid if you genuinely have separate applications.
Pattern 5: API Proxy with Built-in Rate Management
If you don't want to build caching and queuing yourself, API proxies handle this at the infrastructure layer. They pool connections, manage token refresh, and smooth rate limits.
I built RevAddress for this exact problem — it's a USPS v3 proxy with 120-600 req/min depending on tier. But you can also build this yourself with Redis + a worker queue.
Request a Rate Limit Increase
The official path:
- Log into the USPS Developer Portal
- Go to your application → Support
- File a service request: "Rate limit increase for [App Name]"
- Include: your CRID, current volume, expected volume, business justification
- Wait 2-4 weeks
Include actual numbers. "We process 5,000 address validations daily for e-commerce checkout" is better than "we need more requests."
Full article with more code patterns: revaddress.com/blog/usps-api-rate-limits-2026-what-changed
Open-source USPS v3 SDKs: github.com/revereveal/usps-v3
Top comments (0)