🔼 Upstream API
🚧 Heads‑up! This is our next‑generation API and it's still under active development.
How you can help
- Try it out in non‑production environments first.
- 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/v3Scope token:upstream_*(production) oruat_upstream_*(sandbox)
1 · Delivery options
| Mode | Workflow | Best for |
|---|---|---|
| Polling | GET /upstream → up to 1000 events, plus cursor for the next page. | Batch jobs, cron. |
| Webhooks | Dockflow 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 vesselis_final_pod: Final Port of Discharge — where the container will be unloaded from the final vesselis_transshipment: Transshipment Port — intermediate port where cargo transfers between vesselsis_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 Status | Current Vessel |
|---|---|
| Waiting at POL (no ATD yet) | First vessel |
| In transit on a leg | Vessel of that leg |
| On transshipment quay (arrived at T/S, waiting for next vessel) | null |
| Arrived at final POD | Last 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:
| Field | Type | Description |
|---|---|---|
distance_km | float | Total route distance in kilometers (Haversine calculation) |
co2_emissions_kg | float | Total CO2 emissions in kg (Well-to-Wheel = TTW + WTT) |
ttw_kg | float | Tank-to-Wheel emissions (direct fuel combustion) |
wtt_kg | float | Well-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
| Field | Type | Description |
|---|---|---|
commercial | string | Shipping line release status value |
commercial_color | string | Color indicator: GREEN, YELLOW, or RED |
commercial_latest_update | string | Timestamp of last status change (ISO 8601) |
customs | string | Customs clearance status value |
customs_color | string | Color indicator: GREEN, YELLOW, or RED |
customs_latest_update | string | Timestamp of last status change (ISO 8601) |
terminal | string | Terminal ready status value |
terminal_color | string | Color indicator: GREEN, YELLOW, or RED |
terminal_latest_update | string | Timestamp of last status change (ISO 8601) |
terminal_code | string | UNLOCODE of the terminal (e.g., BEANR) |
source | string | Data source (e.g., nxtport_cpu) |
Status values
Commercial release (shipping line authorization):
| Value | commercial_color | Description |
|---|---|---|
OK | GREEN | Released by shipping line |
BLOCKED | RED | Blocked by shipping line |
Customs release (customs authority clearance):
| Value | customs_color | Description |
|---|---|---|
RELEASED | GREEN | Customs cleared |
MANUALOVERWRITE | GREEN | Manually cleared |
NOTRELEASED | RED | Not yet released (initial state) |
DOCUMENTARYCONTROL | RED | Documentary control required |
SELECTEDFORSCAN | YELLOW | Selected for scanning |
TRANSHIPMENT | YELLOW | Transhipment handling |
TRANSFER | YELLOW | Transfer in progress |
PORTEQUALISATION | YELLOW | Port equalization |
FAVV | YELLOW | FASFC inspection (food safety) |
Terminal release (terminal ready for pickup):
| Value | terminal_color | Description |
|---|---|---|
READY | GREEN | Terminal ready for pickup |
DISCHARGED | GREEN | Container discharged from vessel |
BLOCKED | RED | Terminal 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:
| Field | Type | Description |
|---|---|---|
vessel_schedule_event_date_zulu | string | null | Consensus date in UTC (ISO 8601) |
vessel_schedule_event_date_local | string | null | Consensus 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_localuses the same timezone asevent_date_local(derived from the port location) - When the tradeflow's own
_is_actualistrue, 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:
| Field | Type | Description |
|---|---|---|
event_date_zulu | string | UTC/Zulu time in ISO 8601 format |
event_date_local | string | Local time at the location in ISO 8601 format |
timezone_geo | string | IANA timezone identifier (e.g., Europe/Brussels) |
timezone_utc_offset_minutes | integer | UTC offset in minutes (e.g., 120 for UTC+02:00) |
timezone_abbreviation | string | Timezone abbreviation (e.g., CEST, PDT) |
vessel_schedule_event_date_zulu | string | omitted | Vessel schedule consensus date in UTC (see §7) |
vessel_schedule_event_date_local | string | omitted | Vessel 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
| Code | Category | Description |
|---|---|---|
| GE | MILESTONE | Empty equipment dispatched |
| GN | MILESTONE | Gate in |
| AE | MILESTONE | Loaded on vessel |
| VD | MILESTONE | Vessel departure |
| VA | MILESTONE | Vessel arrival |
| UV | MILESTONE | Unloaded from vessel |
| GT | MILESTONE | Gate out |
| GR | MILESTONE | Empty 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
| Param | What it does |
|---|---|
since=ISO‑date | Only events created after this timestamp (UTC). |
tradeflow=REF | Filter by tradeflow reference. |
container=REF | Filter by container reference. |
category=MILESTONE | Event category. |
code=VD | Specific status code. |
active | Filter by status: true (strictly active only), false, or both. Default (no param): active + recently deactivated (7 days). |
per_page=1‑1000 | Page size (default 500). |
12 · Error handling
| Status | Meaning | Suggested fix |
|---|---|---|
| 400 | Invalid parameter. | Check fields/filters spelling. |
| 401 | Wrong token scope. | Use an upstream_* token. |
| 413 | Webhook body too large. | Lower per_page or trim blocks via fields. |
| 429 | Rate limit hit. | Wait 60 s / reduce polling. |
| 5xx | Dockflow outage. | Retry with back‑off. |
Questions? Contact [email protected] — engineers respond within one business day.