Container Tracking API & MCP: Maersk, MSC, COSCO & More

Track containers from Maersk (including Hamburg Süd), MSC, COSCO, Evergreen, ONE and Yang Ming through the same tracking API and MCP tools as parcels, in the same normalized JSON. Carrier inference works where the number identifies the line; leased prefixes such as TGHU and TCNU require explicit carrier selection. Container watches recheck every 6 hours (hourly once a container is out for delivery).

No booking, bill of lading or shipping line account is needed: the container number is enough.


Supported Shipping Lines

Every example below is a real container looked up in November 2026.

LineSlug (?carrier=)Owner codes detectedExample containersWhat you get
Maersk (with Hamburg Süd)maerskMSKU MRKU MRSU MNBU SUDUMSKU7812341 · MNBU0123457Every move with vessel and voyage, local times, ETA
MSCmscMSCU MEDU MSDU MSMU MSNU MSBUMEDU1234562 · MSCU6789016Every move incl. transshipments, bill of lading, ETA
COSCO ShippingcoscoCSNU CBHU CCLU CSLU FCIUCSNU8123465 · CSNU7123455Latest move only (COSCO's public limit)
EvergreenevergreenEGHU EGSU EISU EITUEGHU9123457 · EGSU9123450Every move on the bill of lading, with vessel and voyage
ONE (Ocean Network Express)oneONEU KKFUONEU1234566 · ONEU0123450Every move with exact UTC times, vessel and voyage, ETA
Yang MingyangmingYMMUYMMU6123458 · YMMU7123452Every move incl. rail legs, with vessel and voyage

1. Container Numbers and Auto-Detection

A container number (ISO 6346) is the owner's 3-letter code plus U, six digits and a check digit: MSKU 781234 1. lastscanned checks the check digit and sends the number to the line that owns the code, so GET /v1/track/MSKU7812341 goes to Maersk with no ?carrier=.

Leased containers need ?carrier=. About half the world's boxes belong to leasing companies (Textainer TGHU, Triton TCNU and TRHU, CAI CAIU, SeaCo SEGU and others) and sail with any line. Their owner code says nothing about the line, so name it:

curl -s "https://api.lastscanned.com/v1/track/TGHU9123451?carrier=msc" \
  -H "Authorization: Bearer $LASTSCANNED_API_KEY"

Without ?carrier=, a leased container answers 400 unknown_carrier with a message saying to name the line. It is not billed.


2. Statuses for a Container's Trip

Containers use the same seven statuses as parcels, mapped onto a container's trip:

StatusContainer move
label_createdEmpty container released to the shipper
in_transitReceived full at the origin terminal, loaded, sailing, transshipped, discharged
out_for_deliveryFull container leaving the destination terminal for the consignee
deliveredEmpty container returned: the trip is over

The shipping lines don't report when the consignee unloads the goods, so delivered means the empty box is back. Watch for out_for_delivery if you need to know when the cargo left the port.


3. Times, ETAs and Bills of Lading

  • Times: most lines give local port time without a zone (MSC and Evergreen give a date only), so localTime is set and timestamp is null. Never read a container's localTime as UTC. ONE is the exception: it gives both, so both are exact.
  • ETA: Maersk's, MSC's and ONE's estimated arrival is estimatedDelivery (ONE's also as estimatedDeliveryAt in UTC). Planned moves are never mixed into events.
  • Bill of lading or booking: MSC and Evergreen name the bill the container sails under in message; ONE names the booking.

4. Watches and Webhooks for Containers

A container trip runs for weeks, so polling is wasteful. Set your webhook once, then create a watch per container. lastscanned re-checks it every 6 hours (hourly once it is out for delivery) and posts to your webhook when its status, newest move or ETA changes:

curl -s -X PUT "https://api.lastscanned.com/v1/webhook" \
  -H "Authorization: Bearer $LASTSCANNED_API_KEY" \
  -H "content-type: application/json" \
  -d '{"url": "https://example.com/hooks/containers"}'

curl -s -X POST "https://api.lastscanned.com/v1/watches" \
  -H "Authorization: Bearer $LASTSCANNED_API_KEY" \
  -H "content-type: application/json" \
  -d '{"trackingNumber": "MEDU1234562", "metadata": {"po": "PO-1042"}}'

A watch ends by itself when the empty container is returned, or after 90 days. On Pro, a container counts once per billing period however often it is re-checked.


5. Limits Worth Knowing

  • COSCO shows a container's latest move only, without the bill of lading. COSCO's firewall also blocks bursts, so a batch of COSCO containers is looked up one at a time.
  • Maersk and MSC are read through a browser session (their sites refuse plain server requests), so a lookup takes several seconds. One session serves a whole batch.
  • Other lines (CMA CGM, Hapag-Lloyd, HMM, ZIM) are not supported yet.

On this page