Skip to main content

🔼 Upstream API

Early‑Access API

🚧 Heads‑up! This is our next‑generation API and it's still under active development.

How you can help

  1. Try it out in non‑production environments first.
  2. Report issues or request features by mailing [email protected]

Thank you for partnering with us to shape the future of our platform!

Base URL: https://api.dockflow.com/v3 Scope token: upstream_* (production) or uat_upstream_* (sandbox)


1 · Delivery options

ModeWorkflowBest for
PollingGET /upstream → up to 1000 events, plus cursor for the next page.Batch jobs, cron.
WebhooksDockflow POSTs events to your HTTPS URL within seconds (automatic retries).Real‑time pipelines.

2 · Envelope format

{
"version": "3.0.0",
"tradeflow_reference": "PO4564268",

"data_quality": { // information about the Blue Sails
"freshness_min": 12,
"anomalies": 0,
"missed_milestones": 1,
"has_live_data": true,
"is_singular_shipment": false
},

"metadata": {
"last_updated": "2025‑05‑10T12:22:48Z",
"carrier_name": "Maersk",
"carrier_scac": "MAEU",
"is_active": true // whether the tradeflow is currently active
},

"locations": [
{ "reference": "BEANR", "name": "Port of Antwerp", "type": "SEA_PORT",
"timezone": "Europe/Brussels", "country": "Belgium",
"lat": 51.263, "lng": 4.398 }
],

"containers": [
{ "reference": "ABCD1234567", "iso_type": "45R1", "length_ft": 40,
"is_reefer": true,
"free_time": { // detention & demurrage window
"demurrage_free_time_expires": "2025‑06‑08T23:59:00+02:00",
"detention_free_time_expires": "2025‑06‑15T23:59:00+02:00",
},
"import_release_status": { // terminal release lights (Antwerp only)
"commercial": "OK", // shipping line release
"commercial_color": "GREEN",
"commercial_latest_update": "2025-06-05T10:30:00+02:00",
"customs": "RELEASED", // customs clearance
"customs_color": "GREEN",
"customs_latest_update": "2025-06-05T11:00:00+02:00",
"terminal": "READY", // terminal ready for pickup
"terminal_color": "GREEN",
"terminal_latest_update": "2025-06-05T11:15:00+02:00",
"terminal_code": "BEANR",
"source": "nxtport_cpu"
},
"arrival_at_pod_event_date": "2025‑06‑06T15:30:00‑07:00", // container ETA/ATA at final POD
"arrival_at_pod_event_date_extended": {
"event_date_zulu": "2025-06-06T22:30:00Z",
"event_date_local": "2025-06-06T15:30:00-07:00",
"timezone_geo": "America/Los_Angeles",
"timezone_utc_offset_minutes": -420,
"timezone_abbreviation": "PDT",
"vessel_schedule_event_date_zulu": "2025-06-06T22:30:00Z",
"vessel_schedule_event_date_local": "2025-06-06T15:30:00-07:00"
},
"arrival_at_pod_is_actual": false, // true if actual, false if estimated
"latest_actual_milestone": { // last confirmed milestone for this container
"code": "GN",
"event_date": "2025‑05‑09T10:34:00+02:00",
"event_date_extended": {
"event_date_zulu": "2025-05-09T08:34:00Z",
"event_date_local": "2025-05-09T10:34:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST"
},
"location_reference": "BEANR",
"is_pol": false, // true if at port of loading
"is_final_pod": false, // true if at final port of discharge
"is_transshipment": false, // true if at a transshipment port
"is_prepol": false, // true if before port of loading
"is_postpod": false // true if after final port of discharge
}}
],

"vessels": [
{ "name": "MAERSK SOPHIE", "imo": "9721234", "mmsi": "219028000" }
],

"shipment": {
"split_shipment_number": 2, // undefined if single leg
"port_of_loading": "BEANR",
"departure_event_date": "2025‑05‑14T10:00:00+02:00",
"departure_event_date_extended": {
"event_date_zulu": "2025-05-14T08:00:00Z",
"event_date_local": "2025-05-14T10:00:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-14T08:00:00Z",
"vessel_schedule_event_date_local": "2025-05-14T10:00:00+02:00"
},
"departure_is_actual": true,

"port_of_discharge": "USLAX",
"arrival_event_date": "2025‑06‑06T15:30:00‑07:00",
"arrival_event_date_extended": {
"event_date_zulu": "2025-06-06T22:30:00Z",
"event_date_local": "2025-06-06T15:30:00-07:00",
"timezone_geo": "America/Los_Angeles",
"timezone_utc_offset_minutes": -420,
"timezone_abbreviation": "PDT",
"vessel_schedule_event_date_zulu": "2025-06-06T22:30:00Z",
"vessel_schedule_event_date_local": "2025-06-06T15:30:00-07:00"
},
"arrival_is_actual": false,

"transshipment_ports": ["ESBCN"],
"incoterms": "FOB",
"cargo_opening_time": "2025‑05‑11T08:00:00+02:00",
"shipment_legs": [
{
"sequence_number": 0,
"vessel": "MAERSK SOPHIE",

"departure": "BEANR",
"departure_event_date": "2025-05-14T10:00:00+02:00",
"departure_event_date_extended": {
"event_date_zulu": "2025-05-14T08:00:00Z",
"event_date_local": "2025-05-14T10:00:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-14T08:00:00Z",
"vessel_schedule_event_date_local": "2025-05-14T10:00:00+02:00"
},
"departure_is_actual": true,
"departure_location_type": "pol",

"arrival": "ESBCN",
"arrival_event_date": "2025-05-20T08:00:00+02:00",
"arrival_event_date_extended": {
"event_date_zulu": "2025-05-20T06:00:00Z",
"event_date_local": "2025-05-20T08:00:00+02:00",
"timezone_geo": "Europe/Madrid",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-20T06:00:00Z",
"vessel_schedule_event_date_local": "2025-05-20T08:00:00+02:00"
},
"arrival_is_actual": false,
"arrival_location_type": "transshipment"
},
{
"sequence_number": 1,
"vessel": "MAERSK SOPHIE",

"departure": "ESBCN",
"departure_event_date": "2025-05-21T14:00:00+02:00",
"departure_event_date_extended": {
"event_date_zulu": "2025-05-21T12:00:00Z",
"event_date_local": "2025-05-21T14:00:00+02:00",
"timezone_geo": "Europe/Madrid",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-21T12:00:00Z",
"vessel_schedule_event_date_local": "2025-05-21T14:00:00+02:00"
},
"departure_is_actual": false,
"departure_location_type": "transshipment",

"arrival": "USLAX",
"arrival_event_date": "2025-06-06T15:30:00-07:00",
"arrival_event_date_extended": {
"event_date_zulu": "2025-06-06T22:30:00Z",
"event_date_local": "2025-06-06T15:30:00-07:00",
"timezone_geo": "America/Los_Angeles",
"timezone_utc_offset_minutes": -420,
"timezone_abbreviation": "PDT",
"vessel_schedule_event_date_zulu": "2025-06-06T22:30:00Z",
"vessel_schedule_event_date_local": "2025-06-06T15:30:00-07:00"
},
"arrival_is_actual": false,
"arrival_location_type": "pod"
}
],

"current_vessel": { // vessel the shipment is currently on
"name": "MAERSK SOPHIE",
"imo": "9721234",
"mmsi": "219028000"
},

"carbon_emissions": { // CO2 emissions (null if not yet calculated)
"distance_km": 12450.5, // route distance in kilometers
"co2_emissions_kg": 2134.8, // total CO2 (Well-to-Wheel)
"ttw_kg": 1850.2, // Tank-to-Wheel (direct combustion)
"wtt_kg": 284.6 // Well-to-Tank (fuel production)
}
},

"events": [
{ "id": "evt_01", "category": "MILESTONE", "code": "GN",
"message": "Gate in",
"event_date": "2025‑05‑09T10:34:00+02:00",
"event_date_extended": {
"event_date_zulu": "2025-05-09T08:34:00Z",
"event_date_local": "2025-05-09T10:34:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST"
},
"actual": true,
"container_reference": "ABCD1234567",
"location_reference": "BEANR",
"is_pol": false,
"is_final_pod": false,
"is_transshipment": false,
"is_prepol": false,
"is_postpod": false }
]
}

All date‑times (event_date, free‑time expiry, cargo opening) are expressed in the timezone of the location.


3 · Location type flags

Both the latest_actual_milestone object (in containers) and all events in the events array include boolean flags indicating the type of location where the milestone occurred:

  • is_pol: Port of Loading — where the container was loaded onto the first vessel
  • is_final_pod: Final Port of Discharge — where the container will be unloaded from the final vessel
  • is_transshipment: Transshipment Port — intermediate port where cargo transfers between vessels
  • is_prepol: Pre-POL Location — locations before the port of loading (e.g., depot, rail terminal)
  • is_postpod: Post-POD Location — locations after final discharge (e.g., inland destination, final delivery point)

Note: Multiple flags can be true simultaneously. For example, a milestone at a transshipment port that also serves as a POL for the next leg could have both is_transshipment and is_pol set to true.

Usage: These flags are particularly useful for vessel arrival/departure events (VA/VD) to determine whether the vessel is arriving at or departing from a POL, POD, or transshipment port.


4 · Current vessel

The current_vessel field in the shipment object shows which vessel the cargo is currently on:

Shipment StatusCurrent Vessel
Waiting at POL (no ATD yet)First vessel
In transit on a legVessel of that leg
On transshipment quay (arrived at T/S, waiting for next vessel)null
Arrived at final PODLast vessel

Example:

"current_vessel": {
"name": "MAERSK SOPHIE",
"imo": "9721234",
"mmsi": "219028000"
}

Returns null when cargo is on a transshipment quay between vessels.


5 · Carbon emissions

The carbon_emissions field provides CO2 emission data for the shipment route:

FieldTypeDescription
distance_kmfloatTotal route distance in kilometers (Haversine calculation)
co2_emissions_kgfloatTotal CO2 emissions in kg (Well-to-Wheel = TTW + WTT)
ttw_kgfloatTank-to-Wheel emissions (direct fuel combustion)
wtt_kgfloatWell-to-Tank emissions (upstream fuel production)

Example:

"carbon_emissions": {
"distance_km": 12450.5,
"co2_emissions_kg": 2134.8,
"ttw_kg": 1850.2,
"wtt_kg": 284.6
}

Note: Returns null if emissions have not yet been calculated (calculation typically occurs after shipment arrival).


6 · Import release status (green lights)

The import_release_status field in each container provides real-time pickup authorization status from terminal systems. This data comes from NxtPort Certified Pickup (CPu) for containers at Antwerp-Bruges terminals.

Fields

FieldTypeDescription
commercialstringShipping line release status value
commercial_colorstringColor indicator: GREEN, YELLOW, or RED
commercial_latest_updatestringTimestamp of last status change (ISO 8601)
customsstringCustoms clearance status value
customs_colorstringColor indicator: GREEN, YELLOW, or RED
customs_latest_updatestringTimestamp of last status change (ISO 8601)
terminalstringTerminal ready status value
terminal_colorstringColor indicator: GREEN, YELLOW, or RED
terminal_latest_updatestringTimestamp of last status change (ISO 8601)
terminal_codestringUNLOCODE of the terminal (e.g., BEANR)
sourcestringData source (e.g., nxtport_cpu)

Status values

Commercial release (shipping line authorization):

Valuecommercial_colorDescription
OKGREENReleased by shipping line
BLOCKEDREDBlocked by shipping line

Customs release (customs authority clearance):

Valuecustoms_colorDescription
RELEASEDGREENCustoms cleared
MANUALOVERWRITEGREENManually cleared
NOTRELEASEDREDNot yet released (initial state)
DOCUMENTARYCONTROLREDDocumentary control required
SELECTEDFORSCANYELLOWSelected for scanning
TRANSHIPMENTYELLOWTranshipment handling
TRANSFERYELLOWTransfer in progress
PORTEQUALISATIONYELLOWPort equalization
FAVVYELLOWFASFC inspection (food safety)

Terminal release (terminal ready for pickup):

Valueterminal_colorDescription
READYGREENTerminal ready for pickup
DISCHARGEDGREENContainer discharged from vessel
BLOCKEDREDTerminal blocked

Pickup authorization

Container can be picked up when all three lights are GREEN:

commercial_color = GREEN
customs_color = GREEN
terminal_color = GREEN
─────────────────────────────────────────────
→ Container ready for pickup ✅

If any light is RED or YELLOW, the container is not yet ready for pickup.

Example

"import_release_status": {
"commercial": "OK",
"commercial_color": "GREEN",
"commercial_latest_update": "2025-06-05T10:30:00+02:00",

"customs": "RELEASED",
"customs_color": "GREEN",
"customs_latest_update": "2025-06-05T11:00:00+02:00",

"terminal": "READY",
"terminal_color": "GREEN",
"terminal_latest_update": "2025-06-05T11:15:00+02:00",

"terminal_code": "BEANR",
"source": "nxtport_cpu"
}

Availability

  • Supported terminals: Antwerp-Bruges (BEANR, BEZEE) via NxtPort CPu
  • Requirements: Your organization must have NxtPort CPu credentials configured in Dockflow
  • Returns null: When import release status is not available for the container (non-Antwerp terminal or no credentials configured)

7 · Vessel Schedule Intelligence

Alongside per-tradeflow ETAs/ETDs, the API includes cross-tradeflow consensus dates derived from all tradeflows sharing the same vessel. When multiple tradeflows track the same vessel at the same port, Dockflow aggregates their readings into a single best-estimate using recency-weighted consensus.

Fields

Vessel schedule data is embedded inside the existing *_extended date objects as two additional fields:

FieldTypeDescription
vessel_schedule_event_date_zulustring | nullConsensus date in UTC (ISO 8601)
vessel_schedule_event_date_localstring | nullConsensus date in local time at the location (ISO 8601)

These fields appear in every _extended object that has vessel schedule context:

  • Shipment level: departure_event_date_extended, arrival_event_date_extended
  • Leg level: each leg's departure_event_date_extended, arrival_event_date_extended
  • Container level: arrival_at_pod_event_date_extended

Example

"departure_event_date_extended": {
"event_date_zulu": "2025-05-14T08:00:00Z",
"event_date_local": "2025-05-14T10:00:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-14T08:00:00Z", // consensus ETD (UTC)
"vessel_schedule_event_date_local": "2025-05-14T10:00:00+02:00" // consensus ETD (local)
}

Interpretation

  • Fields are omitted when no vessel schedule data is available (vessel not tracked cross-tradeflow, insufficient data, or low confidence)
  • The vessel_schedule_event_date_local uses the same timezone as event_date_local (derived from the port location)
  • When the tradeflow's own _is_actual is true, the vessel schedule fields are informational only — the actual reading is authoritative

8 · Extended date format

All date fields (event_date, arrival_at_pod_event_date, departure_event_date, arrival_event_date) include a corresponding *_extended object with full timezone context:

FieldTypeDescription
event_date_zulustringUTC/Zulu time in ISO 8601 format
event_date_localstringLocal time at the location in ISO 8601 format
timezone_geostringIANA timezone identifier (e.g., Europe/Brussels)
timezone_utc_offset_minutesintegerUTC offset in minutes (e.g., 120 for UTC+02:00)
timezone_abbreviationstringTimezone abbreviation (e.g., CEST, PDT)
vessel_schedule_event_date_zulustring | omittedVessel schedule consensus date in UTC (see §7)
vessel_schedule_event_date_localstring | omittedVessel schedule consensus date in local time (see §7)

Example:

"event_date": "2025-05-09T10:34:00+02:00",
"event_date_extended": {
"event_date_zulu": "2025-05-09T08:34:00Z",
"event_date_local": "2025-05-09T10:34:00+02:00",
"timezone_geo": "Europe/Brussels",
"timezone_utc_offset_minutes": 120,
"timezone_abbreviation": "CEST",
"vessel_schedule_event_date_zulu": "2025-05-09T08:30:00Z",
"vessel_schedule_event_date_local": "2025-05-09T10:30:00+02:00"
}

Note: If the location has no timezone configured, timezone_geo, timezone_utc_offset_minutes, and timezone_abbreviation will be null, and event_date_local will match the original event_date. The vessel_schedule_* fields are only present when vessel schedule data is available for that date (see §7).


9 · Status code table

CodeCategoryDescription
GEMILESTONEEmpty equipment dispatched
GNMILESTONEGate in
AEMILESTONELoaded on vessel
VDMILESTONEVessel departure
VAMILESTONEVessel arrival
UVMILESTONEUnloaded from vessel
GTMILESTONEGate out
GRMILESTONEEmpty equipment returned

10 · Attribute selection

Choose which blocks to receive with the fields parameter (polling and webhooks):

fields=events,locations,containers,shipment,vessels

Default fields (when parameter is omitted): events, locations, containers, shipment

To include the vessels array, explicitly add it to your fields parameter.


11 · Filters

ParamWhat it does
since=ISO‑dateOnly events created after this timestamp (UTC).
tradeflow=REFFilter by tradeflow reference.
container=REFFilter by container reference.
category=MILESTONEEvent category.
code=VDSpecific status code.
activeFilter by status: true (strictly active only), false, or both. Default (no param): active + recently deactivated (7 days).
per_page=1‑1000Page size (default 500).

12 · Error handling

StatusMeaningSuggested fix
400Invalid parameter.Check fields/filters spelling.
401Wrong token scope.Use an upstream_* token.
413Webhook body too large.Lower per_page or trim blocks via fields.
429Rate limit hit.Wait 60 s / reduce polling.
5xxDockflow outage.Retry with back‑off.

Questions? Contact [email protected] — engineers respond within one business day.