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.
| Line | Slug (?carrier=) | Owner codes detected | Example containers | What you get |
|---|---|---|---|---|
| Maersk (with Hamburg Süd) | maersk | MSKU MRKU MRSU MNBU SUDU | MSKU7812341 · MNBU0123457 | Every move with vessel and voyage, local times, ETA |
| MSC | msc | MSCU MEDU MSDU MSMU MSNU MSBU | MEDU1234562 · MSCU6789016 | Every move incl. transshipments, bill of lading, ETA |
| COSCO Shipping | cosco | CSNU CBHU CCLU CSLU FCIU | CSNU8123465 · CSNU7123455 | Latest move only (COSCO's public limit) |
| Evergreen | evergreen | EGHU EGSU EISU EITU | EGHU9123457 · EGSU9123450 | Every move on the bill of lading, with vessel and voyage |
| ONE (Ocean Network Express) | one | ONEU KKFU | ONEU1234566 · ONEU0123450 | Every move with exact UTC times, vessel and voyage, ETA |
| Yang Ming | yangming | YMMU | YMMU6123458 · YMMU7123452 | Every 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:
| Status | Container move |
|---|---|
label_created | Empty container released to the shipper |
in_transit | Received full at the origin terminal, loaded, sailing, transshipped, discharged |
out_for_delivery | Full container leaving the destination terminal for the consignee |
delivered | Empty 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
localTimeis set andtimestampisnull. Never read a container'slocalTimeas 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 asestimatedDeliveryAtin UTC). Planned moves are never mixed intoevents. - 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.
Related Resources
- Formats and check digits: Tracking number formats & auto-detection
- Freight by road: LTL freight & heavy parcel tracking
- Agents: MCP server