Skip to content

Quickstart

  1. 1

    Create a key

    No credit card required. Takes 10 seconds.

    Create a key
  2. 2

    Validate an address

    curl 'https://api.revaddress.com/api/address/validate?streetAddress=1600+Pennsylvania+Ave&city=Washington&state=DC&ZIPCode=20500'
  3. 3

    Explore the full API

    Start free with Census standardization and geocoding. USPS verification and enabled production workflows require paid access and purchased funding; label purchase remains disabled.

    Read the API reference

How access works

Census standardization, geocoding and the Census data demos are free. USPS workflows need a paid plan, and each USPS verification takes 10 purchased credits ($0.01).

Free tier
  • Census address standardization and extraction
  • Street-level geocoding and the ACS demographics demo
  • Free operations use Census and local reference data only
  • No paid USPS or AI provider calls

USPS verification needs a paid plan and purchased credits. A Census answer is not a USPS DPV confirmation.

Paid plan and funding
  • Package tracking
  • Batch validation and the checkout widget
  • Dashboard and webhooks
  • Pickup scheduling

Paid workflows need a current payment. USPS verification also takes 10 purchased credits ($0.01) per address, and credits never top up automatically.

Higher volume
  • Increased throughput
  • Enterprise onboarding
  • Custom integrations

Talk to us when volume or licensing needs go past the published plans.

Authentication

Use the X-API-Key header for paid workflows such as tracking, labels, batch validation, request-access pickup, dashboard usage, and BYOK. The free tier covers Census address standardization, geocoding, address extract, and the intelligence demo, with no USPS license needed. Paid provider calls require current paid access and funding. Platform USPS DPV verification requires 10 purchased credits ($0.01) per address in addition to the software plan. BYOK credentials do not bypass the gate. Use a free API key when you want one identity across the docs and dashboard, then move to protected production workflows.

curl -H "X-API-Key: rv_live_your_key_here" \
  https://api.revaddress.com/api/address/validate?streetAddress=1600+Pennsylvania+Ave&city=Washington&state=DC&ZIPCode=20500

Address validation

Two validation paths, one endpoint. Every tier returns Census-standardized results (corrected street, city, state, ZIP Code and coordinates) with no USPS credentials required: use it for form standardization and geocoding today. For USPS DPV confirmation (deliverability, ZIP+4, CMRA, vacancy), a paid plan and purchased funding are required. Each platform USPS verification reserves 10 purchased credits ($0.01) in addition to software metering. Select Census standardization for the free path. An explicit verification request without funding stops before the provider call; do not treat a Census fallback as verified delivery. Free tier

GET /api/address/validate
  ?streetAddress=1600+Pennsylvania+Ave
  &secondaryAddress=Suite+100
  &city=Washington
  &state=DC
  &ZIPCode=20500

// Response
{
  "address": {
    "streetAddress": "1600 PENNSYLVANIA AVE NW",
    "secondaryAddress": "STE 100",
    "city": "WASHINGTON",
    "state": "DC",
    "ZIPCode": "20500",
    "ZIPPlus4": "0005"
  },
  "additionalInfo": {
    "DPVConfirmation": "Y",
    "vacant": "N",
    "deliveryPoint": "00",
    "business": "Y"
  },
  "matches": [{ "code": "31", "text": "Single Response - exact match" }],
  "resolution": {
    "classification": "deliverable_exact",
    "nextAction": "done",
    "userMessage": "USPS confirmed this address."
  }
}

City and state lookup

Look up city and state from a ZIP code. Returns all valid city names for the ZIP. Free tier

GET /api/address/city-state?zip=10001

// Response
{
  "zip5": "10001",
  "city": "NEW YORK",
  "state": "NY"
}

Batch address validation

Validate up to 50 addresses in a single request using Promise.allSettled, so every address gets a result even if some fail. Responses include per-address timing. Results are KV-cached for 24 hours. Growth+

POST /api/batch/validate
Content-Type: application/json

{
  "addresses": [
    { "streetAddress": "1600 Pennsylvania Ave", "city": "Washington", "state": "DC", "ZIPCode": "20500" },
    { "streetAddress": "350 Fifth Avenue", "city": "New York", "state": "NY", "ZIPCode": "10118" },
    { "streetAddress": "999 Fake St", "city": "Nowhere", "state": "XX", "ZIPCode": "00000" }
  ]
}

// Response — every address gets a result
{
  "results": [
    { "status": "fulfilled", "value": { "streetAddress": "1600 PENNSYLVANIA AVE NW", "ZIPPlus4": "20500-0005", "DPVConfirmation": "Y" } },
    { "status": "fulfilled", "value": { "streetAddress": "350 5TH AVE", "ZIPPlus4": "10118-0110", "DPVConfirmation": "Y" } },
    { "status": "rejected", "reason": { "error": "ADDRESS_NOT_FOUND", "message": "Address not found" } }
  ],
  "summary": { "total": 3, "fulfilled": 2, "rejected": 1 },
  "timing_ms": 342
}

Package tracking

Use the managed tracking route for USPS status lookup and normalized tracking data. Tracking is protected behind API keys and plan access; Census standardization, geocoding, and address extract stay free to test, while USPS operations require current paid access and funding.

GET /api/tracking/9400111899223456789012

// Response
{
  "tracking_number": "9400111899223456789012",
  "status": "Pre-Shipment",
  "status_detail": "Shipping Label Created, USPS Awaiting Item",
  "location": "NEW YORK, NY 10003",
  "events": [
    {
      "timestamp": "2026-03-17T03:26:34Z",
      "event": "Shipping Label Created, USPS Awaiting Item",
      "city": "NEW YORK",
      "state": "NY"
    }
  ]
}

Domestic prices

Compare USPS pricing across all domestic service types. Returns rates for Priority Mail, Ground Advantage, Priority Mail Express, and more. Free tier

POST /api/rates
Content-Type: application/json

{
  "origin_zip": "10001",
  "destination_zip": "90001",
  "weight_oz": 16,
  "mail_class": "ALL"
}

// Response
{
  "rates": [
    { "service": "PRIORITY_MAIL", "price": 8.70, "delivery_days": 2 },
    { "service": "GROUND_ADVANTAGE", "price": 5.25, "delivery_days": 5 },
    { "service": "PRIORITY_MAIL_EXPRESS", "price": 26.60, "delivery_days": 1 }
  ]
}

International prices

Get USPS pricing for international shipments. Supports all destination countries and international service types. Requires API key.

POST /api/international-prices
Content-Type: application/json

{
  "destination_country": "GB",
  "weight_oz": 32,
  "mail_class": "ALL"
}

// Response
{
  "rates": [
    { "service": "PRIORITY_MAIL_INTERNATIONAL", "price": 49.50, "delivery_days": 10 },
    { "service": "FIRST_CLASS_MAIL_INTERNATIONAL", "price": 15.25, "delivery_days": 21 }
  ]
}

Label creation

Create USPS shipping labels through the managed workflow path. Returns workflow, label, download, and refund/void metadata when completed. Requires Growth plan or higher.

POST /api/labels
Content-Type: application/json

{
  "from": {
    "name": "Your Company",
    "street": "123 Sender St",
    "city": "New York",
    "state": "NY",
    "zip": "10001"
  },
  "to": {
    "name": "Recipient",
    "street": "456 Receiver Ave",
    "city": "Los Angeles",
    "state": "CA",
    "zip": "90001"
  },
  "service": "PRIORITY_MAIL",
  "weight_oz": 16
}

// Response
{
  "label_id": "lbl_abc123",
  "tracking_number": "9205590164917312345678",
  "label_url": "https://api.revaddress.com/labels/lbl_abc123.pdf",
  "rate": { "amount": 8.70, "currency": "USD" }
}

Label management

List your labels, download PDFs, and void unused labels for refund. All operations scoped to your API key.

// List your labels
GET /api/labels

// Download a label PDF
GET /api/labels/lbl_abc123/download

// Void an unused label (refund postage)
POST /api/labels/void/lbl_abc123

// Response
{
  "label_id": "lbl_abc123",
  "status": "voided",
  "refund_status": "pending"
}

Service standards

Look up USPS delivery time standards between two ZIP codes. Returns estimated delivery days by service type.

GET /api/service-standards
  ?origin_zip=10001
  &destination_zip=90001

// Response
{
  "origin_zip": "10001",
  "destination_zip": "90001",
  "standards": [
    { "service": "PRIORITY_MAIL", "days": 2 },
    { "service": "GROUND_ADVANTAGE", "days": 5 },
    { "service": "PRIORITY_MAIL_EXPRESS", "days": 1 }
  ]
}

Locations

Find USPS post offices, collection boxes, and service locations near a ZIP code or address.

GET /api/locations?zip=10001&radius=5

// Response
{
  "locations": [
    {
      "name": "Midtown Station",
      "address": "223 W 38th St, New York, NY 10018",
      "type": "POST_OFFICE",
      "hours": "Mon-Fri 8am-7pm, Sat 9am-4pm",
      "distance_miles": 0.3
    }
  ]
}

Pickup scheduling

Pickup endpoints are limited-rollout surfaces. Request access before relying on pickup flows for production operations.

POST /api/pickup
Content-Type: application/json

{
  "address": {
    "street": "123 Sender St",
    "city": "New York",
    "state": "NY",
    "zip": "10001"
  },
  "pickup_date": "2026-03-12",
  "package_count": 3,
  "service": "PRIORITY_MAIL"
}

// Illustrative response shape
{
  "confirmation_number": "WTC123456789",
  "pickup_date": "2026-03-12",
  "status": "pending_confirmation"
}

Shipping options

Get available USPS shipping options for a given origin/destination pair. Returns eligible service types with features and restrictions.

GET /api/shipping-options
  ?origin_zip=10001
  &destination_zip=90001
  &weight_oz=16

// Response
{
  "options": [
    {
      "service": "PRIORITY_MAIL",
      "features": ["TRACKING", "INSURANCE_INCLUDED"],
      "max_weight_oz": 1120
    },
    {
      "service": "GROUND_ADVANTAGE",
      "features": ["TRACKING"],
      "max_weight_oz": 1120
    }
  ]
}

BYOK (bring your own keys)

Supported paid accounts can connect their own USPS app (client_id and client_secret) for enabled integrations through /dashboard/#byok. Charges on that USPS license remain your responsibility. Connecting credentials does not bypass paid RevAddress access, request limits or funding checks. Credentials are AES-GCM encrypted at rest with an HKDF-derived account key; an isolated token manager handles OAuth refresh, retries and caching. Status values: pending_verification and verified. Label purchase and payment authorization remain disabled.

// Store your USPS credentials (encrypted at rest) — verifies immediately
POST /api/byok/credentials
X-API-Key: rv_live_...
Content-Type: application/json

{
  "client_id": "your_usps_consumer_key",
  "client_secret": "your_usps_consumer_secret",
  // optional — labels & payments only
  "crid": "12345678",
  "master_mid": "900000001",
  "label_mid": "900000002",
  "epa_account": "1000000001"
}

// 201 verified · 200 pending_verification
{ "status": "verified", "has_payment_fields": false,
  "verification": { "success": true, "message": "OAuth token obtained successfully" } }

// Check credential status + live token health
GET /api/byok/status
{ "byok_enabled": true, "status": "verified", "last_verified_at": "2026-08-17 14:02:11",
  "tokens": { "oauth": { "valid": true, "ttl_seconds": 25200 } } }

// Re-verify stored credentials
POST /api/byok/verify

// Remove your credentials — requests fall back to hosted processing
DELETE /api/byok/credentials

Webhook notifications

Webhook registration is available in limited rollout for tracking status updates. Register a URL when event delivery is enabled for your account. Payloads are HMAC-SHA256 signed so you can verify authenticity. Requires Starter plan or above. Maximum 5 endpoints per merchant.

// Register a webhook endpoint
POST /api/my/webhooks
Content-Type: application/json

{
  "url": "https://your-app.com/webhooks/tracking",
  "events": ["tracking.status_changed", "tracking.alert"]
}

// Response (secret shown ONLY on creation — save it!)
{
  "id": "wh_abc123",
  "url": "https://your-app.com/webhooks/tracking",
  "events": ["tracking.status_changed", "tracking.alert"],
  "secret": "rv_whsec_a1b2c3d4e5f6..."
}

// Illustrative webhook payload delivered to your URL
POST https://your-app.com/webhooks/tracking
Revaddress-Signature: t=1710000000,v1=5d41402abc...
Content-Type: application/json

{
  "event": "tracking.status_changed",
  "tracking_number": "9400111899223456789012",
  "status": "pre_shipment",
  "data": {
    "statusCategory": "Pre-Shipment",
    "latestEvent": {
      "eventType": "Shipping Label Created, USPS Awaiting Item",
      "eventCity": "NEW YORK",
      "eventState": "NY"
    }
  },
  "timestamp": "2026-03-17T03:26:34.000Z"
}

// Verify the signature — Node.js
const crypto = require('crypto');
const sig = req.headers['revaddress-signature'];
const [tPart, v1Part] = sig.split(',');
const timestamp = tPart.replace('t=', '');
const expected = crypto
  .createHmac('sha256', webhookSecret)
  .update(timestamp + '.' + JSON.stringify(req.body))
  .digest('hex');
const valid = v1Part.replace('v1=', '') === expected;

// Verify the signature — Python
import hmac, hashlib
sig = request.headers['Revaddress-Signature']
parts = dict(p.split('=', 1) for p in sig.split(','))
expected = hmac.new(
    webhook_secret.encode(),
    f"{parts['t']}.{request.data.decode()}".encode(),
    hashlib.sha256
).hexdigest()
valid = hmac.compare_digest(parts['v1'], expected)

// Verify the signature — PHP
$sig = $_SERVER['HTTP_REVADDRESS_SIGNATURE'];
preg_match('/t=(\d+),v1=(.+)/', $sig, $m);
$expected = hash_hmac('sha256',
    $m[1] . '.' . file_get_contents('php://input'),
    $webhookSecret);
$valid = hash_equals($m[2], $expected);

// Manage endpoints
GET /api/my/webhooks           // List all endpoints
DELETE /api/my/webhooks/{id}   // Remove an endpoint

Account management

View your usage, manage API keys, and check subscription status. All endpoints scoped to your authenticated merchant account.

// View your usage this billing period
GET /api/my/usage

// Response
{
  "merchant_id": "stripe_cus_abc123",
  "period_start": "2026-03-01",
  "total_requests": 1247,
  "by_endpoint": {
    "/api/address/validate": 892,
    "/api/tracking": 231,
    "/api/rates": 124
  }
}

// List your API keys
GET /api/my/keys

// Revoke an API key
DELETE /api/my/keys/{key_hash}

Admin diagnostics

Admin-only token diagnostics for internal operators. Use Authorization: Bearer {ADMIN_SECRET} to inspect token state, clear cached OAuth/payment tokens, force refreshes, and test payment authorization without buying postage. Internal only

GET /api/tokens/status

// Response
{
  "environment": "production",
  "oauth": { "valid": true, "ttl_seconds": 25120 },
  "payment": {
    "valid": true,
    "ttl_seconds": 23980,
    "lastAttemptAt": "2026-03-15T15:24:11.112Z",
    "lastUpstreamStatus": 200,
    "lastUpstreamMessage": "Payment authorization token obtained",
    "failureClass": null,
    "blockedReason": null
  }
}

POST /api/tokens/clear?env=prod
POST /api/tokens/refresh
POST /api/test-payment-auth

Rate limits

Rate limits are applied per API key, per minute. Exceeding your limit returns a 429 status. Current limits are returned in response headers. Free tier (no API key): 30 requests per 10 seconds, IP-limited.

// Response headers on every authenticated request
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1709913600

// Tier limits
// Starter:    120 req/min
// Growth:     300 req/min
// Pro:        higher plan limit
// Enterprise: Custom

// When rate limited
HTTP/1.1 429 Too Many Requests
{
  "error": "Rate limit exceeded",
  "retry_after": 42
}

Error handling

All errors return a consistent JSON structure with machine-readable error codes and human-readable messages.

// 400 Bad Request
{
  "error": "INVALID_ADDRESS",
  "message": "Street address is required",
  "field": "street"
}

// 401 Unauthorized
{
  "error": "INVALID_API_KEY",
  "message": "API key is missing or invalid"
}

// 403 Forbidden
{
  "error": "PLAN_LIMIT",
  "message": "Label creation requires Growth plan or higher"
}

// 429 Too Many Requests
{
  "error": "Rate limit exceeded",
  "retry_after": 42
}

Try it live

No signup required

Census standardization, geocoding and the Census data demos are free. USPS workflows need a paid plan, and each USPS verification takes 10 purchased credits ($0.01).

// Click "Validate address" to see the live response

Endpoint summary

Core commercial and operator endpoints across validation, rates, service standards, locations, tracking, label workflows, BYOK, and admin diagnostics.

Method Endpoint Auth Plan
GET/api/address/validateFreeAll
GET/api/address/city-stateFreeAll
POST/api/ratesAPI KeyStarter+
POST/api/international-pricesAPI KeyStarter+
GET/api/service-standardsAPI KeyStarter+
GET/api/shipping-optionsAPI KeyStarter+
GET/api/locationsAPI KeyStarter+
GET/api/tracking/:numberAPI KeyStarter+
POST/api/batch/validateAPI KeyGrowth+
POST/api/labelsAPI KeyGrowth+
GET/api/labelsAPI KeyGrowth+
GET/api/labels/:id/downloadAPI KeyGrowth+
POST/api/labels/void/:idAPI KeyGrowth+
POST/api/pickupAPI KeyStarter+
POST/api/my/webhooksAPI KeyStarter+
GET/api/my/webhooksAPI KeyStarter+
POST/api/byok/credentialsAPI KeyAccount management
GET/api/byok/statusAPI KeyAccount management
GET/api/my/usageAPI KeyAll
GET/api/my/keysAPI KeyAll

SDKs and libraries

Official SDKs for Python, Node.js and PHP.

Python v1.0.2 on PyPI
pip install usps-v3
Node.js v1.0.2 on npm
npm install usps-v3
PHP v1.0.0 on Packagist
composer require revaddress/usps-v3-php