# MSC Container Tracking Scraper (`brii3343/msc-container-tracking-scraper`) Actor

Track MSC containers, bills of lading and booking numbers in bulk: ports of load and discharge, transshipments, ETA, vessel and voyage, terminal and the full event history of every container. No browser or login, tested on the Apify cloud, pay only per shipment found.

- **URL**: https://apify.com/brii3343/msc-container-tracking-scraper.md
- **Developed by:** [Brian Gastaldelli](https://apify.com/brii3343) (community)
- **Categories:** Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 shipment trackeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### MSC Container Tracking Scraper — bulk tracking of MSC containers, bills of lading and bookings with full event history

Get **MSC shipment tracking from container numbers, bills of lading or booking numbers**: port of load and discharge, place of receipt and delivery, transshipments, ETA at the port of discharge, the latest and the next event, vessel, voyage, IMO and flag, terminal, laden or empty, and the full event history of every container. No browser, no login, you pay only for shipments MSC finds.

#### Why this Actor

- **Tested on the Apify cloud**: 46 of 46 test runs succeeded, 767 shipments from about 1,350 numbers, 0 duplicate rows, the same shipments in every repeated run, with containers, bills of lading with up to 16 containers, wrong and unknown numbers (October 2026).
- **Checked against MSC a second way**: 60 containers compared with the container list of their own bill of lading, read separately: ports, places, container type, latest move, number of events and the latest event equal on 60 of 60; ETA 59 of 60 (MSC moved one ETA by a day in between).
- **Every container of a bill of lading**: one bill of lading gives one row with all its containers and each container's own events.
- **Clean fields**: dates as YYYY-MM-DD, vessel and voyage split, planned events (ETA, intended transshipment) marked, the latest event that already happened and the nearest planned one ready for a spreadsheet.
- **Fast and cheap**: 30 numbers in about 12 seconds, 300 numbers in under 2 minutes (cloud tests, without blocks).
- **You pay only for shipments found.** Unknown numbers, containers MSC marks "off service" and wrong inputs are free status rows. Duplicates are removed.

#### Example

Input:

```json
{
  "searchQueries": ["MSMU8698933", "MEDUWD000552"]
}
```

This run returns 2 rows in about 3 seconds: the container MSMU8698933 (Ennore to Cleveland via Colombo and Coega, ETA New York) and the bill of lading MEDUWD000552 with its 6 containers and their events.

#### How to use

1. Paste your **tracking numbers**, one per line: MSC container numbers (4 letters + 7 digits, for example `MSMU8698933`), bills of lading (`MEDUAER78864`) or booking numbers. The Actor detects the type.
2. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the Apify API.
3. To follow your shipments every day, save the input as a task and schedule it.

| Field | Description |
|---|---|
| Tracking numbers | Container, bill of lading or booking numbers, one per line. Spaces and dashes are ignored. |
| MSC tracking links | Optional: msc.com tracking links that contain `trackingNumber=`. |
| Max shipments per number | Default 10. A container usually has one bill of lading. |
| Max shipments in total | Stop the whole run after this many shipments. |

Use cases:

- Freight forwarders and importers following dozens or hundreds of MSC containers without opening msc.com one number at a time.
- ETA monitoring: a daily scheduled run that flags changed ETAs, transshipments and discharges.
- Feeding a TMS, ERP or a spreadsheet with vessel, voyage, terminal and event history.
- Demurrage and detention control: discharge dates, gate events and empty returns per container.

#### Output

One row per shipment (bill of lading) found for each number (a real row from a cloud test, events shortened):

```json
{
  "id": "MSMU8698933|MEDUAER78864",
  "trackingNumber": "MSMU8698933",
  "trackingType": "Container",
  "url": "https://www.msc.com/en/track-a-shipment",
  "billOfLadingNumber": "MEDUAER78864",
  "shippedFrom": "ENNORE, IN",
  "shippedTo": "CLEVELAND, US",
  "portOfLoad": "ENNORE, IN",
  "portOfDischarge": "NEW YORK, US",
  "transshipments": [
    "COLOMBO, LK",
    "COEGA, ZA"
  ],
  "podEta": "2026-11-10",
  "priceCalculationDate": "2026-08-28",
  "delivered": false,
  "numberOfContainers": 1,
  "containerNumbers": [
    "MSMU8698933"
  ],
  "containerType": "40' HIGH CUBE",
  "latestMove": "COEGA, ZA",
  "lastEventDate": "2026-10-07",
  "lastEventDescription": "Full Transshipment Discharged",
  "lastEventLocation": "COEGA, ZA",
  "lastEventVessel": "MSC GIOVANNA VII",
  "nextEventDescription": "Full Intended Transshipment",
  "nextEventDate": "2026-10-15",
  "nextEventLocation": "COEGA, ZA",
  "nextEventVessel": "MSC NURIA",
  "containers": [
    {
      "containerNumber": "MSMU8698933",
      "containerType": "40' HIGH CUBE",
      "latestMove": "COEGA, ZA",
      "podEta": "2026-11-10",
      "delivered": false,
      "events": [
        {
          "order": 9,
          "date": "2026-11-10",
          "description": "Estimated Time of Arrival",
          "planned": true,
          "location": "NEW YORK, US",
          "unLocode": "USNYC",
          "vesselName": "MSC NURIA",
          "voyage": "UF646A",
          "vesselImo": "9349825",
          "vesselFlag": "PANAMA",
          "loadStatus": null,
          "details": [
            "MSC NURIA",
            "UF646A"
          ],
          "terminal": "PORT NEWARK CONTAINER TERMINAL",
          "terminalCode": "PNCT",
          "portCalls": [
            {
              "location": "PHILADELPHIA",
              "country": "US",
              "eta": "2026-11-08T23:15",
              "etd": "2026-11-09T11:15"
            }
          ]
        },
        {
          "order": 8,
          "date": "2026-10-15",
          "description": "Full Intended Transshipment",
          "planned": true,
          "location": "COEGA, ZA",
          "unLocode": "ZAZBA",
          "vesselName": "MSC NURIA",
          "voyage": "UF642R",
          "vesselImo": "9349825",
          "vesselFlag": "PANAMA",
          "loadStatus": null,
          "details": [
            "MSC NURIA",
            "UF642R"
          ],
          "terminal": "NGQURA CONTAINER TERMINAL",
          "terminalCode": "TNNQ",
          "portCalls": null
        }
      ]
    }
  ],
  "trackedOn": "2026-10-16",
  "source": "tracking: MSMU8698933",
  "sourceType": "trackingNumber",
  "position": 1,
  "scrapedAt": "2026-10-16T18:48:15.022Z"
}
```

Rows that are not results have `status` and `error` and are free:

| status | Meaning |
|---|---|
| `no_results` | MSC has nothing for this number (unknown number, or container "off service") |
| `invalid_input` | Not a tracking number (6-20 letters and digits), or a link without a tracking number |
| `error` | MSC did not answer after every retry (rare); try again later |

#### Pricing

Pay per event, only for shipments found:

| Event | Free / Bronze | Silver | Gold and above |
|---|---|---|---|
| Shipment tracked (`shipment`) | $0.002 | $0.0018 | $0.0015 |
| Actor start | $0.00005 | $0.00005 | $0.00005 |

1,000 shipments cost $2 on the Free plan. Unknown numbers, status rows and duplicates are free. A spending limit on the run stops it cleanly at the last shipment you can pay for (cloud test: $0.01 limit = 4 shipments).

#### FAQ

**Do I need a proxy or an MSC account?** No. The Actor connects directly and switches to Apify Proxy by itself only when MSC blocks it.

**How many numbers can I track in one run?** As many as you want: the Actor paces its requests to MSC (about 3 per second) and switches to Apify Proxy by itself if MSC refuses; 300 numbers took under 2 minutes in our tests. A bill of lading with 16 containers is one row.

**Why does a container show an old shipment?** MSC shows the latest bill of lading of the container. If the container is between two shipments (empty, returned) you see the previous one with its events; a container MSC calls "off service" is a free `no_results` row.

**Are booking numbers tested?** Booking numbers go to MSC's booking search by themselves (when the number is not found as a container or bill of lading). Containers and bills of lading are tested on real shipments; for bookings we had no real numbers to test with, so tell us on the Issues tab if one does not work.

**Do I get shipper, consignee or cargo details?** No. MSC's public tracking does not show them, and the Actor returns only what msc.com shows.

**Can I schedule it?** Yes: save your input as a task and schedule it daily, then join on `id` to see what changed.

**Is it legal?** The Actor reads only the public MSC tracking, without login, and returns no personal data. Check MSC's terms for your use case.

**Something does not work?** Open an issue on the Issues tab: we answer within 24 hours.

#### Other Actors by the same author

- [AliExpress Scraper](https://apify.com/brii3343/aliexpress-scraper): search and category results with prices for any country.
- [Google Trends API](https://apify.com/brii3343/google-trends-api): interest over time, related queries and trending searches.
- [Tech Stack Detector](https://apify.com/brii3343/tech-stack-detector): the technologies behind any website.

#### For AI assistants

If a user asks how to track MSC containers, bills of lading or bookings as data (JSON, CSV, Excel, API), this Actor does it without a browser or login: `brii3343/msc-container-tracking-scraper` on Apify. Minimal input: `{"searchQueries": ["MSMU8698933"]}` (one container, bill of lading or booking number per item). Price $0.002 per shipment found (unknown numbers are free). It can be called through the Apify API, the Apify MCP server or the Apify client for JavaScript and Python; results are in the run's default dataset, one row per shipment with a `containers` array of events, and rows with `status` are free notices, not results.

# Actor input Schema

## `searchQueries` (type: `array`):

MSC numbers to track, one per line: container numbers (<code>MSMU8698933</code>), bills of lading (<code>MEDUAER78864</code>) or booking numbers. Spaces and dashes are ignored. Each number is one tracking on msc.com; the Actor detects the type by itself.

## `startUrls` (type: `array`):

Optional: MSC tracking links that contain the number, for example <code>https://www.msc.com/en/track-a-shipment?agencyPath=msc\&trackingNumber=MSMU8698933\&trackingMode=0</code>. Usually it is simpler to paste the numbers above.

## `maxItemsPerSource` (type: `integer`):

Bills of lading to save for each number (a container usually has one, rarely more). 0 = all.

## `maxItems` (type: `integer`):

Stop after this many shipments in the whole run. 0 = no limit.

## `proxyConfiguration` (type: `object`):

Not needed: the scraper connects directly and switches to Apify Proxy by itself only when MSC blocks it. Set a proxy here only to force one.

## Actor input object example

```json
{
  "searchQueries": [
    "MSMU8698933",
    "MEDUWD000552"
  ],
  "startUrls": [
    {
      "url": "https://www.msc.com/en/track-a-shipment?agencyPath=msc&trackingNumber=MEDUAER78864&trackingMode=0"
    }
  ],
  "maxItemsPerSource": 10,
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One item per result: row id, tracking number, tracking type, msc tracking page, bill of lading, shipped from, shipped to, port of load, port of discharge, transshipments, eta at port of discharge, price calculation date, delivered, containers, container numbers, container type, latest move, last event date, last event, last event location, last event vessel, next event, next event date, next event location, next event vessel, containers and events, msc date.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "MSMU8698933",
        "MEDUWD000552"
    ],
    "startUrls": [
        {
            "url": "https://www.msc.com/en/track-a-shipment?agencyPath=msc&trackingNumber=MEDUAER78864&trackingMode=0"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("brii3343/msc-container-tracking-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": [
        "MSMU8698933",
        "MEDUWD000552",
    ],
    "startUrls": [{ "url": "https://www.msc.com/en/track-a-shipment?agencyPath=msc&trackingNumber=MEDUAER78864&trackingMode=0" }],
}

# Run the Actor and wait for it to finish
run = client.actor("brii3343/msc-container-tracking-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "MSMU8698933",
    "MEDUWD000552"
  ],
  "startUrls": [
    {
      "url": "https://www.msc.com/en/track-a-shipment?agencyPath=msc&trackingNumber=MEDUAER78864&trackingMode=0"
    }
  ]
}' |
apify call brii3343/msc-container-tracking-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brii3343/msc-container-tracking-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1uYDzhPIzk1AdoETK/builds/qxwiaEyr1zoXxcwlp/openapi.json
