USPS Web Tools to v3 REST API: Complete Endpoint Mapping
USPS retired the Web Tools XML API on January 25, 2026. Every legacy XML surface now has a REST equivalent on a different host, with a different auth model and, in several places, different field semantics. This is the mapping reference: which v3 route replaces your legacy call, and what changes about the call besides its URL.
Every route below is checked against the published USPS v3 OpenAPI specifications rather than reproduced from migration folklore. Where the commonly-repeated answer is wrong, that is called out.
Master endpoint mapping
Address APIs
| Web Tools XML API | v3 REST endpoint | Method | Notes |
|---|---|---|---|
AddressValidateRequest |
/addresses/v3/address |
GET | Query params, not an XML body. DPV comes back in additionalInfo |
CityStateLookupRequest |
/addresses/v3/city-state |
GET | ZIP to city and state |
ZipCodeLookupRequest |
/addresses/v3/zipcode |
GET | Returns ZIP+4 |
Tracking APIs
| Web Tools XML API | v3 REST endpoint | Method | Notes |
|---|---|---|---|
TrackFieldRequest |
/tracking/v3/tracking/{trackingNumber} |
GET | Tracking number is a path parameter now |
TrackConfirmRequest |
/tracking/v3/tracking/{trackingNumber} |
GET | Unified. Same route as TrackField |
Shipping and label APIs
| Web Tools XML API | v3 REST endpoint | Method | Notes |
|---|---|---|---|
eVS (Express Mail) |
/labels/v3/label |
POST | Needs a Payment Authorization token |
eVS (Priority Mail) |
/labels/v3/label |
POST | Same route, different mailClass |
eVS (Ground Advantage) |
/labels/v3/label |
POST | Replaces First-Class Package Service |
eVSCancel |
/labels/v3/label/{trackingNumber} |
DELETE | Cancel or refund. See the note below |
Pricing APIs
| Web Tools XML API | v3 REST endpoint | Method | Notes |
|---|---|---|---|
RateV4Request |
/prices/v3/base-rates/search |
POST | JSON body replaces the XML envelope. One mail class per call |
IntlRateV2Request |
/international-prices/v3/base-rates/search |
POST | Same shape, ISO alpha-2 country codes |
The base path is prices, not domestic-prices, and the operation is a POST to a /search route rather than a GET. Both halves of that get published wrong regularly. /prices/v3/total-rates/search is the sibling route when you want totals including extra services rather than base rates alone.
Service standards and locations
| Web Tools XML API | v3 REST endpoint | Method | Notes |
|---|---|---|---|
SDCGetLocationsRequest |
/service-standards/v3/estimates |
GET | Delivery estimates by origin and destination |
POLocatorRequest |
/locations/v3/post-office-locations |
GET | Post offices by ZIP or coordinates |
The locations route is post-office-locations, not post-offices. The same API also serves /locations/v3/dropoff-locations and /locations/v3/parcel-locker-locations, which have no Web Tools equivalent at all.
Authentication: before and after
Web Tools embedded a plain-text USERID in every XML request body. No scopes, no expiry, no rotation. The v3 API uses OAuth 2.0 client credentials, with tokens that last 8 hours.
POST https://secure.shippingapis.com/ShippingAPI.dll?API=Verify
<AddressValidateRequest USERID="YOUR_USERID">
<Address>
<Address1>Apt 2</Address1>
<Address2>1600 Pennsylvania Ave</Address2>
</Address>
</AddressValidateRequest>
<!-- USERID in plain text. No expiry. No scopes. No rotation. --># Step 1: get a token (8-hour lifetime, expires_in 28800)
curl -X POST "https://apis.usps.com/oauth2/v3/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
# Step 2: send it as a Bearer token
curl "https://apis.usps.com/addresses/v3/address?streetAddress=1600+Pennsylvania+Ave+NW&city=Washington&state=DC&ZIPCode=20500" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Cache that token. A token request spends one call against the same 60-per-hour budget as the address lookup it authorizes, so refetching per call halves your throughput.
Key gotchas
These are the migration landmines. Each one has taken down a production system.
01. The rate limit is 60 an hour, and it is shared
Web Tools had no meaningful documented limit. The v3 API allows 60 requests an hour per application, and address validation, tracking, pricing, and labels all draw on the same window. Token fetches count too. A store doing 50 orders a day will cross it during peak hours. You can request an increase; plan for the constraint regardless.
02. Label creation needs two tokens, in two different headers
Labels are the only endpoint family that needs a second authorization token: the standard OAuth Bearer token plus a Payment Authorization token tied to your CRID and MID.
# 1. Standard OAuth token
POST https://apis.usps.com/oauth2/v3/token
grant_type=client_credentials
# 2. Payment Authorization token
POST https://apis.usps.com/payments/v3/payment-authorization
Authorization: Bearer {standard_token}
{
"roles": [
{ "roleName": "PAYER",
"CRID": "YOUR_CRID",
"MID": "YOUR_MID",
"accountType": "EPS",
"accountNumber": "YOUR_EPS_ACCOUNT" }
]
}
# 3. Create the label with BOTH, in separate headers
POST https://apis.usps.com/labels/v3/label
Authorization: Bearer {standard_token}
X-Payment-Authorization-Token: {payment_token}Two details in that flow are commonly published wrong. The payment endpoint is /payments/v3/payment-authorization, not a payment-authorization/v3/payment-token route. And the header is X-Payment-Authorization-Token, not X-Payment-Authorization. The USPS Labels specification marks that header required on label creation, reprint, and cancellation. Put the token in the JSON body instead and the header is simply absent, which USPS reports as an authorization failure that reads like a credential problem when your credentials are fine.
03. Address1 and Address2 semantics are reversed
The single most common migration bug.
// Web Tools XML (reversed semantics)
// <Address1>Apt 2</Address1> <- secondary
// <Address2>1600 Penn Ave</Address2> <- primary street
// v3 REST JSON (plain semantics)
{
"streetAddress": "1600 Penn Ave",
"secondaryAddress": "Apt 2"
}
// Map Address1 -> streetAddress and every apartment
// number becomes the street. It fails silently.04. DPV data moved, it did not disappear
The field is still called DPVConfirmation. What changed is where it sits: the v3 response nests it inside an additionalInfo object alongside deliveryPoint, carrierRoute, countyName, congressDistrict, footnotes, vacant, business, and DPVCMRA, rather than putting it beside the standardized address lines. Code that reaches for it at the top level of the address object finds nothing and reads it as “not confirmed.”
The codes themselves are worth restating because D and S are published backwards constantly: Y both primary and secondary confirmed, D primary confirmed with secondary missing, S primary confirmed with secondary present but unconfirmed, N neither confirmed.
05. Cancel and refund are different operations
DELETE /labels/v3/label/{trackingNumber} cancels a label while no Shipping Services File has been created for it. Once one exists, the same call becomes a refund request and returns a disputeId you use to track the outcome. USPS issues one unique disputeId per CRID per day, so resubmitting the same label the same day is rejected rather than queued.
There is no simple 24-hour void window, which is the number most migration guides print. The trigger is the Shipping Services File, not the clock.
06. New base URLs
| Environment | Web Tools | v3 REST |
|---|---|---|
| Production | secure.shippingapis.com |
apis.usps.com |
| Testing | stg-secure.shippingapis.com |
apis-tem.usps.com |
The test environment takes your production credentials rather than a separate sandbox key pair, and the same product entitlements apply there. A flow that fails in TEM for lack of a granted product will fail identically in production.
07. One endpoint became many routes
Web Tools used an API name per operation (?API=Verify, ?API=CityStateLookup) but every one of them hit the same ShippingAPI.dll. The v3 API gives each resource its own path. Do not port the old dispatcher; map each operation to its dedicated route.
08. Migrating the code is no longer the last step
This one post-dates the shutdown by six months. Since August 1, 2026 the Addresses API requires a signed license agreement, and USPS states that “customers who did not complete onboarding no longer have access to the Addresses API.” A correctly mapped, correctly authenticated v3 integration can still return 401 on every address call. The license is requested through the Business Portal at cop.usps.com under My Account → API Licenses → Add an Addresses API License, signed by DocuSign, and countersigned by USPS on no published schedule. The enrollment guide walks it end to end.
Quick reference: field name changes
| Web Tools XML field | v3 REST JSON field | Watch out |
|---|---|---|
Address1 |
secondaryAddress |
Semantics reversed |
Address2 |
streetAddress |
Semantics reversed |
Zip5 |
ZIPCode |
Capital ZIP |
Zip4 |
ZIPPlus4 |
Capital ZIP, Plus4 suffix |
FirmName |
firm |
Simplified |
DPVConfirmation |
DPVConfirmation, inside additionalInfo |
Same name, moved one level down |
USERID attribute |
Authorization header |
Not in the body anymore |
Where this leaves you
The mapping is mechanical. The parts that are not mechanical are the 60-per-hour ceiling, the two-token label flow, and the license, and those are what actually decide whether a migration ships.
RevAddress runs the machinery against your own USPS credentials: the OAuth lifecycle, the X-Payment-Authorization-Token header, Retry-After handling, caching, and retries, with credentials encrypted at rest. DPV, ZIP+4, rates, tracking, and labels are USPS data and bill on your license, on every plan. Census-based standardization, geocoding, and address extract need no USPS license at all.
Start here
- USPS Web Tools shutdown — what broke on January 25 and the migration paths
- Migration checklist — the step-by-step version
- OAuth troubleshooting — every 401, 403, and 429 with its fix
- CRID and MID enrollment — the license, the EPA, and COP claims linking
- Rate limit strategies — caching and queueing past 60 an hour
- Get a free API key — 1,000 requests a month, no credit card, no USPS license
- Open-source clients: Python and Node on
usps-v3, PHP onrevaddress/usps-v3-php
Questions
- What replaced AddressValidateRequest in the USPS v3 API?
- GET /addresses/v3/address on the apis.usps.com host. It takes query parameters instead of an XML body, returns JSON, and carries DPV data in the additionalInfo object of the response rather than requiring a separate call.
- What replaced RateV4Request?
- POST /prices/v3/base-rates/search, with international pricing at POST /international-prices/v3/base-rates/search. Note the base path is prices, not domestic-prices, and the operation is a POST to a search route rather than a GET.
- How does label creation authorize in v3?
- With two tokens. The standard OAuth Bearer token goes in the Authorization header, and a Payment Authorization token from POST /payments/v3/payment-authorization goes in the X-Payment-Authorization-Token header. Sending the second one in the JSON body is the most common cause of a 401 on a label call.
- Can I still cancel a USPS label after creating it?
- A label can be canceled while no Shipping Services File has been created for it. Once one exists, you submit a refund request instead, which returns a disputeId for tracking. USPS issues one unique disputeId per CRID per day, so duplicate same-day submissions for the same label are rejected.
- Are Address1 and Address2 really reversed?
- Yes, and it is the single most common migration bug. In Web Tools XML, Address1 was the secondary line such as an apartment or suite, and Address2 was the primary street address. In v3, streetAddress is primary and secondaryAddress is secondary. Mapping Address1 to streetAddress turns every apartment number into a street.
Read next
USPS Web Tools Shut Down on January 25, 2026: What Broke and the Fastest Way to the v3 API
USPS retired Web Tools on January 25, 2026. If ShippingAPI.dll, USERID, or secure.shippingapis.com is failing, map the XML route to v3 REST here.
10 min readMigrationUSPS Web Tools Migration Checklist (2026)
A numbered checklist for moving off USPS Web Tools XML: endpoint map, the license now required, OAuth, field mapping, error mapping, and the cutover.
14 min readTroubleshootingUSPS v3 OAuth Troubleshooting: Every Error and How to Fix It
401, 403, and 429 from USPS v3, with the exact fix for each, including the Addresses API license that has gated address calls since August 1, 2026.
9 min read