Track a parcel
Detects the carrier from the number (UPU S10 check digit, carrier number patterns), asks every matching connected source in parallel and returns the one with the most scans, events oldest first. Connected today: Nova Poshta, Cainiao (AliExpress, China Post and partner lines), 4PX, PostNL, InPost, bpost, TNT and EMS through the UPU network. The example is a delivered Nova Poshta parcel.
Query parameters
Tracking number, 8 to 34 letters and digits. Spaces and dashes are ignored.
Skip detection and ask one source: novaposhta, cainiao, 4px, postnl, inpost, bpost, tnt, ems.
Nova Poshta only: the sender or recipient phone. Without it the answer has status and cities, with it the full addresses.
Response schema
19 fields
Derived from the example response, nested as the JSON is.
data
The payload. Everything an endpoint returns sits under this key.
Where the answer on this call came from: direct_carrier or warm_db.
Carrier name, falling back to the SCAC when we hold no name.
Current normalised status of the shipment. Ocean lifecycle order: discharged, available, delivered, returned_empty. Two values end a shipment, delivered and returned_empty, and returned_empty outranks delivered.
Origin code (airport IATA or UN/LOCODE).
Destination code (airport IATA or UN/LOCODE).
Milestone timeline, oldest to newest.
events[]
The event in plain words. A non-actual event is tagged "(planned)".
UN/LOCODE for the event, or null when the carrier gave no place.
extra
Gross weight in kilograms.
Carrier service or loop name.
Arrival time (ISO 8601). Null when the carrier publishes none and we cannot predict one.
Errors
A failure carries { "ok": false, "error": { "code", "message", "severity" } }. Branch on the code, and log the message.
No key in Authorization or x-api-key.
The key is unknown or revoked.
The number is not 8 to 34 letters and digits.
No connected source knows this number. tried[] lists the sources asked.
More than 40 requests in one minute from one client.
A source did not answer. Retry in a minute.
Status vocabulary
status is one of info_received, in_transit, out_for_delivery, delivered, exception, unknown. status_label keeps the wording of the carrier, in its language.
Sources
Only public tracking endpoints that answer without a carrier contract are connected. DHL, La Poste, PostNord and the aggregators need a developer key and come next.
curl 'https://parcel.navo24.com/v1/parcel/track?number=59000000000000&carrier=novaposhta&phone=380501234567' \
-H "Authorization: Bearer tmcp_YOUR_API_KEY"const res = await fetch("https://parcel.navo24.com/v1/parcel/track?number=59000000000000&carrier=novaposhta&phone=380501234567", {
headers: {
"Authorization": "Bearer tmcp_YOUR_API_KEY"
}
});
const data = await res.json();import requests
res = requests.get(
"https://parcel.navo24.com/v1/parcel/track?number=59000000000000&carrier=novaposhta&phone=380501234567",
headers={"Authorization": "Bearer tmcp_YOUR_API_KEY"},
)
data = res.json() {
"data": {
"source": "novaposhta",
"carrier": "Nova Poshta",
"number": "59000000000000",
"status": "delivered",
"status_label": "Відправлення отримано",
"origin": "Житомир",
"destination": "Бориспіль",
"events": [
{
"at": "2026-08-01T19:18:00+03:00",
"label": "Shipment created",
"location": "м. Житомир, Відділення №15: вул. Івана Сірка, 63 (с. Оліївка)"
},
{
"at": "2026-08-02T08:02:00+03:00",
"label": "Arrived at the branch",
"location": "м. Бориспіль, Відділення №8 (до 30 кг): вул. Соцмістечко, 157а"
},
{
"at": "2026-08-04T08:10:00+03:00",
"label": "Received by the recipient",
"location": "м. Бориспіль, Відділення №8 (до 30 кг): вул. Соцмістечко, 157а"
}
],
"extra": {
"weight_kg": 5.47,
"service": "WarehouseWarehouse",
"cargo": "Parcel",
"eta": "2026-08-02T08:02:00+03:00"
},
"also": [],
"tried": [
"Nova Poshta"
]
}
}