Shipment tracking
Use GET /v1/shipment/{shipment}/tracking to read a shipment's movement
timeline. The path accepts either the Cargoplot reference or the numeric
shipment id.
Sea and air journeys are described differently, so the timeline is nested under a key naming the shipment's transport mode. A response carries exactly one of them, decided by the shipment itself.
| Key | Transport mode | Timeline |
|---|---|---|
sea | Sea freight | One entry per container, each with its own events |
air | Air freight | One overall status and one list of events for the shipment |
etd and eta sit at the top level, beside the mode key, because they mean the
same thing whichever mode it is.
Request
curl -H 'X-Cargoplot-Key: <token>' \
'https://api.cargoplot.com/v1/shipment/C2AE-XEE1/tracking'
Sea response
{
"etd": "2026-09-05",
"eta": "2026-09-08",
"sea": {
"containers": [
{
"container_number": "MSKU1234567",
"container_type": "CONTAINER_TYPE_40_HIGH_CUBE",
"status": "CONTAINER_TRACKING_STATUS_SAILING",
"events": [
{
"type": "SEA_TRACKING_EVENT_TYPE_DEPARTED",
"state": "TRACKING_EVENT_STATE_ACTUAL",
"timestamp": "2026-09-05T10:00:00Z",
"location": {
"un_locode": "SGSIN",
"name": "Singapore"
},
"vessel": {
"name": "Example Vessel",
"voyage": "001W"
}
}
]
}
]
}
}
A sea event names its seaport by UN/LOCODE, and carries the vessel and voyage where they are known.
Air response
Air cargo has no container to hang milestones on, so an air timeline sits at the
shipment level: one status for the whole consignment, and one list of events.
{
"etd": "2026-09-05",
"eta": "2026-09-08",
"air": {
"status": "AIR_TRACKING_STATUS_IN_TRANSIT",
"events": [
{
"type": "AIR_TRACKING_EVENT_TYPE_DEPARTED",
"state": "TRACKING_EVENT_STATE_ACTUAL",
"timestamp": "2026-09-05T11:00:00Z",
"location": {
"iata": "SIN",
"name": "Singapore Changi"
},
"flight": {
"number": "KL0887",
"airline": "KLM"
},
"cargo": {
"pieces": 3,
"weight_kg": 412.5,
"volume_cbm": 1.75
}
}
]
}
}
An air event names its airport by IATA code and carries the flight it happened on. Milestones that did not happen in the air — the handover from the shipper, and the final delivery — carry no flight at all.
airline is the carrier on the waybill, and is itself optional — an event can
carry a flight with a number and no airline. Where a consignment flew
partly with another carrier, every event still names the same one, so read it as
the shipment's airline rather than the leg's.
Air status
air.status describes the consignment as a whole. Unlike a container's
status, it is not derived from the event list, so it can say more than the
events do.
Cargo figures, and when they are absent
cargo says how much of the consignment a milestone covered, which is what
tells the legs of a split movement apart when two of them would otherwise look
identical. Each measure names its unit, and a measure that was not reported is
absent rather than 0.
cargo is omitted entirely when more than one of your shipments shares the same air waybill —
the figures on a shared waybill cover everything on it rather than your consignment alone.
The milestones keep the same flight facts — the aircraft's movements are the same for every consignment on board. One consequence to know about, though: two legs that differ only in their cargo figures become indistinguishable once those figures are gone, and are returned as a single milestone rather than two identical ones. So on a shared waybill you cannot tell the legs of a split movement apart, and the event list can be shorter than the number of legs flown.
On a consolidated master air waybill where yours is the only consignment booked through Cargoplot, cargo is
returned, and its figures still describe the whole waybill — including goods
belonging to parties we have no record of. Treat cargo as "how much moved on
this milestone", not "how much of mine moved", unless you know the waybill
carries your consignment alone.
The vocabularies
Every value of SEA_TRACKING_EVENT_TYPE_*, AIR_TRACKING_EVENT_TYPE_*,
CONTAINER_TRACKING_STATUS_*, AIR_TRACKING_STATUS_* and
TRACKING_EVENT_STATE_* is listed with its meaning in the
glossary, along with the
four-letter carrier codes such as GTIN, DEPA and DISC that the same
milestones carry in carrier portals and EDI messages. This endpoint returns the
readable names, never those codes.
Departure and arrival appear in both the sea and the air vocabulary. The two sets are separate, so a switch over one is unaffected as the other grows — but either can gain a member, so handle an unrecognised value rather than assuming your switch is exhaustive. See versioning.
Fields and formats
etd, eta and discharge_date are ISO 8601 calendar dates — "2026-09-05". A date that is not known is absent from the response rather than
present and empty. Event, gate-out and empty-return timestamps are instants, so
they carry a time and use RFC 3339.
Events are ordered from oldest to newest. state tells you whether an event is
TRACKING_EVENT_STATE_EXPECTED or TRACKING_EVENT_STATE_ACTUAL. A container's
status follows its latest actual event, so an expected event does not move the
current status forward.
Location, vessel, voyage, flight, cargo, discharge, gate-out and empty-return details are included when known. Treat absent optional fields as unknown.
When tracking is not available yet
A shipment answers with its mode key even before any movement data exists. On
sea, a known container stays in containers with events: []; on air, events
is []. An empty event list is a valid response, not a reason to discard the
shipment, and etd and eta are still returned.
Do not branch on a particular air.status to detect "nothing yet". An empty
event list can accompany either AIR_TRACKING_STATUS_UNSPECIFIED or
AIR_TRACKING_STATUS_AWAITING_AIRLINE_DATA — the latter is the ordinary
pre-departure case. Test events for emptiness instead.
The endpoint returns 400 when the shipment is transported by road, rail or
express, and 404 when no matching shipment is visible to your account. See
errors for the common error response shapes.