Skip to content

Track a booking

Read a shipment’s tracking status and scan events. There are two endpoints: a public one that needs no API key, and a keyed one that returns a compact event list. See tracking shipments for when to use each and how often to poll.

Both accept the same {reference}: a Transdirect booking id, the courier connote, or a courier tracking reference. It must be 3 to 80 characters of letters, numbers, _ or -.

GET /api/v5/tracking/{reference}

No API key required.

Terminal window
curl https://api.transdirect.com.au/api/v5/tracking/623630
import { getApiV5TrackingByReference } from '@transdirect/api-sdk';
const { data, error } = await getApiV5TrackingByReference({
path: { reference: '623630' },
});

200 OK

{
"reference": "623630",
"matched": true,
"bookingId": "623630",
"connote": "CPBV00123456789",
"deliveryStatus": 2,
"statusPhrase": "In Transit",
"state": "in_transit",
"headline": "In transit",
"summary": "The shipment is moving through the courier network.",
"helpRecommended": false,
"attachmentRecommended": false,
"checkedAt": "2026-10-20T01:15:42.318Z",
"items": [
{
"label": "CPBV00123456789",
"eta": null,
"stage": "in_transit",
"stageCode": 2,
"trackingGraphicUrl": "https://wp-uploads-eb-transdirect-com-au.s3.amazonaws.com/uploads/2019/09/td_tracking_2.png",
"events": [
{
"occurredAt": "2026-10-19T14:02:10+11:00",
"dateText": "2026-10-19 14:02:10",
"stage": "picked_up",
"status": "Picked Up",
"description": "Picked up",
"location": null,
"podUrl": null,
"deliveryDateText": null,
"raw": { "status": "1" }
},
{
"occurredAt": "2026-10-19T21:40:55+11:00",
"dateText": "2026-10-19 21:40:55",
"stage": "in_transit",
"status": "In Transit",
"description": "In transit to destination depot",
"location": null,
"podUrl": null,
"deliveryDateText": null,
"raw": { "status": "2" }
}
]
}
]
}
FieldDescription
referenceThe reference you sent.
matchedtrue when a booking matched.
bookingIdThe matched Transdirect booking id, as a string.
connoteThe courier connote, or null before the courier has issued one.
deliveryStatusInternal numeric status. Prefer state.
statusPhraseShort status text, for example In Transit or Delivered.
stateOverall state: pending, picked_up, in_transit, out_for_delivery, delivered, attention or not_found.
headline, summaryCustomer-facing wording for the current state.
helpRecommendedtrue when the courier reported a problem (state: "attention").
checkedAtWhen this response was built (ISO 8601, UTC).
items[]One entry per consignment, with label (the connote), stage and events[]. Empty until the booking has a connote or a first scan.
items[].events[]Scan events, each with occurredAt (ISO 8601 with offset, or null when the time is unknown), dateText, stage (pending, picked_up, in_transit, out_for_delivery, delivered, exception or unknown), status and description. location, podUrl and deliveryDateText are null when the courier does not supply them.
StatusBodyCause
400{"success":false,"error":{"name":"ZodError","message":"..."}}The reference is shorter than 3 characters, longer than 80, or contains other characters. message is a JSON-encoded list of issues.
404The same shape as a 200, with matched: false and state: "not_found"Nothing matched the reference.
502{"error":"..."}The tracking service did not return a usable answer. Retry later.

A 404 body looks like this:

{
"reference": "NOTAREF123",
"matched": false,
"bookingId": null,
"connote": null,
"deliveryStatus": null,
"statusPhrase": "No booking matched",
"state": "not_found",
"headline": "No shipment found",
"summary": "Check the reference and try again. The courier may also need more time after pickup to publish the first scan.",
"helpRecommended": false,
"attachmentRecommended": false,
"checkedAt": "2026-10-16T04:31:09.111Z",
"items": []
}
GET /api/v5/bookings/track/{id}

Requires your API key in the api-key header. {id} takes the same values as {reference} above.

Terminal window
curl https://api.transdirect.com.au/api/v5/bookings/track/623630 \
-H "api-key: $TD_API_KEY"
import { client, getApiV5BookingsTrackById } from '@transdirect/api-sdk';
client.setConfig({ headers: { 'api-key': process.env.TD_API_KEY! } });
const { data, error } = await getApiV5BookingsTrackById({
path: { id: '623630' },
});

200 OK. The object has one key, the connote (or your reference when there is no connote yet), holding the events.

{
"CPBV00123456789": [
{
"date": "2026-10-19 14:02:10",
"status": "Picked Up",
"description": "Picked up",
"location": null,
"pod_url": null,
"delivery_date": null,
"track_status": "picked_up"
},
{
"date": "2026-10-19 21:40:55",
"status": "In Transit",
"description": "In transit to destination depot",
"location": null,
"pod_url": null,
"delivery_date": null,
"track_status": "in_transit"
}
]
}
FieldDescription
dateWhen the scan was recorded, as stored (YYYY-MM-DD HH:MM:SS).
statusStatus text, for example In Transit.
descriptionThe courier’s scan description.
track_statuspicked_up, in_transit, out_for_delivery, delivered, exception or unknown.
location, pod_url, delivery_datenull when the courier does not supply them.

A booking with a connote but no scans yet returns the connote with an empty list, for example {"CPBV00123456789": []}.

StatusBodyCause
400{"error":"id must be a booking id or tracking reference"}The reference is shorter than 3 characters, longer than 80, or contains other characters.
401{"error":"missing_api_key"} or {"error":"invalid_api_key"}No key, or a key that is not active.
404{"NOTAREF123":[]}Nothing matched. The body is keyed by your reference with an empty list.
429{"error":"rate_limited"}More than 600 requests a minute on this key. Wait for the retry-after seconds.

Open the API Explorer and find Track a public shipment reference to call the public endpoint without a key.