SeaRates-compatible tracking
Track a container, bill of lading or booking and receive the SeaRates-shaped envelope, so an existing SeaRates integration keeps parsing unchanged. You change the base URL and the key, nothing else.
The key travels in the query string as api_key, which is where a SeaRates client already puts it. Any Navo24 tmcp_ key works. Bearer tokens are for the native /v1 API.
Aliases served by the same handler: /compat/searates/container, /compat/searates/reference.
Query parameters
Your Navo24 API key (tmcp_ prefix). Create one in the developer portal.
The reference to track: a container number (4 letters and 7 digits), a bill of lading, or a booking number. Upper-cased and trimmed server-side, and the kind of reference is detected rather than declared.
Response fields
success on a data-bearing reply, error otherwise. An error is still HTTP 200 (see Errors).
OK on a normal reply. On an error it carries the machine code. On a success it can carry one short sentence explaining why a reference is untrackable.
Exactly seven keys, always the same seven. The API version is disclosed in response headers, never as an eighth key here.
Which identifier resolved: CT container, BL bill of lading, BK booking.
The reference exactly as you queried it, upper-cased.
SCAC of the operating line. Falls back to the container prefix when the stored carrier is unresolved and the prefix names a known line, and to the literal auto when even that is unknown.
Human carrier name, or the literal Unknown when no line has been resolved. Never null.
Shipment status: PLANNED, IN_TRANSIT, DELIVERED or UNKNOWN. See the shipment status table.
Always false, and deliberately so: our status is derived from the carrier events we hold, not lifted from a carrier status string. Reporting true would misattribute a value we computed.
Always false. The store is polled continuously and served live rather than as a stale cache hit.
When we last wrote this record, in UTC. Null means we hold no write timestamp, which happens only on a record that has never been polled.
updated_at plus 12 hours, in UTC. Null whenever updated_at is null.
Call cap for the key. NULL MEANS UNCAPPED, which is the common case. It does not mean zero.
Calls consumed in the current period. Always a real number.
Calls left, or null when uncapped.
Same three counters for unique shipments, which is the dimension we meter on. Same null rule.
Every place the payload references, deduplicated. Events and route points point here by id.
One-based id, referenced by events and route points.
Port or place name, cleaned of a trailing country suffix where a carrier appended one.
State or province. Null when our port reference data holds none for this place.
English country name. Null when we could not determine the country at all.
ISO 3166-1 alpha-2. Derived from the UN/LOCODE prefix when the reference data is silent.
Full 5-character UN/LOCODE. NULL MEANS THE CARRIER GAVE A PLACE NAME ONLY and we could not resolve it to a code, not that the place is unknown.
Latitude. Null when the place is unresolved in our port reference data.
Longitude. Null on the same condition as lat.
IANA zone for the port. This is the clock every event date is printed on. Null when the port is unplaced, in which case that event date is the carrier value as filed.
Terminals, depots and yards, deduplicated by name. A place with no UN/LOCODE whose name reads as a terminal or an operator is filed here rather than entering locations.
One-based id, referenced by an event facility.
Terminal or depot name as the carrier reported it.
ISO 3166-1 alpha-2 of the event that introduced the facility. Null when that event carried no country.
Always null today: carriers give us the facility name only. Present so the shape matches.
Always null today, for the same reason as locode.
Always null today, for the same reason as locode.
Always null today. Facility coordinates are not published by the carriers we read.
Always null today, for the same reason as lat.
The inland origin move before the sea leg. See the route block table.
Port of loading.
Port of discharge, which is where the box leaves the ship and is not the inland destination on a door move.
The inland destination move after the final discharge.
Index into locations. Null only when we hold no place for that point at all.
Port-local timestamp of that point. NULL MEANS THE CARRIER HAS NOT FILED THE MOVE YET, not that it did not happen.
True once the milestone has occurred. Null appears only on a prepol that fell back to the pol location because there is no inland origin move.
Predicted arrival at the port of discharge, on pod only. Once the arrival is actual there is nothing left to predict, so it equals the recorded arrival rather than a frozen pre-arrival estimate. Null when we hold no estimate.
Every hull the timeline names, deduplicated by IMO and by canonical name.
One-based id, referenced by an event vessel.
Vessel name. Where two sources disagree we emit the fuller spelling, so a name is never silently truncated.
IMO number. Null when the carrier named the ship but gave no IMO.
Call sign. Null when we hold no particulars for this hull.
MMSI. Null on the same condition as call_sign.
Flag as an ISO 3166-1 alpha-2 code, derived from the MMSI when the stored flag is absent. Null when neither is available.
One entry per box. A container lookup returns one. A bill of lading or booking returns every box on the manifest, never a truncated list.
Container number.
ISO 6346 size and type code. Null when the carrier did not publish one, or when a multi-box bill of lading cannot attribute the parent equipment to one box.
Human size and type, normalised so one box type reads one way across carriers. The ISO code is read first and the carrier short code second, and the two tables are held identical on every shared key, so a value such as 40RH renders "40' Reefer" whichever of the two fields the carrier populated. An unrecognised carrier value is passed through untouched rather than guessed at. Null on the same condition as iso_code.
Shipment status for this box, same vocabulary as metadata.status.
Always false, for the reason given on metadata.is_status_from_sealine.
A provenance disclosure, not a formatting flag. True when this box carries a timeline copied from a sibling on the same bill of lading rather than one sourced for this box. A box whose events were fetched in their own request is false even when its dates match a sibling.
The milestone timeline, chronological, with a journey-stage tie-break so a run of same-timestamp estimates cannot read as a gate-out before the ship has arrived.
One-based position in this timeline, renumbered after duplicate records are removed. A repeated milestone at one place is not a duplicate and keeps its own number (see the duplicates note).
Index into locations. Null when the carrier reported no place, or reported only a terminal, which is filed as the facility instead.
Index into facilities. Null when the carrier named no terminal.
The carrier own wording for the move where we hold it, otherwise a generic label for the code. The carrier sentence wins deliberately: a code-derived label discards a fact the line already stated.
EQUIPMENT or TRANSPORT, derived from the code: arrivals and departures are TRANSPORT, every equipment move is EQUIPMENT. Null only on the transshipment delay notice, which carries no family.
The movement code, drawn from a CLOSED vocabulary of sixteen values and never anything else. Full list in the event code table below. NULL IS A NORMAL VALUE on an ordinary movement, not an error and not only the transshipment delay: it means we hold no code from this closed set for that move, and the incumbent withholds a code on the same kind of row. Read the description when the code is null. The row is never dropped for it.
The milestone this event represents. Full vocabulary in the status code table below. Never null.
The true UTC instant of the event, YYYY-MM-DD HH:MM:SS. This is the primary date on every surface, so a value never depends on which clock the carrier reported it in. The port wall clock rides alongside in event_local_datetime.
The port local wall clock for the same event, YYYY-MM-DDTHH:MM:SS, no offset. A vessel that departs Yantian at 14:15 on the quay shows date 06:15:00 UTC and event_local_datetime T14:15:00. Null until the carrier connector reports a placeable port.
Minutes to add to date to reach event_local_datetime, so the pair is self describing. Null when unknown.
IANA zone of the port, such as Asia/Shanghai. The stable companion to the offset, which alone cannot name the zone or survive a DST change. Null when unresolved.
True once the milestone has occurred, false while it is a forecast. Reconciled to be monotonic: everything at or before the latest actual event is actual, so the sequence never reads as out of order.
Always true: every date on this surface comes from the carrier filing, not from an inference of ours.
Always false. We do not synthesise events.
sea or land. VESSEL and BARGE ride water, RAIL and TRUCK ride land.
VESSEL, RAIL, TRUCK or BARGE. Null only on the transshipment delay notice. See the conveyance table for how TRUCK is used as a fallback.
Index into vessels. NULL ON EVERY LAND MOVE by construction, so a rail or truck leg can never claim to ride a ship, and null on a sea move where the carrier named no hull and the timeline names more than one.
Voyage number. Nulled alongside vessel on a land move, and null when the carrier filed none.
Map payload: plotted legs, the current pin and live AIS. Null when we hold no plottable route. Additive, and safe to ignore if you only consume the timeline.
Plotted legs, port to port, each with its sea lane or land path.
Points as [lat, lng] pairs, in that order.
SEA or LAND for the leg.
The hull that ran the leg. Null on a land leg, and on a sea leg where no hull is known.
Current position as [lat, lng]. Null when we hold no position for the carrying vessel.
Live vessel block. Null when no vessel is under way for this shipment.
The 3-letter port code, which is the UN/LOCODE with its country prefix removed and is NOT itself a UN/LOCODE. Kept for compatibility.
Additive to the incumbent shape: the full 5-character UN/LOCODE, so a consumer keying on UN/LOCODE can match this block. Null when the port is unresolved.
ETA, ETD, ATA or ATD, saying which kind of time the sibling date is.
Provenance for the geometry and the AIS, so you can tell computed geometry from provider geometry.
Errors
This surface follows the incumbent convention: a not-found or still-resolving reference is HTTP 200 with { "status": "error" } and a machine code in message, never a 4xx. Only transport-level failures use a 4xx status, and those carry prose in message with data null.
A well-formed reference with no data yet: not found on the identified line, or still resolving. Retry shortly. The body is { "status": "error", "message": "NO_TRACKING_INFO", "data": {} } plus an additive detail string, which strict parsers can ignore.
The reference has been determined invalid. Same envelope, and the machine code again rides in message rather than in the HTTP status. Where a container number fails its ISO 6346 check digit, detail names the corrected number when one exists.
No number (or container) was supplied. data is null.
The api_key is missing, unknown, revoked or expired. data is null.
The entitlement on this key has expired. data is null.
The per-organisation burst throttle tripped, or the plan allowance is spent. data is null.
What changes, and what does not
Your parser does not change. The envelope, the field names, the normalised locations, facilities and vessels arrays, the route block and the milestone vocabulary are all reproduced. Three things change: the base URL, the api_key you send, and the fact that the data underneath is ours. Two behaviours are worth reading before you cut over: our nulls are documented field by field below, and the differences we know about are stated on this page rather than left for you to find.
Cold lookups
A reference we have never seen is registered and resolved live. The request is held until real data lands, usually two to four seconds, with a ceiling of twenty-five seconds. If nothing resolves inside that window you get NO_TRACKING_INFO, and a retry a moment later normally succeeds because the resolution keeps running in the background. A not-found is never charged against your allowance, so you can retry freely.
Which clock the dates use
Every event date, every route date and the AIS block are printed as the true UTC instant, formatted YYYY-MM-DD HH:MM:SS with no offset. This is the same basis on the native API and this SeaRates-compatible one, so no value depends on which clock a carrier reported it in. The port local wall clock rides alongside each event in event_local_datetime, together with utc_offset_minutes and event_timezone, so you can show quay time without re-deriving it. metadata.updated_at and metadata.cache_expires are our own bookkeeping and stay in UTC too.
Repeated milestones, and which duplicates we remove
A repeated status at one place is NOT treated as a duplicate. A vessel calling the same port twice, or an arrival and a berthing hours apart, is two real movements, and both rows are returned, exactly as the incumbent returns them. Two different movement codes can also fold onto one milestone at one place, and both of those rows are returned too. Only two things are removed, and both are records rather than movements. First, two events at the SAME instant and the same milestone and place, which is one physical move reported twice by two event families. Second, an unlocated copy of an event we also hold with a resolved UN/LOCODE, which is a bookkeeping artefact rather than a second call. Where a pair does fold we keep the located row, then the actual or the later one, and order_id is renumbered afterwards. UNKN and LTS never fold at all, because neither is a once-per-journey milestone.
Versioning
Versions are dates. Pin one with the API-Version request header (X-API-Version and Navo-API-Version are accepted aliases) and your response shape is held. An unpinned request always resolves to the oldest supported version, never the newest, so a deploy can never move an existing integration onto a new shape. The resolved version is echoed on every response, and an unrecognised value never blocks a request: it falls back and returns API-Version-Warning naming what was sent and what was served. One shape difference exists between the two published versions today: 2026-08-04 spells the unclassified milestone UNKN, and 2027-02-01 spells the same value UNK. Everything else is identical, including the seven top-level keys.
Event codes
Every value containers[].events[].event_code can carry, and there are exactly sixteen. The vocabulary is CLOSED: a movement we hold under some other code is emitted with event_code null rather than under a name this list does not contain, because a code outside the list is the one thing a migrating parser cannot be expected to handle. Null is an ordinary outcome on an ordinary movement, not a marker for the transshipment delay alone, and the incumbent withholds a code on the same kind of row. When the code is null, read description: the row still carries its wording, its place, its date, its status and its actual flag, so no movement is lost. Note that the code and the milestone are different questions. The code says what the carrier did; status says where on the journey it happened, and several codes reach one milestone.
| Code | Meaning | Usual milestone |
|---|---|---|
| ARRI | Vessel arrival. | VAT at a hub, VAD at the port of discharge, LTS on an inland leg. |
| DEPA | Vessel departure. | VDL at the loading port, VDT at a hub, LTS on an inland leg. |
| LOAD | Container loaded on the vessel. | CLL on the first load, CLT afterwards, LTS on an inland leg. |
| DISC | Container discharged from the vessel. | CDT at a transshipment port, CDD at the final one. |
| GTIN | Container gate in. Our internal DROP token is emitted as GTIN, which is the only gate-in code this vocabulary has. | CGI laden, CER empty, LTS on an inland leg. |
| GTOT | Container gate out. | CEP when empty, CGO when laden at the destination. |
| PICK | Container picked up. | CPS at the shipper, CGO past the port of discharge, CEP on a merchant-haulage empty pickup. |
| RELS | Released. Carries both the carrier release and the availability-to-collect notice. | UNKN: neither is a positional milestone. |
| STUF | Container stuffed. The long spelling STUFF is emitted as STUF, which is how the wire spells it. | UNKN. |
| STRP | Container stripped. | UNKN. |
| RECE | Received. | UNKN. |
| CONF | Confirmed. | UNKN. |
| CUSR | Customs release. | UNKN. |
| CUSI | Customs inspection. | UNKN. |
| ISSU | Issued. | UNKN. |
| INSP | Inspected. | UNKN. |
| null | No code from the closed set applies. Availability for delivery is the common case, and the transshipment delay notice is a second one. Fall back to description. | The milestone is still emitted: TSD on the delay notice, and the ordinary positional milestone otherwise. |
Size and type
How containers[].size_type is rendered. Two carrier fields can carry the box type, the ISO code and a short code, and both are read against the same vocabulary so one physical box cannot read two ways depending on which field the line happened to populate. The ISO code is consulted first. A code in neither table is passed through as the carrier wrote it rather than guessed at.
| Carrier value | size_type |
|---|---|
| 22G1, 22G0, 20G1 | 20' Dry Standard |
| 20DV, 20GP | 20' Dry Standard |
| 42G1, 42G0, 40G1 | 40' Dry Standard |
| 40DV, 40GP | 40' Dry Standard |
| 45G1, 45G0 | 40' High Cube Dry |
| 40HC, 40HQ, 45GP | 40' High Cube Dry |
| L5G1 | 45' High Cube Dry |
| 45HC | 45' High Cube Dry |
| 22R1, 20RF | 20' Reefer |
| 42R1, 40RF, 40RH | 40' Reefer. 40RH is a carrier short code rather than a valid ISO 6346 size type, and its second character encodes the 8 foot nominal height, so it is not a high cube. Carriers do file it in the ISO field, so it is recognised there as well as in the short-code field. |
| 45R1 | 40' High Cube Reefer |
| 22T1 | 20' Tank |
| 22KL, 22K0 | 20' Tank for Liquids and Gases |
| 42T1 | 40' Tank |
| 22U1, 20U1 | 20' Open Top |
| 42U1 | 40' Open Top |
| 45U1 | 40' High Cube Open Top |
| 22P1 | 20' Flat Rack |
| 22P3 | 20' Flat Collapsible |
| 42P1 | 40' Flat Rack |
Milestone status codes
Every value containers[].events[].status can carry. The vocabulary is position-aware: one movement code means a different milestone before the loading port, at the loading port, at a transshipment hub, at the port of discharge and on an inland move past it. Two rules do most of the work. Cargo state, not journey position, separates the gate pairs, so an empty release is never confused with a laden gate-out and an empty return is never confused with a laden gate-in. And sea milestones are ordinal rather than matched on UN/LOCODE, so a shipment with a missing port code still splits correctly instead of collapsing into transshipments.
| Code | Meaning | When we emit it | Caveat |
|---|---|---|---|
| CPS | Container picked up at the shipper. | A pickup event before or at the port of loading. | The same physical move at the destination is the laden gate-out (CGO). A pickup on a leg the carrier reports as rail, truck or barge is LTS. |
| CEP | Empty container released to the shipper. | A gate-out the carrier reports as EMPTY, wherever it happens, including an unlocated depot. Also a gate-out at the loading port when no cargo state was reported. | One wording-driven exception: an empty pickup the carrier calls merchant haulage is the release to the shipper (CEP), while a carrier-haulage empty pickup at a depot stays CPS. Nothing else infers CEP from position alone. |
| CGI | Laden gate-in at the port of loading. | A gate-in that is laden, or that carries no cargo state, before the box reaches its destination. Also an arrival at the loading port, including a road or rail arrival there. | A laden gate-in on an explicitly inland leg is LTS, not CGI. |
| CLL | Container loaded on the vessel at the port of loading. | The first load of the itinerary. | Ordinal, not matched on UN/LOCODE, so a shipment with a missing port code still splits correctly. An explicitly inland load is LTS. |
| VDL | Vessel departed the port of loading. | The first departure of the itinerary. | Ordinal, same rule as CLL. An explicitly inland departure is LTS. |
| VAT | Vessel arrived at a transshipment hub. | Any vessel arrival that is not the last sea arrival of the itinerary. | An arrival before the first load, or after the final discharge, is land-side by construction and codes LTS. VAT and VAD are vessel concepts, and a box on a train is at neither. |
| CDT | Container discharged at a transshipment port. | Any discharge the box later sails away from, and any discharge the carrier itself words as a transshipment. | A discharge is the final one only when no sea load or departure follows it. A box discharged at a hub and still waiting for its onward vessel stays CDT, so an arrival is never announced a month early in the wrong country. |
| TSD | Transshipment delay. | A status-only row carrying no movement: no event code, no event family, no conveyance, type sea. Recognised from the carrier exact wording on a row carrying no classifiable code, which covers both an uncoded notice and the DELAY code some lines file. | It is not a discharge. It can appear beside a CDT at the same instant and place, because they are two separate facts. |
| CLT | Container loaded at a transshipment hub. | Any load that is not the first of the itinerary. | |
| VDT | Vessel departed a transshipment hub. | Any departure that is not the first of the itinerary. | |
| BTS | Barge transshipment: the barge or feeder leg serving an inland port. | Only where the carrier own wording names both a barge or feeder and an inland port. | Deliberately biased to precision. Where a feeder IS the carriage rather than an ancillary leg, the ordinary ocean codes apply, so some genuine barge legs read CLT, VDT or CDD instead. Neither the conveyance nor the journey position reproduces this code, and we do not guess it. |
| VAD | Vessel arrived at the port of discharge. | The last sea arrival of the itinerary, and only when the box never sails again after it. | |
| CDD | Container discharged at the final port of discharge. | The last discharge with no onward sea leg after it. An availability notice at the destination folds onto the same milestone. | Two of our movement codes can reach this milestone at one port. Where they land on the same instant that is one physical discharge reported twice and it is folded to a single row; where they land on different instants they are two facts and both rows are returned (see the duplicates note). |
| CGO | Laden gate-out at the destination. | A gate-out or pickup once the box is at or past the port of discharge. | Cargo state decides the gate pairs, not position: an EMPTY gate-out is a release (CEP) wherever it occurs, and only a laden or unstated one at the destination is CGO. |
| CDC | Container delivered to the consignee. | Only where the carrier entire statement is the delivery itself, matched against a short list of unambiguous phrases. | Narrow on purpose, and this is a difference worth knowing. Measured against captured carrier envelopes, a broader positional or wording rule rewrites hundreds of correct empty returns into a wrong code, so a delivery whose wording is indistinguishable from a gate-out or an empty return keeps that code instead. We would rather under-emit CDC than write a wrong value into your database. |
| CER | Empty container returned. | A gate-in the carrier reports as EMPTY, anywhere. Also a gate-in with no cargo state once the box is at or past the destination. | The carrier explicit indicator wins where it exists. Most rows carry none, and an EMPTY stated only in the carrier prose is honoured as well. |
| LTS | Inland transport stage: land pre-carriage or on-carriage. | Any load, discharge, departure, gate move or arrival on a leg the carrier explicitly reports as rail, truck or barge. Also a gate-out or arrival before the box reaches its loading port, and an arrival after the port of discharge. | LTS is a category of inland movement, not a once-per-journey milestone. Several LTS rows at one place are normal (an inland origin routinely files both an arrival and a departure) and they are never collapsed onto each other. |
| UNKN | No milestone definition applies to this event. | A gate move at a sea transshipment hub or at no place at all, and ancillary codes with no evidenced milestone: stuffing, stripping, customs inspection, customs release, release and availability notices. | The spelling is version-dependent. Version 2026-08-04 emits the four-letter UNKN and version 2027-02-01 emits the three-letter UNK for the same value. An unpinned request keeps UNKN. Either way the row keeps its date, its place and the carrier own description: we would rather carry an unclassified row than force a wrong milestone onto it. |
type and transport_type
These two fields are the pair most migrations map first, and they derive from the same signal, so an event can never read as land while claiming a vessel. An explicit conveyance from the carrier always wins. Where the carrier reports none in a structured field we read its own event wording on an unambiguous whole-word match, and where there is no signal at all a vessel operation is sea and everything else is land.
| transport_type | type | When we emit it |
|---|---|---|
| VESSEL | sea | An ocean leg. Also the default for a load, discharge, departure or arrival where the carrier reports no mode. |
| BARGE | sea | A barge or inland-waterway leg. It rides water, so it is typed sea, and it legitimately names its hull. |
| RAIL | land | An intermodal rail leg, reported by the carrier either in a structured mode field or unambiguously in its own event wording. |
| TRUCK | land | A road leg, and also the fallback for any land-side move where no mode was reported. Read it as not a sea leg rather than as a claim that a truck was used. |
| null | sea | Only on the transshipment delay notice (TSD), which carries no conveyance at all. |
The route block
Four anchor points. On a bill of lading that expanded into per-box timelines the route is derived from the union of those timelines, so it can only ever cite a date you can find elsewhere in the same payload. Each point carries location, date and actual, and only pod carries predictive_eta.
| Point | What it is | How we resolve it |
|---|---|---|
| prepol | The inland origin move before the sea leg. | The first gate or pickup event ahead of the first load or departure. Falls back to the pol location, with a null date and a null actual, when there is no inland origin move. |
| pol | Port of loading. | Anchored on the vessel departure, falling back to the first load. The departure is preferred because a door or rail origin files an inland load first, which would otherwise put the loading port inland and the departure date days early. |
| pod | Port of discharge: where the box leaves the ship. | The last vessel discharge the box never sails away from, and never a discharge the carrier itself calls a transshipment. This is NOT the inland destination on a door or ramp move: that belongs to postpod. |
| postpod | The inland destination move after the final discharge. | The last availability or gate event past the port of discharge. On a multi-box bill of lading this is the last box back to the depot, which is what closes the demurrage clock. Falls back to pod when there is no on-carriage move. |
Shipment status
The value carried by metadata.status and by containers[].status.
| Value | Meaning |
|---|---|
| PLANNED | Booked, not yet departed. |
| IN_TRANSIT | Everything from the origin port through discharge, availability and customs hold. |
| DELIVERED | Delivered, or returned empty. |
| UNKNOWN | Nothing has resolved yet, or the booking was cancelled. |
curl 'https://api.trackingmcp.com/compat/searates/tracking?api_key=tmcp_YOUR_API_KEY&number=MEDU1234562'const res = await fetch("https://api.trackingmcp.com/compat/searates/tracking?api_key=tmcp_YOUR_API_KEY&number=MEDU1234562");
const data = await res.json();import requests
res = requests.get("https://api.trackingmcp.com/compat/searates/tracking?api_key=tmcp_YOUR_API_KEY&number=MEDU1234562")
data = res.json() {
"status": "success",
"message": "OK",
"data": {
"metadata": {
"type": "CT",
"number": "MEDU1234562",
"sealine": "MSCU",
"sealine_name": "MSC",
"status": "IN_TRANSIT",
"is_status_from_sealine": false,
"from_cache": false,
"updated_at": "2026-06-29 14:22:07",
"cache_expires": "2026-06-30 02:22:07",
"api_calls": { "total": null, "used": 1284, "remaining": null },
"unique_shipments": { "total": 500, "used": 213, "remaining": 287 }
},
"locations": [
{ "id": 1, "name": "Ningbo", "state": "Zhejiang", "country": "China",
"country_code": "CN", "locode": "CNNGB", "lat": 29.8683, "lng": 121.544,
"timezone": "Asia/Shanghai" },
{ "id": 2, "name": "Singapore", "state": null, "country": "Singapore",
"country_code": "SG", "locode": "SGSIN", "lat": 1.2653, "lng": 103.8221,
"timezone": "Asia/Singapore" },
{ "id": 3, "name": "Rotterdam", "state": "South Holland", "country": "Netherlands",
"country_code": "NL", "locode": "NLRTM", "lat": 51.9496, "lng": 4.1421,
"timezone": "Europe/Amsterdam" }
],
"facilities": [
{ "id": 1, "name": "Ningbo Beilun Second Container Terminal", "country_code": "CN",
"locode": null, "bic_code": null, "smdg_code": null, "lat": null, "lng": null }
],
"route": {
"prepol": { "location": 1, "date": "2026-06-14 09:20:00", "actual": true },
"pol": { "location": 1, "date": "2026-06-18 22:10:00", "actual": true },
"pod": { "location": 3, "date": "2026-07-21 06:30:00", "actual": false,
"predictive_eta": "2026-07-21 06:30:00" },
"postpod":{ "location": 3, "date": "2026-07-21 06:30:00", "actual": false }
},
"vessels": [
{ "id": 1, "name": "MSC TERESA", "imo": 9398350, "call_sign": "3FOE9",
"mmsi": 372525000, "flag": "PA" },
{ "id": 2, "name": "MSC ISABELLA", "imo": 9839430, "call_sign": "9HA5192",
"mmsi": 229985000, "flag": "MT" }
],
"containers": [
{
"number": "MEDU1234562",
"iso_code": "45G1",
"size_type": "40' High Cube Dry",
"status": "IN_TRANSIT",
"is_status_from_sealine": false,
"events_mirrored": false,
"events": [
{ "order_id": 1, "location": 1, "facility": 1,
"description": "Empty container release to shipper",
"event_type": "EQUIPMENT", "event_code": "GTOT", "status": "CEP",
"date": "2026-06-14 09:20:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "land", "transport_type": "TRUCK", "vessel": null, "voyage": null },
{ "order_id": 2, "location": 1, "facility": 1,
"description": "Full container gate in",
"event_type": "EQUIPMENT", "event_code": "GTIN", "status": "CGI",
"date": "2026-06-16 14:05:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "land", "transport_type": "TRUCK", "vessel": null, "voyage": null },
{ "order_id": 3, "location": 1, "facility": 1,
"description": "Loaded on vessel",
"event_type": "EQUIPMENT", "event_code": "LOAD", "status": "CLL",
"date": "2026-06-18 18:40:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 1, "voyage": "FL626A" },
{ "order_id": 4, "location": 1, "facility": null,
"description": "Vessel departure",
"event_type": "TRANSPORT", "event_code": "DEPA", "status": "VDL",
"date": "2026-06-18 22:10:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 1, "voyage": "FL626A" },
{ "order_id": 5, "location": 2, "facility": null,
"description": "Vessel arrival",
"event_type": "TRANSPORT", "event_code": "ARRI", "status": "VAT",
"date": "2026-06-26 11:55:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 1, "voyage": "FL626A" },
{ "order_id": 6, "location": 2, "facility": null,
"description": "Full transshipment discharged",
"event_type": "EQUIPMENT", "event_code": "DISC", "status": "CDT",
"date": "2026-06-26 19:30:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 1, "voyage": "FL626A" },
{ "order_id": 7, "location": 2, "facility": null,
"description": "Loaded on vessel",
"event_type": "EQUIPMENT", "event_code": "LOAD", "status": "CLT",
"date": "2026-06-29 04:15:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 2, "voyage": "228W" },
{ "order_id": 8, "location": 2, "facility": null,
"description": "Vessel departure",
"event_type": "TRANSPORT", "event_code": "DEPA", "status": "VDT",
"date": "2026-06-29 13:40:00", "actual": true,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 2, "voyage": "228W" },
{ "order_id": 9, "location": 3, "facility": null,
"description": "Vessel arrival",
"event_type": "TRANSPORT", "event_code": "ARRI", "status": "VAD",
"date": "2026-07-21 06:30:00", "actual": false,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 2, "voyage": "228W" },
{ "order_id": 10, "location": 3, "facility": null,
"description": "Discharged from vessel",
"event_type": "EQUIPMENT", "event_code": "DISC", "status": "CDD",
"date": "2026-07-21 15:10:00", "actual": false,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "sea", "transport_type": "VESSEL", "vessel": 2, "voyage": "228W" },
{ "order_id": 11, "location": 3, "facility": null,
"description": "Full available for delivery",
"event_type": "EQUIPMENT", "event_code": null, "status": "CDD",
"date": "2026-07-22 08:00:00", "actual": false,
"is_date_from_sealine": true, "is_additional_event": false,
"type": "land", "transport_type": "TRUCK", "vessel": null, "voyage": null }
]
}
],
"route_data": {
"route": [
{ "from": { "lat": 29.8683, "lng": 121.544, "name": "Ningbo", "state": "Zhejiang",
"locode": "CNNGB", "country": "China", "timezone": "Asia/Shanghai",
"country_code": "CN" },
"to": { "lat": 1.2653, "lng": 103.8221, "name": "Singapore", "state": null,
"locode": "SGSIN", "country": "Singapore", "timezone": "Asia/Singapore",
"country_code": "SG" },
"path": [[29.8683, 121.544], [22.1, 114.3], [1.2653, 103.8221]],
"type": "SEA",
"vessel": { "imo": 9398350, "flag": "PA", "mmsi": 372525000,
"name": "MSC TERESA", "call_sign": "3FOE9" },
"transport_type": "VESSEL" }
],
"pin": [6.42, 79.85],
"ais": {
"status": "OK",
"data": {
"vessel": { "imo": 9839430, "flag": "MT", "mmsi": 229985000,
"name": "MSC ISABELLA", "call_sign": "9HA5192" },
"last_event": { "date": "2026-06-29 13:40:00", "voyage": "228W",
"description": "Vessel departure" },
"updated_at": "2026-06-29 14:05:00",
"arrival_port": { "code": "RTM", "locode": "NLRTM", "name": "Rotterdam",
"date": "2026-07-21 06:30:00", "date_label": "ETA",
"country_code": "NL" },
"departure_port": { "code": "SIN", "locode": "SGSIN", "name": "Singapore",
"date": "2026-06-29 13:40:00", "date_label": "ATD",
"country_code": "SG" },
"discharge_port": { "code": "RTM", "locode": "NLRTM", "name": "Rotterdam",
"date": "2026-07-21 06:30:00", "date_label": "ETA",
"country_code": "NL" },
"last_vessel_position": { "lat": 6.42, "lng": 79.85,
"updated_at": "2026-06-29 14:05:00" }
}
},
"source": {
"provider": "trackingmcp",
"provider_name": "TrackingMCP",
"route_geometry": "trackingmcp_computed",
"ais": "trackingmcp_vessel_positions",
"note": "Sea lane computed from a marine network; AIS from our own fused vessel positions."
}
}
}
}