Shipment / Tour Webhooks
To proactively notify customer systems about changes to transport orders/shipments and tours, webhooks can be configured in X4Fleet for both entities.
For each entity there is a list of events that can trigger a webhook.
Webhooks can be configured by admin users in X4Fleet under Settings > Settings > "Status notifications (Webhooks)".

For authentication of the POST request, either a username/password pair or an x509 certificate can be stored.
If a different method is required or X4Fleet itself should not send requests to the customer system, these can also be proactively retrieved (e.g. every 5 minutes) by the customer system. (Enable the checkbox "Use webhook storage only" for this.)
Even if the payload is very extensive, it is recommended to treat the webhook only as a trigger for "Hey, something happened to shipment X. Go check it out!" — meaning a GET Shipment or GET Tour is triggered by the customer system to get further details. This is because the webhook payload is intended to become leaner over time and new data structures will only be built into the corresponding endpoints.
Endpoints:
GET /x4gateway/v1/export/webhookShipmentMessages
GET /x4gateway/v1/export/webhookTourMessages
Shipment / Transport Order Triggers
- In progress - The shipment has been created but is still being edited or information is missing
- Released - The shipment was manually or via setting released for planning onto a tour
- Scheduled - Shipment was assigned to a tour
- Pickup completed
- Delivery completed
- Quantity split - Shipment was split into N additional shipments because the quantity cannot be handled in one trip
- Route split - Shipment was split into N additional shipments because the goods are routed via N depots before reaching their destination
- Completed
- Completed with reservation - There are discrepancies between execution and planning (e.g. less was loaded than planned)
- Reopened - Something on the shipment needs to be corrected
Tour Triggers
- In planning - A first shipment was assigned to the tour (usually not relevant for customer system)
- Planned - The tour was calculated or optimized (usually not relevant for customer system)
- Released - The tour was released for execution (depending on the process, several days may pass between release and execution)
- Re-released - The tour was recalled, possibly changed, and re-released for execution
- In revision - The tour was once released but then recalled for a correction
- Revised - After "In revision" when recalculated/optimized
- In execution - Driver has started the released tour
- Completely finished - All transport points and shipments completed as planned
- Incompletely finished - Discrepancies between completed execution and dispatcher's planning
- Not started
- Paused - e.g. during driver's break or when the vehicle was preloaded the previous day and the tour is now waiting for further execution
- * (A) - This suffix means the tour was once in status "In execution" before switching to the new status
- * (P) - This suffix means the tour was once in status "Paused" before switching to the new status
A tour webhook is only sent when the status of the tour actually changes. If an action is repeated within the same status (e.g. further shipments are allocated to a tour that is already "Planning"), no further tour webhook is sent. Exception: if the "Shipment review" module is active, tour webhooks from the start of execution onwards (from status "In execution") are only sent once all shipments of the tour have been reviewed; the tour webhook is then sent with the current status of the tour, even without a status change, provided the webhook is configured for this status. Status changes in between are not sent retroactively. This restriction does not apply to shipment webhooks.
JSON Schema for received webhooks
{
"title": "WebhookShipmentDto",
"type": "object",
"properties": {
"id": { "type": "integer" },
"groupId": { "type": "integer" },
"refId": { "type": ["string", "null"] },
"source": { "type": ["string", "null"] },
"salesmanCode": { "type": ["string", "null"] },
"orderNumber": { "type": ["string", "null"] },
"note": { "type": ["string", "null"] },
"timeStamp": { "type": "string", "format": "date-time" },
"status": { "type": ["string", "null"] },
"fiscalStatus": { "type": ["string", "null"] },
"shipmentType": { "type": ["string", "null"] },
"customField1": { "type": ["string", "null"] },
"customField2": { "type": ["string", "null"] },
"customField3": { "type": ["string", "null"] },
"customField4": { "type": ["string", "null"] },
"customField5": { "type": ["string", "null"] },
"customField6": { "type": ["string", "null"] },
"customField7": { "type": ["string", "null"] },
"customField8": { "type": ["string", "null"] },
"customField9": { "type": ["string", "null"] },
"customField10": { "type": ["string", "null"] },
"precombinedTourNumber": { "type": ["string", "null"] },
"extSortOrderA": { "type": ["integer", "null"] },
"extSortOrderB": { "type": ["integer", "null"] },
"calculatedSortOrderA": { "type": ["integer", "null"] },
"calculatedSortOrderB": { "type": ["integer", "null"] },
"transportPoints": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookTransportPointDto" }
},
"shipmentReports": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookShipmentReportDto" }
},
"parentShipmentReports": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookShipmentReportDto" },
"description": "Reports stored on the split parent shipment (e.g. the parent delivery note); empty for shipments without a split parent"
},
"splitParentId": { "type": ["integer", "null"] },
"parentShipmentType": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/ShipmentTypeEnum" }
]
},
"splits": { "type": ["integer", "null"] },
"splitSortOrder": { "type": ["integer", "null"] },
"pickupLocationRefId": { "type": ["string", "null"] },
"dropoffLocationRefId": { "type": ["string", "null"] },
"isReadyForCommissioning": { "type": "boolean" }
},
"$defs": {
"WebhookTransportPointDto": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"dropoffStop": { "type": "boolean" },
"sortOrder": { "type": "integer" },
"precombinedTourNumber": { "type": ["string", "null"] },
"scheduledArrival": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"scheduledDeparture": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"startActual": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"endActual": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"images": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookTransportPointImageDto" }
},
"status": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/StopStatusEnum" }
]
},
"driverTasks": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookDriverTaskDto" }
}
}
},
"WebhookTransportPointImageDto": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"transportPointId": { "type": "integer" },
"url": { "type": ["string", "null"] },
"lat": { "type": ["number", "null"] },
"lng": { "type": ["number", "null"] }
}
},
"WebhookShipmentReportDto": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"reportId": { "type": ["integer", "null"] },
"reportUrl": { "type": ["string", "null"] },
"timeStamp": { "type": ["string", "null"], "format": "date-time" },
"reportType": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/ReportTypeEnum" }
]
}
}
},
"WebhookDriverTaskDto": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"type": { "$ref": "#/$defs/DriverTaskType" },
"status": { "$ref": "#/$defs/DriverTaskStatusEnum" },
"barCode": { "type": ["string", "null"] },
"scannerLat": { "type": ["number", "null"] },
"scannerLng": { "type": ["number", "null"] },
"quantityRequired": { "type": ["number", "null"] },
"quantityActual": { "type": ["number", "null"] },
"quantityEdited": { "type": ["number", "null"] }
}
},
"ShipmentTypeEnum": {
"type": "integer",
"enum": [0, 1, 2, 3, 4],
"description": "0 = InitialLeg, 1 = MainLeg, 2 = FinalLeg, 3 = Direct, 4 = Undefined"
},
"StopStatusEnum": {
"type": "integer",
"enum": [0, 1, 2, 3, 9, 10, 11],
"description": "0 = NotStarted, 1 = Success, 2 = Fail, 3 = Warning, 9 = InProgress, 10 = WaitingAfterArrival, 11 = WaitingBeforeDeparture"
},
"DriverTaskType": {
"type": "integer",
"enum": [1, 2, 3],
"description": "1 = Pickup, 2 = Dropoff, 3 = Flushing"
},
"DriverTaskStatusEnum": {
"type": "integer",
"enum": [0, 1, 2, 3],
"description": "0 = NotStarted, 1 = Completed, 2 = Failed, 3 = InProgress"
},
"ReportTypeEnum": {
"type": "integer",
"enum": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],
"description": "0=EmptyReport, 1=TourListReport, 2=DeliveryNoteReport, 3=SpecialEventReport, 4=SimulationManipulationReport, 5=ShipmentViewReport, 6=PoiDocumentReport, 7=ContainerLabelReport, 8=KpiTourReport, 9=KpiVehicleReport, 10=KpiDriverReport, 11=KpiQualityReport, 12=TradingOffersReport, 13=TradingDemandsReport, 14=KpiResourcePlanningReport, 15=KpiPositionReport, 16=KpiGroupReport, 17=PickupNoteReport, 18=KpiTsg, 19=KpiExamGroupReport, 21=BarcodeHistory, 26=TourListActualArrivalsReport, 27=TransportPointReport, 28=ShipmentListReport, 29=WeeklyPrecombinedTourReport, 30=InvoicingOrderReport, 31=InvoicingPositionsReport, 32=TourDriverTaskReport, 33=RecurringOrdersReport, 34=WaySplitReport, 35=ScaleNoteReport, 36=PickupQuantityReport, 37=FlushingReport, 38=ProposalReport, 39=LoadUnitReport, 40=ParentShipmentReport"
}
}
}
{
"title": "WebhookTourDto",
"type": "object",
"properties": {
"id": { "type": "integer" },
"groupId": { "type": ["integer", "null"] },
"refId": { "type": ["string", "null"] },
"name": { "type": ["string", "null"] },
"note": { "type": ["string", "null"] },
"version": { "type": ["string", "null"] },
"timeStamp": { "type": ["string", "null"], "format": "date-time" },
"tourStatus": { "type": ["string", "null"] },
"vehicleId": { "type": ["integer", "null"] },
"vehicleRefId": { "type": ["string", "null"] },
"vehicleTSGRefId": { "type": ["string", "null"] },
"trailerid": { "type": ["integer", "null"] },
"trailerRefId": { "type": ["string", "null"] },
"trailerTSGRefId": { "type": ["string", "null"] },
"driverId": { "type": ["integer", "null"] },
"driverRefId": { "type": ["string", "null"] },
"customField1": { "type": ["string", "null"] },
"customField2": { "type": ["string", "null"] },
"customField3": { "type": ["string", "null"] },
"customField4": { "type": ["string", "null"] },
"customField5": { "type": ["string", "null"] },
"customField6": { "type": ["string", "null"] },
"date": { "type": ["string", "null"], "format": "date", "description": "LOCAL time, serialized as date-only via WebhookDateConverter" },
"tillDate": { "type": ["string", "null"], "format": "date", "description": "LOCAL time, serialized as date-only via WebhookDateConverter" },
"fixStartTime": { "type": ["string", "null"], "pattern": "^-?\\d+\\.?\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?$", "description": "TimeSpan serialized as string (e.g. '08:30:00')" },
"scheduledStart": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"scheduledEnd": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"start": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"end": { "type": ["string", "null"], "format": "date-time", "description": "UTC time" },
"distance": { "type": ["integer", "null"] },
"actualDistance": { "type": ["integer", "null"] },
"plannedDrivingTime": { "type": ["integer", "null"] },
"actualDrivingTime": { "type": ["integer", "null"] },
"plannedTourTime": { "type": ["integer", "null"] },
"actualTourTime": { "type": ["integer", "null"] },
"precombinedTourNumber": { "type": ["string", "null"] },
"shipments": {
"type": ["array", "null"],
"items": { "$ref": "#/$defs/WebhookShipmentDto" }
}
}
}
Network & Security
Protocol and Port
Webhooks are sent exclusively via HTTPS on port 443. The webhook URL must always start with https:// in the x4fleet configuration. An HTTP redirect on the recipient side is possible, but it is recommended to configure the URL with https:// directly.
Source IP Addresses
Webhooks are sent from the x4fleet API infrastructure (Azure App Service). Outbound IP addresses are managed by Azure and may change when infrastructure changes occur. Production and staging/testing run on separate Azure environments with different outbound IP addresses. The current IP addresses can be requested from x4fleet support.
Note: gateway.x4fleet.com and gateway-staging.x4fleet.com are the incoming API endpoints for x4fleet clients — not the source of outgoing webhooks. These DNS names are therefore not suitable for firewall rules on the recipient side.
Security Recommendations
IP whitelisting is technically possible but not recommended, as Azure outbound IPs are not exclusive and can change. X4fleet supports the following cryptographically secured authentication methods that work independently of IP addresses:
- Basic Auth — Username and password in the
Authorizationheader - Client certificate (mTLS) — x509 certificate via Azure Key Vault