Trace docs
One API key. One endpoint. Clean, normalized tracking for any package.
Quickstart
Create an account
Sign up and open the dashboard.
Generate a key
Copy your trc_live key from the API keys page.
Track a package
Send one POST request to /v1/track — that's the whole API.
curl https://api.traceapi.dev/v1/track \
-H "Authorization: Bearer trc_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"tracking_number":"YT2412345678"}'Authentication
Every request goes to the same base URL. Send your API key as a Bearer token and keep live keys on your server, never in public frontend code.
https://api.traceapi.devAuthorization: Bearer trc_live_xxxxxxxxxxxxx/v1/track
Track one shipment. Trace detects the likely carrier, fetches current tracking data, normalizes status, and returns carrier events when available.
{ "tracking_number": "YT2412345678" }{
"tracking_number": "YT2412345678",
"carrier": {
"code": "yunexpress",
"name": "YunExpress",
"type": "dropshipping"
},
"status": "in_transit",
"estimated_delivery": null,
"events": [
{
"status": "in_transit",
"description": "Departed origin facility",
"location": "Shenzhen, China",
"timestamp": "2026-07-03T09:30:00.000Z"
}
],
"cached": false,
"request_id": "req_abc123",
"last_checked_at": "2026-07-03T10:00:00.000Z"
}Response fields
Every tracking response uses the same shape, whether the lookup is fresh, served from cache, or the carrier has no new scans yet.
| Field | Type | Description |
|---|---|---|
| tracking_number | string | The tracking number exactly as submitted (trimmed). |
| carrier.code | string | Stable carrier identifier, e.g. yunexpress or ups. See carrier codes below; unknown when no pattern matches. |
| carrier.name | string | Human-readable carrier name. |
| carrier.type | string | premium, standard, domestic, regional, dropshipping, freight, or unknown. |
| status | string | Normalized shipment status. One of the statuses listed below. |
| estimated_delivery | string | null | ISO 8601 date when the carrier provides one, otherwise null. |
| events | array | Normalized tracking history. Empty when the carrier has not published scans. |
| events[].status | string | Per-event status using the same enum as status. |
| events[].description | string | Customer-safe, human-readable event copy. |
| events[].location | string | null | City / country when available, otherwise null. |
| events[].timestamp | string | ISO 8601 scan time. |
| cached | boolean | true when the response was served from the 30-minute cache. |
| request_id | string | Unique id for this request; batch calls share one id across results. |
| last_checked_at | string | ISO 8601 time the upstream lookup last ran. |
pending Label created; the carrier has not received the package yet.
in_transit Package is moving through the carrier network.
out_for_delivery On the vehicle for final delivery.
customs Held in customs or clearance.
delivered Delivered.
exception Delivery problem: failed attempt, held, returned, or customs delay./v1/track/batch
Track up to 20 shipments in one request. Batch calls count each tracking number toward usage.
{
"tracking_numbers": [
"YT2412345678",
"1Z999AA10123456784"
]
}Carrier codes
The carrier.code values returned by the API, with the tracking number prefixes used for auto-detection. Unrecognized numbers return unknown and Trace still attempts a lookup.
Carriers shown as Numeric use purely numeric tracking numbers with no alphabetic prefix, so they are matched by length and digit patterns rather than a prefix string.
| Code | Carrier | Type | Prefixes | Regions |
|---|---|---|---|---|
| yunexpress | YunExpress | dropshipping | YT | CN to US, CN to EU, CN to AU |
| epacket | ePacket (China Post) | dropshipping | LX, LY, LZ | CN to Global |
| 4px | 4PX | dropshipping | 4PX, FPXE | CN to US, CN to EU |
| cainiao | Cainiao | dropshipping | CAIN, LP | CN to Global |
| cjpacket | CJ Packet | dropshipping | CJPAK | CN to US, CN to EU |
| yanwen | Yanwen | dropshipping | YW | CN to Global |
| sfexpress | SF Express | dropshipping | SF | CN to Global |
| jtexpress | J&T Express | dropshipping | JT | SEA to Global |
| suntek | SunTek Express | dropshipping | STK | CN to US |
| dhl | DHL Express | premium | JD | Global |
| dhlecommerce | DHL eCommerce | standard | GM | Global |
| tnt | TNT | premium | GE | Global |
| aramex | Aramex | standard | ARX | Middle East to Global |
| usps | USPS | domestic | 9, LZ, EC | US |
| fedex | FedEx | premium | 7 | US, Global |
| ups | UPS | premium | 1Z | US, Global |
| royalmail | Royal Mail | domestic | AA, ZZ | UK |
| dpd | DPD | domestic | Numeric | EU |
| gls | GLS | domestic | Numeric | EU |
| hermes | Evri (Hermes) | domestic | Numeric | UK |
| postnl | PostNL | domestic | 3S | NL, EU |
| deutschepost | Deutsche Post | domestic | RR | DE, EU |
| laposte | La Poste | domestic | CB | FR, EU |
| correos | Correos (Spain) | domestic | PQ | ES, EU |
| canadapost | Canada Post | domestic | Numeric | CA |
| australiapost | Australia Post | domestic | 33, 99 | AU |
| japanpost | Japan Post | domestic | EJ, RJ | JP |
| indiapost | India Post | domestic | EE, RR | IN |
| ninjavan | Ninja Van | regional | NV | SEA |
| correiosbr | Correios (Brazil) | domestic | SS, OB | BR |
| ontrac | OnTrac | regional | C | US |
| lasership | LaserShip | regional | 1LS | US |
| chronopost | Chronopost | premium | X | FR, EU |
| colissimo | Colissimo | domestic | 6A, 6C, 8N | FR, EU |
| mondialrelay | Mondial Relay | regional | Numeric | FR, BE, ES, EU |
| bpost | bpost | domestic | CD, CE | BE, EU |
| postnord | PostNord | domestic | Numeric | DK, SE, NO, FI |
| bring | Bring | domestic | Numeric | NO, Nordics |
| swisspost | Swiss Post | domestic | 99 | CH, EU |
| austrianpost | Austrian Post | domestic | Numeric | AT, EU |
| posteitaliane | Poste Italiane | domestic | IT | IT, EU |
| inpost | InPost | regional | Numeric | PL, UK, EU |
| packeta | Packeta | regional | Z | CZ, SK, EU |
| yodel | Yodel | domestic | JD | UK |
| parcelforce | Parcelforce | premium | PB, PN | UK, Global |
| anpost | An Post | domestic | Numeric | IE |
| seur | SEUR | regional | Numeric | ES, PT |
| mrw | MRW | regional | Numeric | ES, PT |
| ctt | CTT Portugal Post | domestic | DA, LX | PT |
| ptt | PTT Posta | domestic | RR, CP | TR |
| israelpost | Israel Post | domestic | Numeric | IL |
| saudipost | Saudi Post | domestic | Numeric | SA |
| emiratespost | Emirates Post | domestic | Numeric | AE |
| qatarpost | Qatar Post | domestic | Numeric | QA |
| singaporepost | Singapore Post | domestic | RC, RF, RR | SG, Global |
| hongkongpost | Hongkong Post | domestic | RB, RC | HK, Global |
| thailandpost | Thailand Post | domestic | EE, RR | TH |
| vietnampost | Vietnam Post | domestic | Numeric | VN |
| poslaju | Pos Laju | domestic | EL, ER | MY |
| phlpost | PHLPost | domestic | Numeric | PH |
| koreapost | Korea Post | domestic | EG, RR | KR, Global |
| taiwanpost | Taiwan Post | domestic | Numeric | TW |
| nzpost | New Zealand Post | domestic | NZ | NZ |
| chinapost | China Post | standard | RA, RB, RC, EA, EB | CN, Global |
| ems | EMS | standard | E | Global |
| speedaf | Speedaf | regional | SP | CN, Africa, Global |
| delhivery | Delhivery | domestic | Numeric | IN |
| bluedart | Blue Dart | premium | Numeric | IN |
| ekart | Ekart | domestic | FMPC, FMPP | IN |
| dtdc | DTDC | domestic | Numeric | IN |
| xpressbees | XpressBees | domestic | Numeric | IN |
| aramexau | Aramex Australia | regional | Numeric | AU |
| fastway | Fastway | regional | Numeric | AU, IE, NZ |
| toll | Toll | regional | Numeric | AU, APAC |
| startrack | StarTrack | premium | Numeric | AU |
| purolator | Purolator | premium | Numeric | CA |
| canpar | Canpar | regional | Numeric | CA |
| tforce | TForce Freight | regional | Numeric | US, CA |
| estes | Estes | freight | Numeric | US |
| xpo | XPO | freight | Numeric | US, EU |
| yrc | YRC Freight | freight | Numeric | US |
| olddominion | Old Dominion Freight Line | freight | Numeric | US |
| rlcarriers | R+L Carriers | freight | Numeric | US |
| saia | Saia | freight | Numeric | US |
| estafeta | Estafeta | domestic | Numeric | MX |
| redpack | Redpack | domestic | Numeric | MX |
| chilexpress | Chilexpress | domestic | Numeric | CL |
| servientrega | Servientrega | regional | Numeric | CO, EC |
| urbano | Urbano | regional | Numeric | AR, PE |
Webhooks
Add an endpoint in the dashboard and Trace will POST signed tracking events to your app. You can test delivery from the Webhooks page before using it in production.
tracking.updated
tracking.delivered
tracking.exception{
"event_id": "evt_abc123",
"event_type": "tracking.updated",
"created_at": "2026-07-03T10:00:00.000Z",
"tracking": {
"tracking_number": "YT2412345678",
"status": "in_transit",
"carrier": {
"code": "yunexpress",
"name": "YunExpress"
},
"events": []
}
}Trace-Event: tracking.updated
Trace-Timestamp: 1783072800
Trace-Signature: t=1783072800,v1=signature_hashimport crypto from "node:crypto";
const expected = crypto
.createHmac("sha256", webhookSecret)
.update(`${req.headers["trace-timestamp"]}.${rawBody}`)
.digest("hex");
const trusted = req.headers["trace-signature"]?.includes(`v1=${expected}`);Tracking playground
Test a live tracking request from the docs. Your key is sent only to the Trace API.
Client snippets
Copy-paste clients for your stack — no dependencies, same request shape the official Trace SDKs wrap.
export async function trackPackage(apiKey, trackingNumber) {
const response = await fetch("https://api.traceapi.dev/v1/track", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ tracking_number: trackingNumber })
});
if (!response.ok) throw new Error("Trace request failed");
return response.json();
}import requests
def track_package(api_key, tracking_number):
response = requests.post(
"https://api.traceapi.dev/v1/track",
headers={"Authorization": f"Bearer {api_key}"},
json={"tracking_number": tracking_number},
timeout=30,
)
response.raise_for_status()
return response.json()Limits and quotas
| Plan | Requests / minute | Monthly lookups |
|---|---|---|
| Free | 10 | 500 |
| Startup | 60 | 10,000 |
| Business | 120 | 50,000 |
| Enterprise | 300 | Unlimited |
Errors
Every error returns the same shape: { "error": { "code", "message" } } with one of the codes below.
unauthorized401Missing or invalid API key.
invalid_request400Required request data is missing or malformed.
rate_limited429Per-minute request limit exceeded.
monthly_quota_exceeded402Monthly lookup quota exceeded for the current plan.
internal_error500Trace could not complete the request.
Health check
{ "ok": true, "service": "trace-api" }