ONE Line Port Schedules & Cut-offs Scraper avatar

ONE Line Port Schedules & Cut-offs Scraper

Pricing

from $1.80 / 1,000 port call scrapeds

Go to Apify Store
ONE Line Port Schedules & Cut-offs Scraper

ONE Line Port Schedules & Cut-offs Scraper

Scrape ONE (Ocean Network Express) berth schedules per port: arrival/berthing/departure times, cargo/document/VGM cut-offs and coded delay reasons. Optional vessel particulars (GT/NT, IMO, class).

Pricing

from $1.80 / 1,000 port call scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Categories

Share

ONE Port Schedules: Berth calls by port with ETA, ETB, ETD, the four booking cut-offs and coded delay reasons

Pulls Ocean Network Express (ONE) berth schedules directly from the same public schedule service ONE's own website uses. For any port you name, you get every vessel call in your date window: arrival, berthing and departure with their status codes, four separate cut-off timestamps (cargo, document, VGM, inland), the vessel's voyage identifiers, and a coded reason whenever ONE has flagged the call as delayed.

No browser, no proxy, no login required to use this Actor. Point it at a UN/LOCODE or a port name and it does the rest, including resolving names to codes and, optionally, enriching each call with the vessel's own particulars (tonnage, IMO number, flag, class, build date).

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/one-line-port-schedules-scraper.md

What you get

FieldWhat it holds
portCode, portNameThe UN/LOCODE you asked for, and the port name ONE resolved it to
vvdName, vesselName, vesselCodeVoyage identifier (vessel + voyage + direction), vessel name, ONE's internal vessel code
scheduleVoyageNumber, scheduleDirectionCodeVoyage number and direction (E/W/N/S-style trade lane code)
yardName, yardCode, terminalNameMaskFlagTerminal the call is berthing at, plus ONE's own flag for whether the terminal name is masked at source
vesselServiceLaneCode, vesselServiceTypeCodeONE's own service/trade-lane codes
arrivalDateTime, arrivalStatusETA/ATA and whether it is estimated or actual
berthingDateTime, berthingStatusETB/ATB and its status
departureDateTime, departureStatusETD/ATD and its status
cargoCutOffDateTime, documentCutOffDateTime, vgmCutOffDateTime, inlandCutOffDateTimeThe four booking cut-offs, each null when the source has none set
vesselDelayReasonCode, vesselDelayReasonONE's coded delay reason and its plain-text explanation, when the call is delayed
netTonnage, grossTonnage, portRegistry, ownerName, callSign, carrier, builtOn, lloydsNo, registryCode, classNo, ageVessel particulars, only when includeVesselDetails is on; otherwise null
vesselDetailsFetched, vesselDetailDisplaytrue when the particulars above were actually fetched for this row; vesselDetailDisplay is ONE's own Y/N flag for whether it publishes vessel details for this call
fromDate, toDate, vesselType, cargoNatureThe window and filters the run used
scrapedAtRun timestamp

RUN_SUMMARY in the key-value store holds per-port counts, any port or port-name lookup that failed, and the vessel-lookup tally.

Use cases

  • Schedule slippage tracking. vesselDelayReasonCode is a coded field most schedule sources don't expose at all, pull it across a trade lane over time and you have a real delay attribution dataset, not just a slipping ETA.
  • Booking cut-off alerts. Watch cargoCutOffDateTime/documentCutOffDateTime/vgmCutOffDateTime for the vessels you have cargo on and alert before a cut-off passes.
  • Berth utilisation. yardCode plus berthingDateTime/departureDateTime gives terminal-level occupancy for a port.
  • Vessel due diligence. includeVesselDetails adds GT/NT, IMO number, flag and class for every vessel calling a port, without a separate vessel-particulars source.

Quick start

Rotterdam's next two weeks, the default:

{}

Two named ports, capped:

{
"portCodes": ["NLRTM", "DEHAM"],
"fromDate": "2026-08-22",
"toDate": "2026-09-05",
"maxRecords": 200
}

Resolve a port by name instead of knowing its code, with vessel particulars merged in:

{
"portNames": ["rotterdam"],
"includeVesselDetails": true,
"maxRecords": 50
}

Input

FieldTypeDefaultNotes
portCodesarray["NLRTM"]UN/LOCODEs to read, e.g. NLRTM, DEHAM. Case-insensitive, deduplicated, merged with anything portNames resolves.
portNamesarray[]Port names or partial names (3+ letters) to resolve to UN/LOCODEs before scraping. A name matching several ports resolves to all of them. A name matching nothing is recorded in RUN_SUMMARY.nameResolutionFailures and does not stop the run.
fromDatestringtodayWindow start, YYYY-MM-DD.
toDatestringfromDate + 14 daysWindow end, YYYY-MM-DD. Must not be before fromDate.
vesselTypestringIDirection filter passed through as-is. I (inbound) is the only confirmed value.
cargoNaturestringGENERAL_PURPOSECargo-nature filter passed through as-is. GENERAL_PURPOSE is the only confirmed value.
maxRecordsinteger200Stop once this many berth calls have been saved across all ports. 0 means no limit.
includeVesselDetailsbooleanfalseMerge tonnage/IMO/flag/class/build-date into every row for each distinct vessel found. Adds one extra request per distinct vessel, capped at 40 per run.

Nothing is required. Running with no input returns Rotterdam's next two weeks.

Output example

A berth call with vessel particulars off (the default):

{
"portCode": "NLRTM",
"portName": "ROTTERDAM, NETHERLANDS",
"vvdName": "OOCL VERACRUZ 020W",
"vesselName": "OOCL VERACRUZ",
"vesselCode": "OVZT",
"vesselDetailDisplay": "Y",
"scheduleVoyageNumber": "0020",
"scheduleDirectionCode": "W",
"yardName": "RWG (ROTTERDAM WORLD GATEWAY)",
"yardCode": "NLRTM15",
"vesselServiceLaneCode": "AT3",
"arrivalDateTime": "2026-08-18 12:39",
"arrivalStatus": "A",
"berthingDateTime": "2026-08-20 18:44",
"berthingStatus": "A",
"departureDateTime": "2026-08-22 00:02",
"departureStatus": "A",
"cargoCutOffDateTime": "2026-08-19 18:44",
"documentCutOffDateTime": "2026-08-18 09:00",
"vgmCutOffDateTime": "2026-08-19 09:00",
"inlandCutOffDateTime": null,
"vesselDelayReasonCode": "OPP",
"vesselDelayReason": "Delay from previous port/voyage",
"vesselServiceTypeCode": "J",
"terminalNameMaskFlag": "N",
"netTonnage": null,
"grossTonnage": null,
"portRegistry": null,
"ownerName": null,
"callSign": null,
"carrier": null,
"builtOn": null,
"lloydsNo": null,
"registryCode": null,
"classNo": null,
"age": null,
"vesselDetailsFetched": false,
"fromDate": "2026-08-22",
"toDate": "2026-08-29",
"vesselType": "I",
"cargoNature": "GENERAL_PURPOSE",
"scrapedAt": "2026-08-21T22:47:53.796Z"
}

With includeVesselDetails: true, the same row also carries the vessel's own particulars:

{
"netTonnage": "27173.000",
"grossTonnage": "57907.000",
"portRegistry": "MONROVIA, LIBERIA (LRMLW)",
"ownerName": "CHARTER",
"callSign": "5LNG2",
"carrier": "ORIENT OVERSEAS CONTAINER LINE (OOL)",
"builtOn": "2024-01-01",
"lloydsNo": "9979266",
"registryCode": "LR",
"classNo": "ABS / ",
"age": "3",
"vesselDetailsFetched": true
}

Naming a port

You write in portCodesActor reads
NLRTMRotterdam, exactly as given (uppercased)
nlrtm, NLRTMSame, case-folded and trimmed
You write in portNamesActor resolves to
rotterdamNLRTM (one match)
hamEvery port whose name contains "ham", Hamburg, Hamina, Immingham, and more. Use portCodes once you know the exact one.

portCodes and portNames are additive: name every port you know the code for in portCodes, and use portNames only for discovery.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~one-line-port-schedules-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"portCodes": ["NLRTM"],
"fromDate": "2026-08-22",
"toDate": "2026-09-05",
"maxRecords": 200
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/one-line-port-schedules-scraper').call({
portCodes: ['NLRTM', 'DEHAM'],
fromDate: '2026-08-22',
toDate: '2026-09-05',
maxRecords: 300,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const call of items) {
console.log(`${call.portCode} ${call.vesselName} berths ${call.berthingDateTime} (${call.berthingStatus}), cargo cut-off ${call.cargoCutOffDateTime}`);
}

Notes

  • There is no pagination on the source: one request per port returns every call in the window at once, so maxRecords is the only depth control and it bounds the whole run, not each port.
  • An unrecognised port code is a legitimate empty result (zero rows, no failure recorded), the same way it behaves on ONE's own schedule page, it is not distinguishable from "this port has no calls in this window."
  • An unresolvable portNames entry is recorded in RUN_SUMMARY.nameResolutionFailures and does not stop the run as long as another port produced results.
  • Requests to different ports run one at a time rather than in parallel, so a run over several ports takes roughly as long as the sum of its parts.
  • vesselDelayReasonCode/vesselDelayReason, the four cut-off fields, and arrivalStatus/berthingStatus/departureStatus change as a call approaches and completes. Treat every run as a snapshot at scrapedAt, not a final record.
  • Retries (3 attempts, linear backoff) cover transient failures. A malformed date, or an input with nothing usable to look up, ends the run immediately with the reason recorded in RUN_SUMMARY.configError.

FAQ

Do I need a ONE account or API key? No. The service this Actor reads is the same unauthenticated one ONE's own public schedule page calls.

Which ports are covered? Any port ONE calls at, globally. Try portNames first if you are unsure of the UN/LOCODE.

How far ahead can I query? As far as ONE's own schedule page shows, schedules are typically published a few weeks out, and how far back or forward a given port has data varies port to port.

Why is a cut-off field null? ONE simply has none set for that call. inlandCutOffDateTime in particular is empty on most calls.

What does vesselDelayReasonCode mean? It is ONE's own operational delay code (for example OPP for a delay carried over from the previous port/voyage). vesselDelayReason is the paired plain-text explanation; use the code for grouping and the text for display.

Can I get a vessel's IMO number without pulling a whole port's schedule? Not from this Actor directly, vessel particulars are looked up per vessel found while scraping a port's schedule (includeVesselDetails: true), not standalone.

Can I plug it into something else? Yes. Apify API, the client libraries, webhooks, scheduled runs, dataset exports to JSON, CSV or Excel, or MCP. The output is structured JSON.