Carriers

FedEx Tracking API & MCP

Query live FedEx (fedex) package status and scan history in a single synchronous GET request or MCP tool call. lastscanned auto-detects 12-, 15-, 20-, and 22-digit (96…) FedEx tracking numbers and returns a normalized TrackingResult JSON payload—without requiring a FedEx Developer Portal project, OAuth client secret, or webhook setup.

Overview & Quick Facts

PropertyValue
Carrier slug (?carrier=)fedex
Brand & service aliasesFederal Express, FedEx Ground, FedEx Home Delivery, FedEx Express, FedEx Priority Overnight, FedEx Standard Overnight, FedEx 2Day, FedEx Ground Economy (SmartPost), FedEx International Priority
CategoryNational & international parcel carrier (Detection precedence #4 of 31)
Single-package REST endpointGET https://api.lastscanned.com/v1/track/{trackingNumber}
Batch REST endpointGET https://api.lastscanned.com/v1/track?numbers=... (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 FedEx instead of direct requests

  • Avoid Akamai Bot Manager 403 blocks on api.fedex.com: Direct POST calls to api.fedex.com/track/v2/shipments from Cloudflare Workers, Vercel, or AWS Lambda fail with Akamai 403 Forbidden responses unless accompanied by active sensor cookies. Calling GET https://api.lastscanned.com/v1/track/:number from your serverless backend works in a single fetch().
  • Zero FedEx Developer Portal OAuth setup: Official FedEx Track API access requires creating an organization project, passing production key validation, and managing OAuth 2.0 bearer token rotation. lastscanned needs no FedEx credentials.
  • Synchronous GET—no tracker registration: Query any FedEx tracking number on demand with GET /v1/track/:number instead of registering trackers via POST and waiting for webhook callbacks.

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

FedEx is evaluated fourth (#4) in lastscanned's two-pass detector (immediately after DHL):

PassRule / RegexCheck DigitExamples
Pass 1 (matches) — 12-digit/^\d{12}$/ (12 digits, Express / Ground)—789456123012, 281049382716
Pass 1 (matches) — 15-digit/^\d{15}$/ (15 digits, FedEx Ground)—041283910482716
Pass 1 (matches) — 20-digit/^\d{20}$/ (20 digits, excluding 0034043…)—61299998827162534120
Pass 1 (matches) — 22-digit 96…/^96\d{20}$/ (22 digits starting with 96, Ground 96 / SmartPost)—9622001900001234567890
Pass 2 (mayMatch)None——

Collision rules & when to pass ?carrier=fedex

  • 20-digit numbers (DHL Paket SSCC vs FedEx): Because dhl runs at precedence #3 before fedex (#4), 20-digit numbers starting with 0034043 (DHL's GS1 prefix) route to dhl. All other 20-digit numbers automatically route to fedex.
  • 22-digit numbers (USPS vs FedEx): 22-digit numbers starting with 92, 93, 94, or 95 route to usps, while 22-digit numbers starting with 96 route to fedex. If a FedEx Ground Economy (SmartPost) parcel uses a 926129… barcode and you specifically want FedEx's view instead of USPS's, pass ?carrier=fedex.
  • Door Tag numbers (DT + 12 digits): If you are tracking a FedEx Door Tag (DT123456789012) or custom shipper reference, pass ?carrier=fedex.

Synchronous GET Request & Normalized JSON Response

curl

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

JavaScript / TypeScript (fetch)

const res = await fetch("https://api.lastscanned.com/v1/track/789456123012", {
  headers: { Authorization: `Bearer ${process.env.LASTSCANNED_API_KEY}` },
});
const pkg = await res.json();
console.log(pkg.status, pkg.service, pkg.estimatedDeliveryAt);

MCP track_package tool call

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

Normalized TrackingResult JSON response

{
  "carrier": "fedex",
  "trackingNumber": "789456123012",
  "status": "delivered",
  "statusDescription": "Delivered",
  "service": "FedEx Home Delivery",
  "deliveredAt": "2026-10-25T18:34:00Z",
  "deliveredAtLocal": "2026-10-25T14:34:00",
  "signedBy": "Signature not required",
  "destination": {
    "city": "COLUMBUS",
    "state": "OH",
    "country": "US"
  },
  "estimatedDelivery": null,
  "estimatedDeliveryAt": null,
  "events": [
    {
      "timestamp": "2026-10-25T18:34:00Z",
      "localTime": "2026-10-25T14:34:00",
      "status": "delivered",
      "description": "Delivered - Left at front door. Package delivered to recipient address",
      "location": "COLUMBUS, OH",
      "code": "DL"
    },
    {
      "timestamp": "2026-10-25T11:48:00Z",
      "localTime": "2026-10-25T07:48:00",
      "status": "out_for_delivery",
      "description": "On FedEx vehicle for delivery",
      "location": "GROVE CITY, OH",
      "code": "OD"
    },
    {
      "timestamp": "2026-10-25T08:15:00Z",
      "localTime": "2026-10-25T04:15:00",
      "status": "in_transit",
      "description": "At local FedEx facility",
      "location": "GROVE CITY, OH",
      "code": "AR"
    },
    {
      "timestamp": "2026-10-23T19:02:00Z",
      "localTime": "2026-10-23T14:02:00",
      "status": "label_created",
      "description": "Shipment information sent to FedEx",
      "location": null,
      "code": "OC"
    }
  ]
}

Raw status & scan codes: statusDescription preserves FedEx's keyStatus (e.g. "Delivered", "On the way"), while each scan in events[] combines status and scanDetails into description and exposes FedEx's 2-letter statusCD in code ("OC", "PU", "IT", "AR", "DP", "OD", "DL", "DE", "RS").

Carrier-Specific Status & Integration Notes

  • Exact UTC + local timestamps & ETAs: FedEx reports each scan's local date, time, and explicit GMT offset (gmtOffset, e.g. "-04:00"). lastscanned computes exact UTC ISO 8601 timestamps in timestamp and deliveredAt, keeps the local clock in localTime and deliveredAtLocal, and provides both estimatedDelivery (local) and estimatedDeliveryAt (UTC) whenever FedEx includes an offset on its delivery estimate.
  • FedEx status code mapping: FedEx statusCD values map directly to normalized statuses: OC → label_created; PU, IT, AR, DP, AF, OF, FD, CC, HL → in_transit; OD → out_for_delivery; DL → delivered; DE, SE, CA → exception; RS → returned.

On this page