OAuth Token Lifetimes Across 7 Carrier APIs

We measured OAuth access-token lifetimes for FedEx, UPS, DHL, and USPS carrier APIs — from 28 minutes to 8 hours — with sources and dates.

OAuth Token Lifetimes Across 7 Carrier APIs

If you have ever wondered why your UPS integration started throwing 401s at 3am for no obvious reason, the answer is buried in a developer portal page nobody rereads after go-live. Carrier API token lifetime varies by a factor of 16 across the carriers most European shippers actually integrate with, from 30 minutes to 8 hours, and at least one major carrier changed its expiry window this year without much fanfare. We pulled the published numbers, dated them, and built the table your token-cache config should have been using already.

Method: what we checked and what we didn't

Every figure below comes from a carrier's own developer documentation, a sandbox token response example, or a documented advisory from a shipping software vendor where the carrier's own docs were vague. We collected these in September 2026. This is a docs benchmark, not a live-call timing test: we did not fire OAuth requests against production credentials and measure wall-clock expiry ourselves. If your own sandbox logs show different numbers, we want to hear about it for a follow-up post, particularly for GLS and DPD, where no public lifetime figure exists at all.

Where a vendor has multiple token types (access token, refresh token, payment token), we list each separately, because conflating them is exactly the kind of mistake that causes silent auth failures three weeks into production.

The token lifetime table

VendorToken typePublished lifetimeSource
FedEx (REST API)Access token60 minutes (3600s)FedEx Developer Portal
FedEx Supply ChainRefresh token31 days (2,682,000s), capped at 4,096 uses per appFedEx Supply Chain OAuth docs
UPSAccess token1 hour (reduced from 4 hours, effective April 1, 2026)Pitney Bowes advisory
DHL Post & Parcel GermanyAccess token30 minutes (1799s)DHL Developer Portal
DHL eCommerce AmericasAccess token60 minutes (3600s)DHL Developer Portal
USPS (v3 API)OAuth access token8 hours (28,800s)USPS APIs Onboarding Guide
USPS (v3 API)Payment token8 hoursUSPS APIs Onboarding Guide
GLSAccess tokenNot published
DPDAccess tokenNot published
EasyPostAPI key (no OAuth)Does not expireEasyPost Authentication docs
ShippoAPI key (no OAuth)Does not expireShippo Authentication docs

All figures verified as of September 2026. Where a carrier splits access and refresh tokens (FedEx Supply Chain, in the table above), we listed only the token relevant to ongoing session management; both carriers document a 60-minute access token alongside it, per the FedEx Supply Chain token endpoint sample response showing {"expires_in": 3600}.

The UPS change is the story here, not a footnote

Starting April 1, 2026, the lifespan of OAuth tokens will change from 4 hours to 1 hour, according to Pitney Bowes' advisory to its shipping software customers. This update impacts how integrations manage token refresh logic, and it means any integration that hardcoded a 4-hour cache window, or worse, one that only refreshed on a scheduled cron job tuned to the old cadence, started failing on April 1 without any code change on the integrator's side.

This is a documentation-drift trap in its own right. Public forum threads and community posts, including a recent n8n community thread, still describe UPS tokens as expiring after 4 hours, because that was accurate until this year. If your team copy-pasted a Postman collection or Stack Overflow snippet built before April 2026, it's now stale, and stale auth documentation is worse than no documentation because it looks authoritative.

What a 16x spread means for your token cache

DHL's Post & Parcel Germany API expires tokens after 30 minutes. USPS holds a token valid for 8 hours. That's a 16x difference in how often your integration needs to hit the token endpoint, and if you're running a single global refresh interval across carriers, you're either refreshing DHL tokens too late or hammering USPS's endpoint far more than necessary.

The standard mitigation is a caching buffer: treat a token as expired somewhat before its stated TTL rather than waiting for the exact second. One integration guide for USPS explicitly recommends caching with a wide buffer rather than a thin one, because USPS says to cache the token with a 30-minute expiry buffer, not 5 minutes, so if expires_in is 28800, treat the token as expired at 28200 seconds. That's roughly a 2% buffer applied to an 8-hour window. Apply the same percentage logic to DHL's 30-minute token and your buffer shrinks to under a minute, which tells you the buffer needs to scale with the token type, not sit at a fixed number of seconds across every vendor.

A practical checklist for a multi-carrier token cache:

  • Store TTL per vendor and per token type (access vs. refresh vs. payment), not as one global constant.
  • Set the refresh trigger as a percentage of TTL, not a fixed seconds value, so it scales correctly between DHL's 30-minute window and USPS's 8-hour window.
  • Treat "expires_in" as advisory rather than a hard guarantee. USPS documents that the token lifetime is 28800 seconds (8 hours) but USPS can revoke tokens early, and a strict expires_in countdown is not reliable, so your retry logic still needs to handle an unexpected 401 mid-window.
  • Log every token issuance with vendor, timestamp, and TTL, so a policy change like UPS's April 2026 shortening shows up in your metrics before it shows up as a support ticket.

Multi-carrier platforms sidestep this entirely

EasyPost and Shippo don't use OAuth for their own API layer at all. EasyPost's REST API uses HTTP Basic Auth with the API key as the username and an empty password, and there are no OAuth scopes; access level is determined entirely by whether you use a Test or Production key. Shippo works the same way: requests carry a static ShippoToken header rather than a bearer token that expires on a clock. Neither key rotates on a schedule the way UPS or DHL access tokens do. That doesn't mean the carrier-side OAuth complexity disappears, it means the platform absorbs it instead of the shipper. This is the actual value proposition of a multi-carrier abstraction layer: you manage one static credential, and the platform handles token churn against DHL, UPS, FedEx and the rest behind the scenes. The same pattern shows up across ShipEngine, Sendcloud, and nShift, and it's central to how platforms built for shippers running many carrier contracts at once, including Cargoson, position themselves against maintaining direct carrier connections one by one.

Where this leaves your integration checklist

If you're integrating carriers directly, build a per-vendor TTL table into your codebase now rather than assuming a shared refresh interval, and flag UPS specifically if your last token-handling code review predates April 2026. If you're running GLS or DPD in production and can see the actual expiry value in your token responses, send us the number and the date you captured it. Those two gaps in the table above stay marked "Not published" until we have a real sandbox timestamp to cite, not a guess.