Public Tracking
Use Public Tracking when a customer-facing service needs the current, customer-safe status for one shipment. The endpoint is anonymous, but accepts only the shipment tracking_number; package scan codes and internal IDs are not substitutes.
Request contract
| Method | URL | Use it when |
|---|---|---|
GET | https://mexpress.nz/api/v1/public/tracking/{tracking_number}/ | You need the status projection. |
HEAD | https://mexpress.nz/api/v1/public/tracking/{tracking_number}/ | You need only the status and headers. |
HEAD has the same existence and rate-limit behaviour as GET, but does not return a response body. Use it only when the body would not be consumed.
Before you call it
Use the production API host above—not docs.mexpress.nz—and encode the tracking number as a path segment in your HTTP client.
curl --fail-with-body \
'https://mexpress.nz/api/v1/public/tracking/MX123456789/'curl --head \
'https://mexpress.nz/api/v1/public/tracking/MX123456789/'Read the 200 projection
The shape below is a contract example. Values are illustrative, not test data to hard-code.
{
"tracking_number": "MX123456789",
"status": "out_for_delivery",
"milestone": "out_for_delivery",
"reason": null,
"status_label": "Out for delivery",
"package_count": 1,
"package_summary": { "out_for_delivery": 1 },
"projection_revision": 7,
"occurred_at": "2026-08-02T01:15:00.000000Z",
"timeline": [{
"status": "out_for_delivery",
"label": "Out for delivery",
"occurred_at": "2026-08-02T01:15:00.000000Z"
}]
}| Field | How to use it |
|---|---|
tracking_number | Confirm the shipment displayed to the customer. |
status, status_label | Present the current customer-safe state. |
milestone, reason | Add context only when present. |
package_count, package_summary | Describe the package state at a summary level. |
occurred_at, timeline | Render customer-visible chronology. |
projection_revision | Detect a changed projection in your own cache or UI. |
Present returned labels and timeline as a customer experience, not an operational screen. The response never contains recipient contact or address data, package scan codes, POD media, precise location, driver/device identity, billing data, raw scan evidence, or internal fields.
Failures, rate limits, and safe polling
| Status | Meaning | Your handling |
|---|---|---|
404 | Unknown or not publicly visible. | Show one neutral unavailable result; do not infer or expose the reason. |
429 | The anonymous request is rate limited. | Read the positive Retry-After value and wait at least that long. |
Steady-state limits are 5 requests/second per source IP with a burst of 30. A shared service limit is also applied. For 429, wait for Retry-After, then use exponential backoff with jitter; never use a tight retry loop or treat rate limiting as proof that a tracking number exists.
Poll only when a customer experience needs a refresh. A conservative default is at most once per minute for the same tracking number. Use Webhooks when your backend needs delivery-driven updates instead of frequent polling.
Verification checklist
- [ ]
GETdisplays only documented safe projection fields. - [ ]
HEADis used only when no response body is needed. - [ ]
404has one neutral customer-facing treatment. - [ ]
429honours a positiveRetry-Afterbefore any retry. - [ ] Polling has backoff, jitter, and no tight loop.
Next step
Use Webhooks when your system should receive delivery changes as they occur.