Container detail
The full record: status, route, vessel, milestone timeline and the basis for the ETA. This is the widest payload in the API and it carries more keys than the example below, including the per-field provenance envelope. The fields shown are the stable core.
Path parameters
The container UUID returned by create, list or lookup. Not the container number.
Response schema
418 fields
Derived from the example response, nested as the JSON is.
The response contract this build answers, as a date. Pin it in your client and nothing in the shape below moves under you.
Whether the request succeeded.
data
The payload. Everything an endpoint returns sits under this key.
Stable identifier for the record. On the tracking endpoints this is the container UUID, except on a portfolio summary row, where it is the container number.
Your organisation. Every keyed read is scoped to it, so this is always your own id: it exists so a record stays self-describing once exported.
The container number, or null when the record was tracked by a bill of lading or booking that has not yet resolved to a box.
The bill of lading, or null when the record was not tracked by one.
The booking reference, or null when the record was not tracked by one.
Carrier SCAC.
Carrier name.
ISO 6346 size and type code as the carrier filed it, for example 45G1. Null when the carrier stated none.
Size in TEU: 1 for a 20ft box, 2 for a 40ft. Null when the size is unknown.
Plain-language equipment type, for example Reefer or Dry. Null when the carrier stated none.
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 port UN/LOCODE, or null when the carrier named no origin we could resolve.
Destination port UN/LOCODE, or null when unresolved.
Origin port name, falling back to its UN/LOCODE.
Destination port name, falling back to its UN/LOCODE.
Arrival time (ISO 8601). Null when the carrier publishes none and we cannot predict one.
True when the ETA is still a forecast, false when it is the actual arrival, null when there is no ETA at all. Never read a date alone as a promise.
How often this lane arrives on time, as a percentage. Null on a lane too thin to score.
When the box was discharged, which is when free time starts counting. Null when no discharge is on file yet.
Free days the terms allow at this port. Null when no terms and no published tariff apply.
The last day free of charge, computed from the discharge and the free days. Null when either is missing.
True when the free-time clock on this box is a concern.
Demurrage charged so far on this box, US dollars. Null when no rate applies, which is not the same as zero owed.
Your own labels on this box. Filter the list endpoint with them.
Your own free-text note on this box. Null when you have written none.
When you started tracking this box (ISO 8601).
When we last asked the carrier (ISO 8601).
Which polling cadence this box sits in (pre_departure, transit, arrival, dwell). It decides how often we ask the carrier, and moves on its own as the shipment progresses.
When tracking stopped, or null while the box is still active.
The container number, bill of lading or booking this record tracks.
What the identifier is. The keyed surface uses container_id, bill_of_lading or booking; the public tracker returns booking_number for the third.
IMO of the hull carrying the box now. Null before loading and after discharge.
Carrier voyage number for the current leg. Null when the carrier publishes none.
Daily demurrage rate in force at the destination, US dollars. Null when neither your terms nor a published tariff cover the port.
The last day before demurrage accrues, or null when no terms are on file.
What caused the most recent carrier check: a schedule, your recheck call, or a webhook. Null when the box has only ever been polled by the scheduler.
Latitude from a physical IoT tracker on the box, when you feed us one. Null on the great majority of boxes, which have no device.
Longitude from that device. Null with the latitude.
When the device last reported. Null when there is no device.
True when the device raised an alert, for example a door opening or a temperature excursion.
Why customs is holding the box, when the carrier names a reason. Null when there is no hold.
When the hold started. Null when there is no hold.
Equipment size, for example 40HC. Null when the carrier did not state it.
Equipment family as the carrier names it. Null when unstated.
The type half of the ISO 6346 code (G1 for a general-purpose box, R1 for a reefer). Null when unstated.
When we gave up resolving this reference. Null while we are still trying, which is the normal state.
A route problem we detected, for example a destination change or a missed connection. Null when the route is behaving.
Departure the carrier planned or actually filed for the load port. Null when the carrier publishes none.
Name of that hull. Null when we hold no name for the IMO.
Cargo (gate) cutoff at the load port. Null when the carrier does not publish it, or when the ship has already sailed: read field_provenance to tell those apart.
VGM filing cutoff. Null under the same rules as cargo_cutoff_at.
Shipping-instruction cutoff. Null under the same rules as cargo_cutoff_at.
Customs-release cutoff at the load port. Null under the same rules as cargo_cutoff_at.
Where the cutoffs came from when they were not on the carrier response, for example a terminal schedule. Null when no enrichment ran.
Why a reference could not be resolved: invalid_number, not_found or bl_booking_unresolved. Null means resolved or still resolving.
When the record itself last changed in our database, which includes bookkeeping writes. For "when did we last learn something about the shipment", read last_updated_at.
Why tracking stopped: your delete call, or an automatic close-out once the box finished its cycle. Null while active.
Internal bookkeeping: when the "container identified" digest was sent for this box. Null when none was sent.
Internal bookkeeping: when a lessor or intermediary lookup last enriched this record. Null when none has run.
Groups every box created by one bulk import, so their digest fires once per batch. Null on a single manual add.
Carrier seal on the box. Null unless the carrier publishes it, which most do not on a track response.
The scope of the move the carrier is performing, for example port to port or door to door. Null when unstated.
Verified gross mass, kilograms. Null until the shipper files a VGM and the carrier publishes it.
Gross weight of the loaded box, kilograms. Null when the carrier publishes none.
Pieces inside the box. Null when the carrier publishes no cargo particulars.
Unit the package count is in, for example CTN or PLT. Null with the count.
Cargo volume, cubic metres. Null when the carrier publishes none.
A special handling requirement filed on the shipment, for example a reefer set point. Null when none.
Cargo and commercial particulars exactly as the carrier filed them, when a carrier publishes any. Null on most lines. Read the typed fields above instead: this is kept so a value we did not map is never lost.
The surface the box was added from. Null on records added before we recorded it.
Where the answer on this call came from: direct_carrier or warm_db.
route_data
The route in the shape our map consumers read: the legs, the current pin and the AIS block. Also returned on the compatibility surface, field for field.
The legs of the drawn route. This is the map geometry, and it is not the four-point route block above.
route[]
from
Where the leg starts.
Latitude.
Longitude.
Human-readable name.
State, province or region of the port, when the gazetteer holds one.
UN/LOCODE of the place.
Country name.
IANA time zone of the place. Null when we could not resolve the port.
ISO 3166-1 alpha-2 country code.
to
Where the leg ends.
Latitude.
Longitude.
Human-readable name.
State, province or region of the port, when the gazetteer holds one.
UN/LOCODE of the place.
Country name.
IANA time zone of the place. Null when we could not resolve the port.
ISO 3166-1 alpha-2 country code.
The drawn geometry of the leg as lat and lng pairs. Empty on an inland leg, where we do not draw a line we cannot verify.
Event code, for example DEPA or LOAD.
Vessel currently carrying the container, or null when we hold neither a name nor an IMO. Its lat and lng are always null here; the keyed endpoints carry the live position under vessel_position.
The mode carrying the leg, for example VESSEL or TRUCK, when the carrier names it. Null when it does not.
Where to draw the box right now, as a lat and lng pair. Null when we have nothing solid enough to place it.
How the pin was placed: ais_vessel_position from a real fix, route_reckoning when computed along the route, or a port when the box is sitting at one.
ais
The vessel and port dates as an AIS-shaped block, kept in the layout integrators migrating from the older API already parse. Null when we hold no vessel.
data
The AIS-shaped payload. It is nested under a data key because that is the layout of the API this surface is compatible with, not because it is a second envelope.
vessel
The hull these dates belong to.
IMO number of the vessel.
Flag state of the vessel, as a two-letter code. Null when we hold none.
Vessel MMSI. Null when we hold none.
Human-readable name.
Vessel radio call sign. Null when we hold none.
last_event
The most recent vessel move behind these dates.
When it happened, as a port wall-clock string without an offset, which is the layout this block has always used.
Carrier voyage number, when published. Null otherwise.
The carrier own phrasing for the event, falling back to our word for the code.
When this AIS block was last rebuilt.
arrival_port
The arrival call these dates describe.
The short port code the compatible API prints next to the UN/LOCODE. Read locode for the standard one.
UN/LOCODE of the place.
The date of the call, as a port wall-clock string with no offset, which is the layout this block has always used. Read date_label to know whether it is an estimate or an actual.
Which kind of date the neighbouring value is: ETA, ETD, ATA or ATD. Read it before treating a date as an actual.
ISO 3166-1 alpha-2 country code.
departure_port
The departure call these dates describe.
The short port code, as above. Read locode for the standard one.
UN/LOCODE of the place.
The date of the call, in the same wall-clock layout. Read date_label before treating it as an actual.
Which kind of date the neighbouring value is: ETA, ETD, ATA or ATD. Read it before treating a date as an actual.
ISO 3166-1 alpha-2 country code.
discharge_port
The discharge call these dates describe.
The short port code, as above. Read locode for the standard one.
UN/LOCODE of the place.
The date of the sea discharge, in the same wall-clock layout. Read date_label before treating it as an actual.
Which kind of date the neighbouring value is: ETA, ETD, ATA or ATD. Read it before treating a date as an actual.
ISO 3166-1 alpha-2 country code.
Human-readable name.
last_vessel_position
The most recent fix for the hull, with the time it was taken.
Latitude.
Longitude.
When the fix was taken.
Whether the AIS block carries data, and why not when it does not.
source
Who produced the route and the AIS in this block. Read it before attributing our route to anybody else.
Machine name of the producer.
Display name of the producer.
How the drawn line was produced, for example trackingmcp_computed.
Which vessel-position source fed the AIS block.
One sentence of provenance in plain language.
True when the pin was computed rather than observed. Never present a computed pin as a sighting.
The observation the estimate was anchored to. Null when there was none to anchor to.
Which generation of our route-drawing produced this geometry. Bumped when the drawing changes, so a cached line can be invalidated.
When this route block was last built.
Registered owner of the box, resolved from its BIC prefix. Null when the prefix is unregistered.
Leasing company, when the box is leased rather than carrier-owned. Null otherwise.
Who holds the box on lease. Null unless the lessor publishes it.
An unconfirmed carrier candidate derived from lessor data. Never a confirmed carrier: read carrier_code for that.
The box status as the lessor reports it, for example on-hire or off-hire. Null when we hold no lessor record.
When we last asked the lessor. Null when we never have.
Redelivery booking for the empty. Null until one exists.
When the empty is due back. Null until scheduled.
Where the empty is due back. Null until scheduled.
The depot the empty is due back at. Null until scheduled.
Lease contract the box sits on. Null unless published.
Lease type, for example long-term or one-way. Null unless published.
Who built the box. Null unless the lessor publishes it.
When the box went on hire. Null unless published.
Where it went on hire. Null unless published.
The depot it went on hire at. Null unless published.
Where a request to connect this carrier stands, when the line needs one. Null when the carrier is already connected.
When you asked to be told the connector went live. Null when you did not ask.
When we told you it went live. Null when we have not.
field_provenance
Per-field account of WHY a declared field is empty, keyed by field name. This is the difference between "the carrier does not publish it", "your contract terms would unlock it" and "it does not apply to this shipment".
cargo_cutoff_at
Cargo (gate) cutoff at the load port. Null when the carrier does not publish it, or when the ship has already sailed: read field_provenance to tell those apart.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
si_cutoff_at
Shipping-instruction cutoff. Null under the same rules as cargo_cutoff_at.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
vgm_cutoff_at
VGM filing cutoff. Null under the same rules as cargo_cutoff_at.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
customs_release_cutoff_at
Customs-release cutoff at the load port. Null under the same rules as cargo_cutoff_at.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
discharge_datetime
When the box was discharged, which is when free time starts counting. Null when no discharge is on file yet.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
free_days
Free days the terms allow at this port. Null when no terms and no published tariff apply.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
demurrage_last_free_day
The last day before demurrage accrues, or null when no terms are on file.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
demurrage_daily_rate_usd
Daily demurrage rate in force at the destination, US dollars. Null when neither your terms nor a published tariff cover the port.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
demurrage_at_risk
True when the free-time clock on this box is a concern.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
last_updated_at
The more recent of the carrier check and the AIS fix: when we last learned anything about this shipment.
Why the field stands where it does: resolved, contract_required, not_published, not_applicable or awaiting_carrier.
What would change the state: supply_terms, wait, or do_not_expect when nothing will.
Where the answer on this call came from: direct_carrier or warm_db.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The reasoning behind the state, in one sentence, so a support answer does not need our source.
field_provenance_summary
Counts of the declared cutoff and demurrage fields by state, so you can tell "we do not have it" from "your contract terms would unlock it".
Declared fields we hold a value for.
Declared fields that stay empty until you supply your own free-time terms.
Declared fields this carrier does not publish.
Declared fields that do not apply to this shipment.
Declared fields we expect but have not received yet.
True when supplying free-time terms would fill at least one empty field.
The carrier payload behind this record, kept for support and replay. Null unless retention is on for your organisation. Not a stable shape: it is whatever that carrier sent.
origin_coord
Coordinate of the origin port. Null when the port could not be placed.
Latitude.
Longitude.
True when the coordinate is a place centroid rather than a terminal position. Do not measure distances against an approximate point.
What the approximate point was derived from. Null when the coordinate is exact.
destination_coord
Coordinate of the destination port. Null when the port could not be placed.
Latitude.
Longitude.
True when the coordinate is a place centroid rather than a terminal position. Do not measure distances against an approximate point.
What the approximate point was derived from. Null when the coordinate is exact.
True on a sample reference. Sample boxes return typical data and have no live carrier feed.
The boxes a bill of lading or booking resolves to, each with its own timeline. Null on a plain container lookup.
Kept for older clients: the AIS-broadcast ETA, also present as vessel_position.eta_ais. Null when the hull broadcasts none.
Milestone timeline, oldest to newest.
events[]
Stable identifier for the record. On the tracking endpoints this is the container UUID, except on a portfolio summary row, where it is the container number.
Your organisation. Every keyed read is scoped to it, so this is always your own id: it exists so a record stays self-describing once exported.
The container number this row is about.
The id this event carries on the DCSA /v2 surface, so the same physical event can be matched across both surfaces.
DCSA event category: SHIPMENT, TRANSPORT or EQUIPMENT.
DCSA classifier: ACT, EST or PLN.
When the event happened or is forecast to (ISO 8601).
When we recorded the event, not when it happened. A late-filed event can be recorded days after the fact.
DCSA transport code on a vessel move: ARRI for arrival, DEPA for departure. Null on an equipment event.
Carrier code for why a move slipped. Null on most lines, which publish no reason.
The carrier own free-text remark about a change to this event. Null when it sent none.
DCSA equipment code on a box move, for example GTOT for a gate-out or LOAD for a load. Null on a transport event.
EMPTY or LADEN on an equipment event. Present only when the carrier reported the fill state: the standard has no unknown value and we do not invent one. It is not an end-of-shipment signal.
The container the event happened to.
ISO 6346 equipment code as filed on this event. Null when the carrier stated none.
DCSA shipment code on a documentation move. Null on the other two families.
The document the shipment event refers to, on the lines that publish one. Null otherwise.
What that document is, for example a bill of lading. Null with the id.
The carrier stated reason for the event, on the lines that publish one. Null otherwise.
transport_call
The location, vessel and voyage of the port call. Null when the carrier gave no call.
location
UN/LOCODE for the event, or null when the carrier gave no place.
Port name as the carrier wrote it, unmapped. Read the UN/LOCODE next to it for the resolved port.
UN/LOCODE.
Extra carrier references filed against the event. Null when the carrier filed none.
Seal numbers filed against the event. Null when the carrier filed none.
How sure we are of the normalised code: REPORTED when the carrier gave a code we map directly, INFERRED when we derived it from its wording, UNKNOWN when neither was possible.
The code the source used, before normalisation. Null when the source sent no code.
The source own event object, kept verbatim. Null when nothing needed keeping. Not a stable shape.
When the record was created (ISO 8601).
The carrier own id for the event, when it publishes one. Null on most lines. Read id for our stable id.
Same instant as event_date_time, under the name the earlier API used. Kept so old integrations keep working.
Machine-readable event code, for example LOAD, DISC, GTIN, GTOT, ARRI, DEPA. Null when the carrier sent none.
raw_payload
The connector event exactly as it was stored, so a value we did not map is never lost. Treat it as evidence, not as API surface: its keys vary by carrier.
Event timestamp (ISO 8601), or null when the carrier gave none.
IANA time zone of the place. Null when we could not resolve the port.
UN/LOCODE port code. On a tracking event it is canonicalised, and null when the carrier named no port.
True when the event happened. False means planned or estimated.
Resolved port name.
Machine-readable event code, for example LOAD, DISC, GTIN, GTOT, ARRI, DEPA. Null when the carrier sent none.
IMO number of the carrying vessel, or null when unknown.
The carrier own phrasing for the event, falling back to our word for the code.
Which source produced the event: carrier for a direct carrier call, searates or twin_share when it reached us another way.
Name of the carrying vessel, or null when the carrier named none.
Which family the code belongs to: EQUIPMENT, TRANSPORT or SHIPMENT.
Carrier voyage number.
What the stored instant MEANS: utc for a true instant, port_local for a wall-clock we could not place. Every value on the documented fields above is already a true instant.
The port wall-clock carried alongside the instant, inside the raw payload.
How the instant was established during normalisation. Diagnostic, not contract.
Mode the source named for the move. Null when it named none.
How precise the carrier was: datetime, or date when it gave a day with no time. A date-only event must never be read as midnight.
Minutes to add to the UTC instant to reach the local wall-clock. Null with the local time.
The exact rung the source was resolved on, kept verbatim so a coarse bucket never hides the detail. Diagnostic.
The port wall-clock for the same moment, naive and with no offset, exactly as a terminal prints it. Null when we could not place the port, and a null here means we do not know, never assume UTC.
Minutes to add to the UTC instant to reach the local wall-clock. Null with the local time.
IANA zone of the port, which survives a DST change in a way a bare offset cannot. Null when the port could not be resolved.
Internal marker for how this row timestamp was established. Do not branch on it: read the UTC instant and, if you need port time, its three local companions.
The step in plain language, for example Gated out.
The shipment as a reader story: carrier events plus the moves we inferred between them, in order. Empty until the first event lands.
journey_timeline[]
Stable identifier for the record. On the tracking endpoints this is the container UUID, except on a portfolio summary row, where it is the container number.
carrier_event when a carrier filed it, trackingmcp_inference when we derived the step from surrounding events.
DCSA classifier: ACT for actual, EST for estimated, PLN for planned.
When the step happened (UTC). Null when the source gave a wall-clock we could not place.
The step in plain language, for example Gated out.
Resolved port UN/LOCODE. Null when the carrier location could not be placed.
Resolved port name.
Terminal or depot inside the port, when the carrier names one. Null otherwise.
The event ids this step was built from, so an inference can always be traced back.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
The event in plain words. A non-actual event is tagged "(planned)".
The role the port plays on this route: origin, transshipment or destination. Null when the route is not resolved enough to say.
The voyage milestone this step marks, when it marks one. Null on ordinary steps.
Count of shipments in an exception state: customs hold, rolled, delayed or at transshipment.
How far back the timeline reaches on your plan, in days.
The leg the box is on now. Null before departure and after final discharge.
The voyage broken into legs. Empty when we cannot yet split it.
vessel_position
Live AIS position of the carrying vessel. Null when we hold no IMO or no fix yet.
IMO number of the vessel.
Human-readable name.
Latitude.
Longitude.
Speed over ground, in knots.
Heading in degrees.
Navigational status as reported by AIS, for example "Under way using engine" or "Moored". We drop a moored or anchored claim that the position contradicts.
When we last wrote the position row.
When the hull was actually observed. This, not position_updated_at, is the age that matters.
The destination ETA the vessel itself is broadcasting, which is the master own entry and often disagrees with the carrier. Null when the hull broadcasts none.
Destination port UN/LOCODE, or null when unresolved.
Photograph of the hull. Null when we hold none.
When the vessel particulars were last refreshed.
The navigational status the vessel broadcasts, unchecked.
False when the broadcast status contradicts where the vessel actually is, for example Moored while far from any port. Then read nav_status, which we correct.
Why the broadcast status was not trusted, for example outside_port_geofence. Null when it was trusted.
Distance to the nearest port, nautical miles, which is the evidence behind the check. Null when the status needed no checking.
How the pin was placed: ais_vessel_position from a real fix, route_reckoning when computed along the route, or a port when the box is sitting at one.
What the reckoning leaned on when the pin was computed rather than observed, for example a published schedule.
The observation the estimate was anchored to. Null when there was none to anchor to.
observed_position
The last position we actually observed, never a computed one. Null when the hull has no fix on record.
Latitude.
Longitude.
When the fix was taken.
How exact the fix is: precise for a terrestrial fix, coarse for a satellite one.
Radius the fix is good to, kilometres. Null when the source states no accuracy.
estimated_position
A computed position, for when there is no fresh fix. Always labelled as computed; never merge the two blocks.
Latitude.
Longitude.
The moment the estimate describes.
The observation the estimate was reckoned from. Null when the reckoning had no fix to start from and leaned on the schedule alone.
Which reckoning class produced the estimate. Diagnostic detail for support, not something to branch on.
How the position was produced, for example route_reckoning.
vessel_photo
Photograph of the current hull with its attribution. Null when we hold none.
Where we POST the events.
Where the answer on this call came from: direct_carrier or warm_db.
When we fetched the photograph.
The more recent of the carrier check and the AIS fix: when we last learned anything about this shipment.
Which of the two produced last_updated_at: carrier_poll or ais_vessel_position. Null when neither has happened yet.
When the vessel was last actually observed by AIS, or null when we hold no fix.
IMO to name map covering every leg, so an onward vessel can be named without a second call. Empty when no leg carries a hull we can name.
The hub the box is dwelling at and its onward vessel. Null unless it is dwelling.
schedule_overlay
The published vessel rotation we matched this box to, which is the plan against which actuals can be read. Null when nothing matched.
Where the answer on this call came from: direct_carrier or warm_db.
How strongly the sailing matches the box, strongest first: vessel_voyage, vessel_lane, vessel_route, onward_vessel_lane, lane, carrier_lane. Weaker matches are context, not proof.
Carrier SCAC.
Carrier service or loop name.
IMO number of the carrying vessel, or null when unknown.
Carrier voyage number.
The departure the carrier published (ISO 8601). Null when it published none.
The arrival the carrier published (ISO 8601). Null when it published none.
Port-to-port transit in days.
True when the box changes vessel on the way.
The voyage broken into legs. Empty when we cannot yet split it.
legs[]
Position of the leg in the rotation, starting at 1.
UN/LOCODE the leg departs.
UN/LOCODE the leg arrives at.
Name of the departure port.
Name of the arrival port.
Name of the carrying vessel, or null when the carrier named none.
Carrier voyage number, when published. Null otherwise.
Carrier service or loop name.
Estimated time of departure (ISO 8601).
Arrival time (ISO 8601). Null when the carrier publishes none and we cannot predict one.
eta_intel
Probability envelope and reliability context. Null on thin lanes.
What the reliability figures were computed from, which tells you how much to lean on them.
True when the statistics are for THIS carrier on this lane, false when they are lane-level across all carriers and therefore coarser.
On-time percentage for the lane, which is the same number the ring shows.
Share of sailings that arrived on time.
Typical delay on the lane, hours. Null on a lane too thin to score.
Delay that 90 percent of arrivals stay inside, hours. Null on a thin lane.
Number of observed sailings behind the figure.
How far back those observations reach, days.
Best case: the published ETA, arriving on time. Null when there is no ETA to anchor to.
The date 90 percent of arrivals land by. Null when there is no ETA to anchor to.
The typical outcome: the ETA plus the median delay. Null when there is no ETA to anchor to.
Median transit time on the lane, hours. Null on a thin lane.
Transit time 90 percent of sailings stay inside, hours. Null on a thin lane.
Congestion warning. Null unless the next port is congested or the vessel has waited at anchor.
observability
Which of the four lenses we can offer on this shipment, and how many are active.
lenses
actuals (carrier milestones), position (the vessel), plan (a schedule) and probability (a confidence figure).
True when we hold carrier milestones.
True when we hold a vessel.
On LoadingMCP, the computed load plan. Inside a tracking observability lens, true when we hold a schedule for the shipment.
True when the ETA can carry a confidence figure.
How many of the four lenses are present.
Whether the sources tell the same story: aligned, diverging, partial, or insufficient when there are too few to compare.
The ETA each cross-checkable source implies, so a disagreement can be seen rather than averaged away.
eta_sources[]
Which source this ETA came from: carrier, published or ais.
Arrival time (ISO 8601). Null when the carrier publishes none and we cannot predict one.
Hours between the furthest-apart ETA sources. Null when fewer than two sources have an ETA.
A written read of the shipment state. Null when none has been generated for this box.
True while one is being generated, so a client can poll instead of showing an empty space.
Errors
A failure carries { "ok": false, "error": { "code", "message", "severity" } }. Branch on the code, and log the message.
The key is missing, malformed or revoked.
No container with that UUID on your account. Note the id is the UUID, not the container number.
curl 'https://api.trackingmcp.com/v1/containers/8f1c2d4e-6a3b-4f52-9c70-11ab22cd33ef' \
-H "Authorization: Bearer tmcp_YOUR_API_KEY"const res = await fetch("https://api.trackingmcp.com/v1/containers/8f1c2d4e-6a3b-4f52-9c70-11ab22cd33ef", {
headers: {
"Authorization": "Bearer tmcp_YOUR_API_KEY"
}
});
const data = await res.json();import requests
res = requests.get(
"https://api.trackingmcp.com/v1/containers/8f1c2d4e-6a3b-4f52-9c70-11ab22cd33ef",
headers={"Authorization": "Bearer tmcp_YOUR_API_KEY"},
)
data = res.json() {
"api_version": "2026-08-04",
"ok": true,
"data": {
"id": "6b2f4c81-9d35-4e70-a18c-5f7e2a9b4d63",
"org_id": "e04a7c19-8b62-4d35-9017-3a5c8e2b6f94",
"container_number": "HLXU8765432",
"bl_number": null,
"booking_number": null,
"carrier_code": "ONEY",
"carrier_name": "ONE",
"iso_code": null,
"size_teu": null,
"container_type": null,
"status": "in_transit",
"origin_unlocode": "CNCKG",
"destination_unlocode": "GBSOU",
"origin_name": "CHONGQING, CHONGQING",
"destination_name": "SOUTHAMPTON, HAMPSHIRE",
"eta": "2026-10-17T22:00:00+00:00",
"eta_is_estimated": true,
"eta_confidence_pct": 71,
"discharge_datetime": null,
"free_days": null,
"last_free_day": null,
"demurrage_at_risk": false,
"demurrage_accrued_usd": null,
"tags": [],
"notes": null,
"added_at": "2026-08-19T13:07:40.567796+00:00",
"last_polled_at": "2026-08-19T13:08:08.636+00:00",
"poll_priority": "transit",
"archived_at": null,
"identifier": "HLXU8765432",
"identifier_type": "container_id",
"current_vessel_imo": "9637260",
"current_voyage_id": null,
"demurrage_daily_rate_usd": null,
"demurrage_last_free_day": null,
"last_poll_trigger": null,
"tracker_lat": null,
"tracker_lng": null,
"tracker_updated_at": null,
"tracker_has_alert": false,
"customs_hold_reason": null,
"customs_hold_since": null,
"container_size": null,
"equipment_type": null,
"iso_type_code": null,
"unresolvable_since": null,
"route_alert": null,
"planned_departure_at": "2026-08-12T09:57:00+00:00",
"current_vessel_name": "HMM PRIDE",
"cargo_cutoff_at": null,
"vgm_cutoff_at": null,
"si_cutoff_at": null,
"customs_release_cutoff_at": null,
"cutoff_enrichment": null,
"unresolved_reason": null,
"updated_at": "2026-08-19T13:08:15.748434+00:00",
"archived_reason": null,
"identified_notified_at": null,
"intermediary_enriched_at": null,
"import_batch_id": null,
"seal_number": null,
"move_type": null,
"vgm_kg": null,
"gross_weight_kg": null,
"package_count": null,
"package_unit": null,
"measurement_cbm": null,
"service_requirement": null,
"commercial_raw": null,
"tracked_from": null,
"source": "api",
"route_data": {
"route": [
{
"from": {
"lat": 29.719167,
"lng": 106.641667,
"name": "Chongqing",
"state": "CQ",
"locode": "CNCKG",
"country": "China",
"timezone": "Asia/Shanghai",
"country_code": "CN"
},
"to": {
"lat": 31.1267,
"lng": 121.46178,
"name": "Shanghai",
"state": "SH",
"locode": "CNSHA",
"country": "China",
"timezone": "Asia/Shanghai",
"country_code": "CN"
},
"path": [],
"type": "LAND",
"vessel": null,
"transport_type": null
},
{
"from": {
"lat": 31.1267,
"lng": 121.46178,
"name": "Shanghai",
"state": "SH",
"locode": "CNSHA",
"country": "China",
"timezone": "Asia/Shanghai",
"country_code": "CN"
},
"to": {
"lat": 50.899862,
"lng": -1.43843,
"name": "Southampton",
"state": "HAM",
"locode": "GBSOU",
"country": "United Kingdom",
"timezone": "Europe/London",
"country_code": "GB"
},
"path": [
[
31.1267,
121.46177999999998
],
[
30.77811875,
121.31717249999997
],
[
30.6436625,
121.34495874999993
]
],
"type": "SEA",
"vessel": {
"imo": 9637260,
"flag": "KR",
"mmsi": 441486000,
"name": "HMM PRIDE",
"call_sign": "D8HP"
},
"transport_type": "VESSEL"
}
],
"pin": [
30.424815185353165
],
"pin_source": "schedule",
"ais": {
"data": {
"vessel": {
"imo": 9637260,
"flag": "KR",
"mmsi": 441486000,
"name": "HMM PRIDE",
"call_sign": "D8HP"
},
"last_event": {
"date": "2026-08-12 09:57:00",
"voyage": null,
"description": "Vessel departure"
},
"updated_at": "2026-08-19 13:08:15",
"arrival_port": {
"code": "SOU",
"locode": "GBSOU",
"date": "2026-10-17 22:00:00",
"date_label": "ETA",
"country_code": "GB"
},
"departure_port": {
"code": "SHA",
"locode": "CNSHA",
"date": "2026-09-12 19:00:00",
"date_label": "ETD",
"country_code": "CN"
},
"discharge_port": {
"code": "SOU",
"locode": "GBSOU",
"date": "2026-10-17 23:30:00",
"date_label": "ETA",
"country_code": "GB",
"name": "Southampton"
},
"last_vessel_position": {
"lat": 49.02262,
"lng": -123.14808,
"updated_at": "2026-08-19 13:08:17"
}
},
"status": "NOT_ON_BOARD"
},
"source": {
"provider": "trackingmcp",
"provider_name": "TrackingMCP",
"route_geometry": "trackingmcp_computed",
"ais": "trackingmcp_vessel_positions",
"note": "Route geometry and AIS fields were built from TrackingMCP container events, ports, and vessel positions."
},
"pin_estimated": true,
"pin_estimated_from": null,
"geometry_version": 2
},
"route_data_computed_at": "2026-08-19T13:08:15.681+00:00",
"equipment_owner": null,
"equipment_lessor": null,
"lessee_name": null,
"carrier_hint_code": null,
"lessor_status": null,
"lessor_checked_at": null,
"redelivery_reference": null,
"redelivery_date": null,
"redelivery_location": null,
"redelivery_yard": null,
"lessor_contract_number": null,
"lessor_contract_type": null,
"equipment_manufacturer": null,
"lessor_on_hire_date": null,
"lessor_on_hire_location": null,
"lessor_on_hire_yard": null,
"connector_status": null,
"connector_notify_requested_at": null,
"connector_notified_at": null,
"field_provenance": {
"cargo_cutoff_at": {
"state": "not_applicable",
"action": "do_not_expect",
"source": null,
"confidence": null,
"evidence": "cargo_cutoff_at is a pre-departure deadline; this shipment has already sailed (status in_transit)."
},
"si_cutoff_at": {
"state": "not_applicable",
"action": "do_not_expect",
"source": null,
"confidence": null,
"evidence": "si_cutoff_at is a pre-departure deadline; this shipment has already sailed (status in_transit)."
},
"vgm_cutoff_at": {
"state": "not_applicable",
"action": "do_not_expect",
"source": null,
"confidence": null,
"evidence": "vgm_cutoff_at is a pre-departure deadline; this shipment has already sailed (status in_transit)."
},
"customs_release_cutoff_at": {
"state": "not_applicable",
"action": "do_not_expect",
"source": null,
"confidence": null,
"evidence": "customs_release_cutoff_at is a pre-departure deadline; this shipment has already sailed (status in_transit)."
},
"discharge_datetime": {
"state": "awaiting_carrier",
"action": "wait",
"source": null,
"confidence": null,
"evidence": "No laden discharge event reported at the final port of discharge yet."
},
"free_days": {
"state": "contract_required",
"action": "supply_contract_terms",
"source": null,
"confidence": null,
"evidence": "Free time is a commercial term between you and the carrier, negotiated per contract and lane. We cannot observe it. Supply it via POST /v1/demurrage-terms and every field below resolves."
},
"demurrage_last_free_day": {
"state": "not_applicable",
"action": "wait",
"source": null,
"confidence": null,
"evidence": "Free time starts at discharge. This container has not been discharged, so a last free day would not be a real date."
},
"demurrage_daily_rate_usd": {
"state": "contract_required",
"action": "supply_contract_terms",
"source": null,
"confidence": null,
"evidence": "The daily demurrage rate is a tariff/contract figure, not a tracking observation. Supply it with your free-time terms to get a costed exposure."
},
"demurrage_at_risk": {
"state": "not_applicable",
"action": "wait",
"source": null,
"confidence": null,
"evidence": "Risk is only assessable after discharge."
},
"last_updated_at": {
"state": "resolved",
"action": "none",
"source": "carrier",
"confidence": "exact",
"evidence": "Last carrier check at 2026-08-19T13:08:08.636+00:00, more recent than the vessel's last position fix at 2026-08-19T13:04:58+00:00."
}
},
"field_provenance_summary": {
"resolved": 1,
"contract_required": 2,
"not_published": 0,
"not_applicable": 6,
"awaiting_carrier": 1,
"unblocked_by_contract_terms": true
},
"carrier_response_raw": null,
"origin_coord": {
"lat": 29.719167,
"lng": 106.641667,
"approximate": false,
"approx_from": null
},
"destination_coord": {
"lat": 50.899862,
"lng": -1.43843,
"approximate": false,
"approx_from": null
},
"is_demo": false,
"child_containers": null,
"ais_eta": null,
"events": [
{
"id": "5a3c9e71-4d82-4f60-b295-7c1e6b4a8d30",
"org_id": "e04a7c19-8b62-4d35-9017-3a5c8e2b6f94",
"container_id": "6b2f4c81-9d35-4e70-a18c-5f7e2a9b4d63",
"dcsa_event_id": "8f1c2d4e-6a3b-4f52-9c70-11ab22cd33ef",
"event_type": "EQUIPMENT",
"event_classifier_code": "ACT",
"event_date_time": "2026-08-07T05:25:00+00:00",
"event_created_date_time": "2026-08-19T13:08:07.285702+00:00",
"transport_event_type_code": null,
"delay_reason_code": null,
"change_remark": null,
"equipment_event_type_code": "GTOT",
"empty_indicator_code": "EMPTY",
"equipment_reference": "HLXU8765432",
"iso_equipment_code": null,
"shipment_event_type_code": null,
"document_id": null,
"document_type_code": null,
"reason": null,
"transport_call": {
"location": {
"locationName": "CHONGQING, CHONGQING",
"UNLocationCode": "CNCKG"
}
},
"references": null,
"seals": null,
"normalisation_confidence": "INFERRED",
"supplier_raw_event_code": null,
"supplier_raw_payload": null,
"created_at": "2026-08-19T13:08:07.285702+00:00",
"event_id": null,
"event_datetime": "2026-08-07T05:25:00+00:00",
"event_code": "GTOT",
"raw_payload": {
"datetime": "2026-08-07T05:25:00.000Z",
"timezone": "Asia/Shanghai",
"unlocode": "CNCKG",
"is_actual": true,
"port_name": "CHONGQING, CHONGQING",
"event_code": "GTOT",
"vessel_imo": null,
"description": "Empty Container Release to Shipper",
"source_kind": "searates",
"vessel_name": null,
"event_family": "EQUIPMENT",
"voyage_number": null,
"datetime_basis": "utc",
"datetime_local": "2026-08-07T13:25:00",
"time_semantics": "carrier_offset",
"transport_mode": null,
"datetime_precision": "datetime",
"utc_offset_minutes": 480,
"source_resolve_method": "searates_hint"
},
"event_local_datetime": "2026-08-07T13:25:00",
"utc_offset_minutes": 480,
"event_timezone": "Asia/Shanghai",
"event_time_semantics": "carrier_offset",
"event_name": "Gated out"
},
{
"id": "3f1c9a4e-7b52-4f0e-9a41-2c9d5e6b8a10",
"org_id": "e04a7c19-8b62-4d35-9017-3a5c8e2b6f94",
"container_id": "6b2f4c81-9d35-4e70-a18c-5f7e2a9b4d63",
"dcsa_event_id": "a94b2e10-33d7-4c8a-b0f1-6d2e7c9a4b55",
"event_type": "EQUIPMENT",
"event_classifier_code": "ACT",
"event_date_time": "2026-08-07T16:01:00+00:00",
"event_created_date_time": "2026-08-19T13:08:07.402357+00:00",
"transport_event_type_code": null,
"delay_reason_code": null,
"change_remark": null,
"equipment_event_type_code": "GTIN",
"empty_indicator_code": null,
"equipment_reference": "HLXU8765432",
"iso_equipment_code": null,
"shipment_event_type_code": null,
"document_id": null,
"document_type_code": null,
"reason": null,
"transport_call": {
"location": {
"locationName": "CHONGQING, CHONGQING",
"UNLocationCode": "CNCKG"
}
},
"references": null,
"seals": null,
"normalisation_confidence": "INFERRED",
"supplier_raw_event_code": null,
"supplier_raw_payload": null,
"created_at": "2026-08-19T13:08:07.402357+00:00",
"event_id": null,
"event_datetime": "2026-08-07T16:01:00+00:00",
"event_code": "GTIN",
"raw_payload": {
"datetime": "2026-08-07T16:01:00.000Z",
"timezone": "Asia/Shanghai",
"unlocode": "CNCKG",
"is_actual": true,
"port_name": "CHONGQING, CHONGQING",
"event_code": "GTIN",
"vessel_imo": null,
"description": "Gate In to Outbound Terminal",
"source_kind": "searates",
"vessel_name": null,
"event_family": "EQUIPMENT",
"voyage_number": null,
"datetime_basis": "utc",
"datetime_local": "2026-08-08T00:01:00",
"time_semantics": "carrier_offset",
"transport_mode": null,
"datetime_precision": "datetime",
"utc_offset_minutes": 480,
"source_resolve_method": "searates_hint"
},
"event_local_datetime": "2026-08-08T00:01:00",
"utc_offset_minutes": 480,
"event_timezone": "Asia/Shanghai",
"event_time_semantics": "carrier_offset",
"event_name": "Gated in"
}
],
"journey_timeline": [
{
"id": "5a3c9e71-4d82-4f60-b295-7c1e6b4a8d30",
"kind": "carrier_event",
"classifier": "ACT",
"occurred_at": "2026-08-07T05:25:00.000Z",
"event_name": "Gated out",
"port_unlocode": "CNCKG",
"port_name": "CHONGQING, CHONGQING",
"facility_name": null,
"evidence_event_ids": [
"5a3c9e71-4d82-4f60-b295-7c1e6b4a8d30"
],
"confidence": "reported",
"label": "GTOT",
"port_role": null,
"milestone": null
},
{
"id": "3f1c9a4e-7b52-4f0e-9a41-2c9d5e6b8a10",
"kind": "carrier_event",
"classifier": "ACT",
"occurred_at": "2026-08-07T16:01:00.000Z",
"event_name": "Gated in",
"port_unlocode": "CNCKG",
"port_name": "CHONGQING, CHONGQING",
"facility_name": null,
"evidence_event_ids": [
"3f1c9a4e-7b52-4f0e-9a41-2c9d5e6b8a10"
],
"confidence": "reported",
"label": "GTIN",
"port_role": null,
"milestone": null
}
],
"exceptions": [],
"history_days": 365,
"current_leg": null,
"legs": [],
"vessel_position": {
"imo": "9637260",
"name": "HMM PRIDE",
"lat": 49.022617,
"lng": -123.148083,
"speed_knots": 0,
"heading_deg": 133,
"nav_status": "Status unverified",
"position_updated_at": "2026-08-19T13:08:17.763+00:00",
"position_fix_at": "2026-08-19T13:04:58+00:00",
"eta_ais": "2026-08-12T16:00:00+00:00",
"destination_unlocode": "USTIW",
"photo_url": "https://static.vesselfinder.net/ship-photo/9637260-441486000-53d9ac3aef04a1f3f9c4448ba21edbf8/1?v1",
"particulars_updated_at": "2026-08-16T06:08:02.062+00:00",
"reported_nav_status": "Moored",
"nav_status_verified": false,
"nav_status_reason": "outside_port_geofence",
"nearest_port_nm": 4105.3456502614135
},
"pin_source": "route_reckoning",
"pin_basis": "schedule",
"pin_estimated_from": null,
"observed_position": {
"lat": 49.022617,
"lng": -123.148083,
"observed_at": "2026-08-19T13:04:58+00:00",
"quality": "precise",
"accuracy_km": null
},
"estimated_position": {
"lat": 30.424815185353165,
"lng": 114.07153602984077,
"estimated_at": "2026-08-19T14:26:00.000Z",
"based_on_observation_at": null,
"classification": "SAT-A",
"method": "route_reckoning"
},
"vessel_photo": {
"url": "https://static.vesselfinder.net/ship-photo/9637260-441486000-53d9ac3aef04a1f3f9c4448ba21edbf8/1?v1",
"source": "external_enrichment",
"retrieved_at": "2026-08-16T06:08:02.062+00:00"
},
"last_updated_at": "2026-08-19T13:08:08.636+00:00",
"last_updated_source": "carrier_poll",
"last_ais_fix_at": "2026-08-19T13:04:58+00:00",
"vessel_names": {},
"transshipment": null,
"schedule_overlay": {
"source": "published_schedule",
"match": "vessel_lane",
"carrier_code": "MSCU",
"service_name": "GRIFFIN SERVICE",
"vessel_imo": "9637260",
"voyage_number": "0056W",
"published_departure": "2026-09-17T11:30:00+00:00",
"published_arrival": "2026-10-17T07:00:00+00:00",
"transit_days": 30,
"is_transshipment": false,
"legs": [
{
"seq": 1,
"from_unlocode": "SGSIN",
"to_unlocode": "GBSOU",
"from_name": "SINGAPORE",
"to_name": "SOUTHAMPTON",
"vessel_name": "HMM PRIDE",
"voyage": "0056W",
"service": "GRIFFIN SERVICE",
"etd": "2026-09-17T11:30:00.000Z",
"eta": "2026-10-17T07:00:00.000Z"
}
]
},
"eta_intel": {
"basis": "carrier_schedule",
"carrier_scoped": true,
"confidence_pct": 71,
"on_time_pct": 71,
"median_delay_hours": null,
"p90_delay_hours": 168,
"observations": 13270,
"window_days": 90,
"band_low": "2026-10-17T22:00:00+00:00",
"band_high": "2026-10-24T22:00:00.000Z",
"expected": "2026-10-21T10:00:00.000Z",
"transit_p50_hours": null,
"transit_p90_hours": null
},
"eta_at_risk": null,
"observability": {
"lenses": {
"actuals": true,
"position": true,
"plan": true,
"probability": true
},
"active_count": 4,
"agreement": "aligned",
"eta_sources": [
{
"lens": "carrier",
"eta": "2026-10-17T22:00:00+00:00"
}
],
"max_spread_hours": 15
},
"ai_insight": null,
"ai_insight_pending": true
}
}