USPS Tracking API & MCP

Query live United States Postal Service (USPS) (usps) package status and scan history in a single synchronous GET request or MCP tool call. lastscanned detects 20–26 digit USPS IMpb barcodes (including 420 + ZIP routing prefixes) and UPU S10 international tracking numbers, returning a normalized TrackingResult JSON payload—without requiring a USPS Web Tools / COPRA developer registration or MID/CRID onboarding.

Overview & Quick Facts

PropertyValue
Carrier slug (?carrier=)usps
Brand & service aliasesUnited States Postal Service, USPS Ground Advantage, Priority Mail, Priority Mail Express, First-Class Package International, Certified Mail, Media Mail
CategoryUS national postal service
Single-package REST endpointGET https://api.lastscanned.com/v1/track/{trackingNumber}
Batch REST endpointGET https://api.lastscanned.com/v1/track?numbers=9400...,9205... (up to 35 numbers per carrier in a 100-number call)
MCP server (https://mcp.lastscanned.com)track_package, track_packages, list_carriers (claude mcp add --transport http lastscanned https://mcp.lastscanned.com)
Authentication & pricingAuthorization: Bearer lsk_live_... · 1 free keyless lookup/day per IP · Free tier (5 unique numbers/day, $0) · Pro ($4.99/mo for 1,000 unique numbers, unlimited re-polls, $0.015/extra) · HTTP 402 Stripe MPP ($0.50 for 25-number lsk_pack_ key or $0.02/number in USDC on Tempo)

Why developers use lastscanned for USPS instead of direct requests

  • Avoid Akamai challenge pages & 403 blocks from serverless backends: Direct requests to tools.usps.com from Cloudflare Workers, Vercel, or AWS Lambda frequently receive blank Akamai challenge responses or HTTP 403 blocks. Calling GET https://api.lastscanned.com/v1/track/:number from your serverless function returns structured JSON in one fetch().
  • No USPS COPRA / Web Tools migration friction: USPS retired legacy Web Tools XML endpoints in favor of the v3 OAuth API requiring Business Customer Gateway accounts, Mailer IDs (MID), and Customer Registration IDs (CRID). lastscanned requires zero USPS account onboarding.
  • Cross-border & consolidator handoff target: Cross-border parcels from Yanwen, 4PX, Cainiao, YunExpress, CNE Express, and SunYou—plus domestic consolidators like OSM Worldwide, Pitney Bowes, and DHL eCommerce—induct into USPS under 420 + ZIP + 92/93… barcodes that lastscanned tracks natively.

Tracking Number Formats & Auto-Detection (matches vs mayMatch)

USPS is evaluated second (#2) in lastscanned's two-pass detector:

PassRule / RegexCheck DigitExamples
Pass 1 (matches) — Domestic IMpb/^(420\d{5})?9[2345]\d{18,24}$/ (20–26 digits starting 92, 93, 94, or 95, optionally preceded by 420 + 5-digit ZIP)—9400111899223847192011, 420787019261290312839104827163
Pass 1 (matches) — UPU S10/^[A-Z]{2}\d{9}US$/i (2 letters + 9 digits + US)Yes — s10(n) (Mod-11)EA123456785US, LK987654323US
Pass 2 (mayMatch)None——

UPU s10 Mod-11 check-digit algorithm

For 13-character international numbers ending in US, lastscanned validates the 9th digit (index 10) against the first 8 serial digits using UPU S10 weights [8, 6, 4, 2, 3, 5, 9, 7]:

/** UPU S10 (EA123456785US): weights 8,6,4,2,3,5,9,7 over the 8 serial digits, mod 11. */
export function s10(n: string): boolean {
  const d = n.slice(2, 11);
  const w = [8, 6, 4, 2, 3, 5, 9, 7];
  const c = 11 - (w.reduce((s, x, i) => s + x * Number(d[i]), 0) % 11);
  return (c === 10 ? 0 : c === 11 ? 5 : c) === Number(d[8]);
}

Disambiguating 22-digit USPS vs FedEx & Consolidator Labels (?carrier=osm, ?carrier=pitneybowes)

  • No collision with FedEx 22-digit SmartPost: USPS 22-digit IMpb labels start with 92, 93, 94, or 95, whereas FedEx 22-digit numbers start with 96 (/^96\d{20}$/). Both auto-detect without ?carrier=.
  • Resolving "USPS Currently Awaiting Package" on 92… consolidator labels: When a parcel is shipped through OSM Worldwide or Pitney Bowes using a 92… (or 420 + ZIP + 92…) USPS barcode, USPS only displays "Pre-Shipment / Picked Up by Shipping Partner, USPS Awaiting Item" until the consolidator drops the bag at the local USPS facility days later. Pass ?carrier=osm or ?carrier=pitneybowes with that same 92… number to retrieve the consolidator's live middle-mile sort scans!
  • When ?carrier=usps is required: Legacy 20-digit Certified Mail labels starting with 70…, 13-character inbound international S10 parcels originating outside the US (e.g. RR…GB, CP…CN once handed to USPS), or 10-digit Global Express Guaranteed numbers.

Synchronous GET Request & Normalized JSON Response

curl

curl -s "https://api.lastscanned.com/v1/track/9400111899223847192011" \
  -H "Authorization: Bearer $LASTSCANNED_API_KEY"

JavaScript / TypeScript (fetch)

const res = await fetch("https://api.lastscanned.com/v1/track/9400111899223847192011", {
  headers: { Authorization: `Bearer ${process.env.LASTSCANNED_API_KEY}` },
});
const pkg = await res.json();
console.log(pkg.status, pkg.statusDescription, pkg.events[0]);

MCP track_package tool call

{
  "tool": "track_package",
  "arguments": {
    "tracking_number": "9400111899223847192011"
  }
}

Normalized TrackingResult JSON response

{
  "carrier": "usps",
  "trackingNumber": "9400111899223847192011",
  "status": "delivered",
  "statusDescription": "Delivered, In/At Mailbox",
  "service": "USPS Ground Advantage",
  "deliveredAt": "2026-10-24T19:12:00Z",
  "deliveredAtLocal": "2026-10-24T14:12:00",
  "signedBy": null,
  "destination": {
    "city": "CHICAGO",
    "state": "IL",
    "country": "US"
  },
  "estimatedDelivery": null,
  "message": "Your item was delivered in or at the mailbox at 2:12 pm on October 24, 2026 in CHICAGO, IL 60614.",
  "events": [
    {
      "timestamp": "2026-10-24T19:12:00Z",
      "localTime": "2026-10-24T14:12:00",
      "status": "delivered",
      "description": "Delivered, In/At Mailbox",
      "location": "CHICAGO, IL 60614",
      "code": null
    },
    {
      "timestamp": "2026-10-24T11:10:00Z",
      "localTime": "2026-10-24T06:10:00",
      "status": "out_for_delivery",
      "description": "Out for Delivery",
      "location": "CHICAGO, IL 60614",
      "code": null
    },
    {
      "timestamp": "2026-10-24T10:59:00Z",
      "localTime": "2026-10-24T05:59:00",
      "status": "in_transit",
      "description": "Arrived at Post Office",
      "location": "CHICAGO, IL 60614",
      "code": null
    },
    {
      "timestamp": "2026-10-22T03:45:00Z",
      "localTime": "2026-10-21T22:45:00",
      "status": "label_created",
      "description": "Shipping Label Created, USPS Awaiting Item",
      "location": "DALLAS, TX 75201",
      "code": null
    }
  ]
}

Raw status & scan fields: USPS does not expose numeric event codes on public tracking timelines, so events[].code is null while statusDescription, message, and events[].description preserve the exact USPS scan wording (e.g. "Delivered, In/At Mailbox", "Arrived at USPS Regional Facility").

Carrier-Specific Status & Integration Notes

  • Timestamps (localTime and timestamp): USPS prints wall-clock times without an explicit UTC offset on each scan row (and date-only strings like "2026-10-22" on transit facility milestones without a clock time). lastscanned preserves the exact printed clock in localTime and converts full date-time scans to UTC in timestamp.
  • Top-level message summary: USPS provides a human-readable summary sentence for the latest scan (for example, "Your item was delivered in or at the mailbox at 2:12 pm…" or "Your package will arrive later than expected, but is still on its way."), which is returned in message.
  • Up to 35 USPS numbers per batch: GET /v1/track?numbers=... and the MCP track_packages tool accept up to 35 USPS tracking numbers in a single batch call.

On this page