whereparcel

Stuck on integration? Have a question? The developer is standing by.

Shipment tracking API · 43+ live carriers · one JSON shape

Build Your Tracking — Free for 3 Months

†
Ping, a parcel with a radar dish, standing on the datum of the drawing

Ping us.usps 9400 1118 9956 2537 8663 61

Stop paying for tracking infrastructure during your launch. USPS · UPS · FedEx · DHL & 43+ carriers — 10,000 lookups/month × 3 months free for subscribers who write one short post about WhereParcel.

  • CarriersUSPS · UPS · FedEx · DHL · 43+ carriers worldwide
  • The postAny language · any platform · any length

†Ambassador program — for customers who have paid for at least one month and keep an active subscription. There is no free tier. See what to write →

Request · bash
curl -X POST https://api.whereparcel.com/v2/track \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY:YOUR_SECRET_KEY" \
  -d '{"trackingItems":[{"carrier":"us.usps","trackingNumber":"9400111899562537866361"}]}'

Or just track a parcel right now —

POST/v2/track200 OKSample response · abridged
{
  "success": true,
  "data": [{
    "carrier": "us.usps",
    "trackingNumber": "9400111899562537866361",

    "status": "success",
    "data": {
      "deliveryStatus": "in_transit",
      "estimatedDelivery": "2026-10-02T00:00:00.000Z",
      "events": [ {…}, {…}, {…}, {…}, {
        "timestamp": "2026-09-29T10:12:00.000Z",
        "status": "in_transit",
        "location": "ATLANTA GA NETWORK DISTRIBUTION CENTER",
        "rawStatus": "Arrived at USPS Regional Facility",
        "rawDescription": "Arrived at USPS Regional Facility"
      }]
    },
    "billable": true,
    "cached": false
  }],
  "results": […],
  "summary": {
    "total": 1, "success": 1, "failed": 0,
    "usageIncremented": 1
  },
  "requestLimit": {…}, "trackingQuota": {…}
}
  1. Per item: success or error — one bad number doesn't fail the batch.
  2. deliveryStatus is one of nine normalized values (FIG. 2).
  3. = Thu, Oct 1, 8:00 pm ET
  4. Oldest first; the last one is the newest scan.
  5. = Tue, Sep 29, 6:12 am ET
  6. USPS's own wording stays in rawStatus and rawDescription.
  7. Cache hits come back with billable: false.
  8. Deprecated alias of data.
  9. = items with billable: true
FIG. 1One request in, one response shape out — the same for all 43+ live carriers.

Don't know the carrier? Use our free Tracking Number Validator — paste any number, we'll detect the carrier from the format. No signup.

Try API Now →

Follow one parcel

The parcel from FIG. 1, label to doorstep. Four stops, four deliveryStatus values, one response shape the whole way.

us.usps · 9400 1118 9956 2537 8663 61 "deliveryStatus": "in_transit"
  1. SEP 26 18:42

    Shipping Label Created, USPS Awaiting Item

    BROOKLYN, NY 11201

  2. SEP 27 16:05

    Accepted at USPS Origin Facility

    BROOKLYN, NY 11256

  3. SEP 27 21:37

    Departed USPS Facility

    BROOKLYN NY DISTRIBUTION CENTER

  4. SEP 28 --:--

    In Transit to Next Facility

    timeUnknown: true date only, noon filled in
  5. SEP 29 06:12

    Arrived at USPS Regional Facility

    ATLANTA GA NETWORK DISTRIBUTION CENTER

  6. OCT 1 by 20:00

    Expected Thu, Oct 1 · by 8:00 pm

    estimatedDelivery

Why pay more?

UPS, USPS, FedEx, DHL and other major carriers already work reliably. Missing a carrier? Just request it.

There's no reason to pay more for AfterShip or Ship24.

Submit a request and we'll add it fast — and you can cancel anytime.

Most carrier requests are added within days.

Carrier guides: USPS Tracking API · UPS · FedEx · DHL

Live nowCountCarrier codes
United States 5 us.usps us.fedex us.ups us.ontrac us.ca.ontrac
Canada 6 ca.post ca.purolator ca.canpar ca.intelcom ca.loomis ca.ics
United Kingdom 3 gb.royalmail gb.evri gb.fedex
Germany 4 de.hermes de.gls de.post de.fedex
Italy 3 it.tnt it.brt it.poste
Spain 2 es.fedex es.cttExpress
Australia 1 au.post
Japan 2 jp.yamato jp.post
South Korea 7 kr.post kr.cj kr.lotte kr.hanjin kr.logen kr.kdexp kr.daesin
Turkey 2 tr.yurtici tr.ptt
International 8 intl.dhl intl.cainiao intl.yunexpress intl.deutsche-post intl.tnt intl.chronopost intl.yanwen intl.canada-post
Not listed yet 0 Request a carrier → Ping checked twice — us.amazon isn't live yet. Ask, and it goes on the list. Ping looking for a carrier that isn't live yet
Total 43 carriers · 10 countries + international
One stroke = one live carrierView all 43+ live carriers →

Why Developers Choose Our Tracking API

One request shape, one response shape, one status model. The carrier-specific mess stays on our side of the API.

One Status Model for Every Carrier

Every carrier's scans map to the same nine deliveryStatus values (FIG. 2). The carrier's own wording is kept alongside in rawStatus and rawDescription.

pending · in_transit · out_for_delivery · delivered · failed · returned · cancelled · lost · unknown

CarrierrawStatusdeliveryStatus FedEx"DL" UPS"OT" USPS"Out for Delivery" delivered out_for_delivery
Ping, chin in hand, reading a carrier's status text

FIG. 2Three carriers, three dialects, two answers. Ping reads the dialects so your code only has to know nine words.

Real-time Webhook Notifications

Get instant delivery updates via webhooks. No polling needed — we push status changes to your endpoint automatically.

POST https://yourapp.com/webhooks/tracking
X-WhereParcel-Event: tracking.updated
X-WhereParcel-Timestamp: 2026-09-29T10:20:41.000Z
X-WhereParcel-Signature: 9f2c41…e07b

HMAC-SHA256 of the JSON body, hex, keyed with your endpoint's secret.

Enterprise-Grade Security

API key + secret authentication, HMAC-SHA256 signed webhooks, rate limiting, and TLS encryption. Your data is encrypted and protected.

Authorization: Bearer KEY:SECRET

Developer-First Documentation

OpenAPI 3.0 spec, code examples in 5 languages, interactive playground. Ship your integration in under an hour.

POST /v2/track     GET /v2/carriers
POST /v2/detect    GET /v2/countries

Flat Monthly Pricing

One monthly request quota for USPS, UPS, FedEx, DHL and more — no per-shipment fees, no hidden fees, no long-term contracts. Cancel anytime.

Starter $49/mo · 10K requests/month
See all plans →

Integrate in Minutes, Any Language

Start tracking packages with just a few lines of code. Choose your language and copy the example.

View Full Documentation →

See the API in Action

Enter a tracking number and watch the API request generate in real time.

us.usps = from the form
// npm install whereparcel
import { WhereParcel } from 'whereparcel';

const wp = new WhereParcel('YOUR_API_KEY', 'YOUR_SECRET_KEY');

const res = await wp.track([
  { carrier: 'us.usps', trackingNumber: '9400111899562537866361' },
]);

const item = res.data[0];
if (item.status === 'success') {
  console.log(item.data.deliveryStatus);
  console.log(item.data.events);
}
curl -X POST https://api.whereparcel.com/v2/track \
  -H "Authorization: Bearer YOUR_API_KEY:YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"trackingItems":[{"carrier":"us.usps","trackingNumber":"9400111899562537866361"}]}'
const res = await fetch('https://api.whereparcel.com/v2/track', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY:YOUR_SECRET_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    trackingItems: [{ carrier: 'us.usps', trackingNumber: '9400111899562537866361' }],
  }),
});
const { data } = await res.json();
console.log(data[0].data.deliveryStatus);
import requests

res = requests.post(
    "https://api.whereparcel.com/v2/track",
    headers={"Authorization": "Bearer YOUR_API_KEY:YOUR_SECRET_KEY"},
    json={"trackingItems": [{"carrier": "us.usps", "trackingNumber": "9400111899562537866361"}]},
)
print(res.json()["data"][0]["data"]["deliveryStatus"])
$ch = curl_init('https://api.whereparcel.com/v2/track');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer YOUR_API_KEY:YOUR_SECRET_KEY',
    'Content-Type: application/json',
  ],
  CURLOPT_POSTFIELDS => json_encode(['trackingItems' => [
    ['carrier' => 'us.usps', 'trackingNumber' => '9400111899562537866361'],
  ]]),
]);
$res = json_decode(curl_exec($ch), true);
echo $res['data'][0]['data']['deliveryStatus'];
body := strings.NewReader(`{"trackingItems":[{"carrier":"us.usps","trackingNumber":"9400111899562537866361"}]}`)
req, _ := http.NewRequest("POST", "https://api.whereparcel.com/v2/track", body)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY:YOUR_SECRET_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
  1. One package, typed responses.
  2. track() takes an array and returns one result per item.
  3. Each item is success or error — one bad number doesn't fail the batch.
  4. Always one of the nine normalized statuses.
Ping dozing while it waits for a request

No response yet

Open it in the Playground to send this exact request with a demo key. It comes back shaped like FIG. 1.

Ping, waiting on your first request.

Get Started in 3 Simple Steps

From sign-up to live tracking in under 5 minutes.

Get Started
  1. Get Started

    Pick a plan and get started — cancel anytime. Get your API key instantly from the dashboard.

  2. Make Your First API Call

    Use our code examples to send a tracking request. Get real-time delivery status in a single JSON response.

  3. Go Live with Webhooks

    Set up webhook endpoints to receive automatic delivery updates. No polling needed — we push changes to you.

Why WhereParcel Over DIY Integration?

Stop wasting months on carrier-by-carrier integration. Ship faster with a unified API.

Building It YourselfWith WhereParcel
Integrate each carrier API separatelyOne affordable API for all carriers
Maintain many different data formatsNormalized, consistent JSON response
Build your own status normalizationUnified delivery status codes
Handle rate limits and IP blockingCarrier blocking handled on our side
Months of development timeLive in under 5 minutes
Ongoing maintenance burdenWe handle all carrier changes

Simple, Transparent Pricing

Choose the plan that fits your needs. No hidden fees, cancel anytime.

‡

No obligation if you check this — you won't be penalized for not writing. Publish a short post about WhereParcel and we'll add 3 or more months of your plan for free, depending on the post.

PlanUSD / monthRequests / monthRequests / minute API keysSupportUptime SLASubscribe
StarterFor side projects and small apps $49 10K 30 3 Email — Get Started Subscribe & Join the Event
ProBest DealFor growing businesses $99 30K≈ 1,000 / day 60 10 Priority — Get Started Subscribe & Join the Event
GrowthFor scaling teams $250 100K 100 20 Priority — Get Started Subscribe & Join the Event
ScaleFor high-volume operations $450 200K 150 50 Dedicated — Get Started Subscribe & Join the Event
BusinessFor enterprise — dedicated support and 99.95% SLA $650 300K 200 Unlimited Dedicated 99.95% Get Started Subscribe & Join the Event

Webhook notifications · Included · Cancel anytime

Cancel AnytimeCancel anytime from your dashboard — you keep access until the end of your billing period. No long-term contracts.Cancel anytime from your dashboard — you keep access until the end of your billing period. And if you publish a post about us, we'll add 3+ months of your plan for free.

‡Ambassador rewards go to customers who have paid for at least one month and keep an active subscription. The standard reward is 3 months of Starter; longer rewards are decided per post.

Frequently Asked Questions

View All Frequently Asked Questions →
What is a shipment tracking API?
A shipment tracking API allows developers to programmatically retrieve real-time package delivery status from carriers like USPS, UPS, FedEx, and DHL through a single unified endpoint, instead of integrating with each carrier separately.
How many carriers does WhereParcel support?
WhereParcel currently supports 43+ live carriers in production, including major US (USPS, UPS, FedEx, OnTrac), UK (Royal Mail, Evri), and international carriers (DHL Express, TNT Express, Cainiao). Don't see your carrier? Request it on the community board — we add new carriers fast.
Can I try WhereParcel for free?
There's no free trial — you start on a paid plan and can cancel anytime, keeping access until the end of your billing period. Once you are subscribed, one short post about WhereParcel earns you 3 months free through our Ambassador program. See pricing plans.
How do I integrate WhereParcel into my application?
Pick a plan, get your API key, and make your first tracking request in under 5 minutes. Follow our 5-minute setup guide with code examples in cURL, Node.js, Python, and Go, or try the API Playground first. The full quickstart docs cover authentication, webhooks, and a production checklist.
Which countries and carriers does WhereParcel cover?
Live carriers cover 10 countries — the United States, Canada, United Kingdom, Germany, Italy, Spain, Australia, Japan, South Korea and Turkey — plus 8 international carriers such as DHL Express and TNT Express for cross-border shipments.
How does webhook tracking work?
With webhooks, WhereParcel automatically sends real-time notifications to your server whenever a package status changes. Instead of polling the API repeatedly, you register a webhook URL and receive instant updates — reducing API calls and improving response time for your users. Read our webhook best practices guide.
What is the average API response time?
Cached results come back fastest; live lookups depend on each carrier's own systems. The API is served from the US East region (us-east1). USPS, UPS and FedEx accept one tracking number per synchronous request.
Can I track international and cross-border shipments?
Yes. International live carriers include DHL Express, TNT Express, Cainiao, YunExpress, Yanwen, Deutsche Post International, Chronopost International and Canada Post International. You can track packages moving between countries using a single API call with the carrier code and tracking number.
How does WhereParcel compare to AfterShip, 17TRACK, Tracktry, and Parcellab?
WhereParcel offers a unified REST API with 43+ live carriers (and rapid on-request additions) and real-time webhooks. The biggest difference between providers is the billing model — WhereParcel uses flat monthly request quotas, AfterShip charges per shipment, 17TRACK uses an annual prepaid quota, Tracktry charges per tracking, and Parcellab is enterprise-only. See our 5-way 2026 comparison with real pricing for the full breakdown.
Is WhereParcel suitable for e-commerce platforms?
Absolutely. WhereParcel is designed for e-commerce, logistics, and shipping platforms. Features like bulk tracking, webhooks for order status pages, multi-carrier support, and branded tracking pages make it ideal for online stores of any size. See our guide on integrating a branded tracking page on Shopify, WooCommerce, or a custom store.
Do you support OnTrac, Amazon Logistics, and other US regional carriers?
WhereParcel covers all major US national carriers (USPS, UPS, FedEx, DHL) plus OnTrac for West Coast last-mile delivery — see our OnTrac integration guide. Amazon Logistics is not live yet; request it on the community board and we will prioritize it.
What is the UPU S10 tracking number format?
UPU S10 is the international postal tracking standard — 13 characters formatted as 2 letters + 9 digits + 2 letters (country code). It applies to international mail moving through national post operators worldwide. Read our deep dive on the S10 format with check-digit math and validation code.
How do I tell which carrier a tracking number belongs to?
Paste any tracking number into our free Tracking Number Validator — it detects USPS, UPS, FedEx, DHL, OnTrac, UPU S10, and more from the format alone (no API key needed). For ambiguous numbers, the tool shows top candidates and our paid plans support automatic carrier detection.

Talk to Us — We Actually Reply

Have a question? Need a carrier added? Just want to say hi? We're a small team that reads every message. No question is too small — drop by our Discord and let's chat.