Beta: Exceptions via API
Please noteThis is a new experimental feature. We're actively soliciting feedback from users and may change certain details in response. To give feedback, please reach out to us at [email protected].
What are Exceptions?
Exceptions in OpenTrack are significant disruptions or changes to a container's journey that may impact smooth operations. When an exception is detected, users of OpenTrack's web app can be alerted.
Now you can be alerted via API, too. The container.exceptions.updated webhook event sends a notification when an exception is detected, so you can display the details to users of your own system or use it to trigger workflows.
Webhook Event: container.exceptions.updated
Available Exception Types
| exceptionName | Description |
|---|---|
rolledCargo | The container was changed to a different vessel with a new ETA |
streetDwell | The container was picked up from the terminal or rail yard but has not yet been returned empty (high street dwell) |
demurrageRisk | The container is approaching its Last Free Day and has not yet been picked up |
railDwell | The container has been waiting at the port for rail loading longer than the configured rail dwell threshold |
splitCargo | Containers from the same booking are now travelling on different vessels |
demurrageDetected | The container has passed its Last Free Day and is incurring demurrage charges |
activeHold | The container has one or more active customs or freight holds preventing pickup |
noRailSightings | A rail container has had no rail sighting events for 48+ hours |
Want more exception types? Please let us know at [email protected] or in your in-app chat.
Exception Status (rolledCargo only)
| exceptionStatus | Meaning |
|---|---|
Rolled | Container was moved to a later vessel (ETA delayed) |
Advanced | Container was moved to an earlier vessel (ETA improved) |
Payload structure
Unlike other webhook events, container.exceptions.updated has a simplified payload with exception-specific fields in a context object and no changes object:
{
"event": "container.exceptions.updated",
"data": {
"containerId": "MSCU1234567",
"masterBillNumber": "MEDU123456789",
"scacCode": "MSCU",
"exceptionName": "rolledCargo",
"context": {
"originPort": { ... },
"destinationPort": { ... },
"previousVessel": { "name": "ORIGINAL VESSEL" },
"currentVessel": { "name": "NEW VESSEL", "imo": "1234", "mmsi": "1234" },
"previousEta": "2025-12-11T16:00:00.000Z",
"currentEta": "2025-12-14T16:00:00.000Z"
}
},
"deliveryAttempt": 1,
"pendingRetries": 4,
"sentAt": "2025-12-11T16:00:00.000Z"
}
Context fields by exception type
All exception payloads include containerId, masterBillNumber, scacCode, and exceptionName at the top level of data. The context object varies by exception:
| exceptionName | context fields |
|---|---|
rolledCargo | originPort, destinationPort, previousVessel, currentVessel, previousEta, currentEta |
streetDwell | status, originPort, destinationPort, outgatedDate, emptyReturnedDate, detentionLastFreeDay |
demurrageRisk | status, lastFreeDay, lineLastFreeDay, lastFreeDayAtRailStation, isRailMove, originPort, destinationPort |
railDwell | status, originPort, destinationPort, dischargedDate |
splitCargo | status, originPort, destinationPort, siblingContainers |
demurrageDetected | status, demurrageOwedAtPort, demurrageOwedAtRailStation, isRailMove, originPort, destinationPort |
activeHold | status, holds, originPort, destinationPort |
noRailSightings | status, lastKnownPositionDate, originPort, destinationPort |
For splitCargo, siblingContainers is an array of related containers on the same master bill that have advanced while this container has not. Each entry includes containerId and status.
