Notification hooks are used to push events from DFDS Logistics to external systems. The implementation is based on the concept of WebHooks. In this section you will find detailed documentation for our notification hooks api.
This API feature requires the 'Notifications' feature access. Please contract your DFDS representative if you need access to this API.
To receive push notifications, you need to subscribe to a specific event type. Such a subscription is known as a Notification Hook
Use a service account! It is highly recommended that notification hooks are registered using a Service Account. Detected issues and other information about the notification hook is sent to the email associated with the account which has registered the notification hook.
When registering a notification, the receiving service must be alive and able to respond. Each step of the process is detailed below.
A notification hook is registered by posting to the following api endpoint.
POST https://logisticsapi.dfds.com/api/notification
Name | Description | Type |
event | The event type this notification will trigger on. Example: BookingTracking and Instruction. | string |
notificationUrl | The url, triggered notification are posted to. (url endpoint you provide) | url |
deliveryFormat | The content type used when posting notification triggered by this notification. | string |
requireValidSSL | Specifies whether the SSL/TLS certificate on the notification url should be validated when posting notifications. It is strongly recommended to disable this only in testing scenarios. | boolean |
secret | The secret key used when signing outgoing notifications. | string |
When a notification hook is registered, a challenge is sent to the provided notification delivery endpoint.
POST
X-NotificationEndpointChallenge
[nonce]
The request will contain a single plain text nonce in the body. The endpoint must return a HMAC-SHA256 hash, using the provided secret, of the nonce also in the body of the response
HTTP/1.1 400 Bad Request
Missing registration data
HTTP/1.1 400 Bad Request
Delivery format must be specified. Example: application/json.
HTTP/1.1 400 Bad Request
A secret must be specified for your notification hook. This secret is used to sign notifications so you can prevent notificatinos from unauthorized sources.
HTTP/1.1 400 Bad Request
Notification url must be specified. Notifications will be delivered to this url.
HTTP/1.1 400 Bad Request
You have specified that SSL must be validated when delivering notifications, but the provided notification url is not https.
HTTP/1.1 400 Bad Request
An event type must be specified. Possible values are: {eventTypes}.
HTTP/1.1 400 Bad Request
Event type '{eventType}' is not supported. Please specify one of the following event types: {eventTypes}.
HTTP/1.1 400 Bad Request
The event type '{eventType}' does not support a delivery format of {deliveryFormat}. Supported delivery formats are: XX
HTTP/1.1 400 Bad Request
The notification endpoint did not respond within 10 seconds.
HTTP/1.1 400 Bad Request
Error cummunicating with remote endpoint
HTTP/1.1 400 Bad Request
The hashcode challenge is incorrect
HTTP/1.1 400 Bad Request
Received a non-success status code from notification endpoint
Notifications are delivered by posting to the url endpoint you provided when registering the notification hook. The notification data is included in the body as specified by the notification event type. Information specific to the notification hook is included in the request headers.
Notification posts are signed using HMAC-SHA256. You should verify the signature of received notifications to authenticate the source of the information. The secret used to sign notifications is configured when registering a notification hook. The signature is provided as a header value when posting the notification:
X-Signature: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
X-SignatureAlgorithm: HMAC-SHA256
Additionally, a notification delivery contains headers identifying the triggering notification hook and a unique id for the delivery.
User-Agent: Velocity/2.5.7.1
X-NotificationHookId: 314
X-NotificationDeliveryId: 256134
X-NotificationDeliveryTryId: 5487965
The notification signature can be validated using the following sample code
using System.Text;
using System.Security.Cryptography;
public static async Task<bool> ValidateSignatureAsync(HttpResponseMessage message, string secret)
{
using (var algorithm = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
{
var content = await message.Content.ReadAsStringAsync();
var byteContent = Encoding.UTF8.GetBytes(content);
var calculatedSignature = algorithm.ComputeHash(byteContent);
IEnumerable<string> signatureResults;
message.Headers.TryGetValues("X-Signature", out signatureResults);
var providedSignature = Convert.FromBase64String(signatureResults.FirstOrDefault());
return calculatedSignature.SequenceEqual(providedSignature);
}
}
require 'openssl'
require 'base64'
secret = "secret"
challenge = "challenge"
signature = OpenSSL::HMAC.digest('sha256', secret, challenge)
encodedSignature = Base64.urlsafe_encode64(signature)
We will retry notification delivery if the notification endpoint fails. A delivery is considered delivered when a 200-range HTTP status code is returned within 10 seconds.
The request will contain a single plain text nonce. The endpoint must return a HMAC-SHA256 hash, using the provided secret, of the nonce within
The hash should be returned as a base64 encoded string.
If successfull delivery is still not possible, we will mark the delivery as failed.
You can use the auditing and debugging api's to investigate the problem.
Deliveries are retried according to the following approximate wait times (ie. time waited after the previous delivery attempt)
If notification delivery repeatedly fails, your notification hook may be suspended. Information about notification hook suspension is sent to the email associated with the account which registered the notification hook. You may intentionally want to suspend a subscription hook. This can be done by posting to the following endpoint:
Additionally, you may register a notification hook for the event Notification Hook Suspension. Notifications will be posted here when any notification hook changes suspension state.
POST https://logisticsapi.dfds.com/api/notification/{hookId}/suspend
Likewise, a subsciption may be resumed by posting to the following endpoint
POST https://logisticsapi.dfds.com/api/notification/{hookId}/resume
The API supports managing registered notification hooks.
GET https://logisticsapi.dfds.com/api/notification?page={page}
The result is paged with max 20 items pr page. Use the response header 'X-HasMoreItems' to determine whether additional pages are available. Pages are indexed starting at 1. The page number to retrieve. If no page page is specified, the first page is returned.
X-HasMoreItems: True
HTTP Status 400 if the provided page is less than 1.
HTTP/1.1 400 Bad Request
The page numbering starts a '1', but you specified 0. Please try again using a page number of 1 or larger
GET https://logisticsapi.dfds.com/api/notification/{hookId}
Name | Description | Type |
createdDate | The date and time this notification hook was registered in UTC. | date |
lastUpdatedDate | The date and time of the last modification to this notification callback in UTC. | date |
id | Identifier uniquely identifying the registered notification hook. | number |
state | The current state of the notification hook. Ex "Normal", "Warning" or "Suspended". | string |
event | The event type this notification will trigger on. Please refer to Notification Hook Events for documentation on available types. | string |
notificationUrl | The url triggered notification are posted to. | url |
deliveryFormat | The content type used when posting notification triggered by this notification. | string |
requireValidSSL | Specifies whether the SSL/TLS certificate on the notification url should be validated when posting notifications. It is strongly recommended to disable this only in testing scenarios. | boolean |
secret | The secret key used when signing outgoing notifications. | string |
{
"$id": "1",
"createdDate": "2017-12-02T12:21:09",
"lastUpdatedDate": "2017-12-03T17:37:41",
"id": 10231,
"event": "TrackingUpdated",
"notificationUrl": "https://company.com/events/trackingUpdate",
"deliveryFormat": "application/json",
"requireValidSSL": true,
"secret": "WUPuBhdEdw6Pn92fAKAcrFRv"
}
An existing notification hook may be updated with new parameters. The event type cannot be changed. If you need to change the event type, delete the notification hook and create a new one instead.
If the endpoint is updated, a challenge will be sent to the new endpoint similar to the challenge sent when registering a new notification hook. See the registration challenge section for details.
POST https://logisticsapi.dfds.com/api/notification/{hookId}
Name | Description | Type |
eventType | The event type this notification will trigger on. Please refer to Notification Hook Events for documentation on available types. | string |
notificationUrl | The url triggered notification are posted to. | url |
deliveryFormat | The content type used when posting notification triggered by this notification. | string |
requireValidSSL | Specifies whether the SSL/TLS certificate on the notification url should be validated when posting notifications. It is strongly recommended to disable this only in testing scenarios. | boolean |
secret | The secret key used when signing outgoing notifications. | string |
{
"event": "TrackingUpdated",
"notificationUrl": "https://company.com/events/trackingUpdate",
"deliveryFormat": "application/json",
"requireValidSSL": true,
"secret": "WUPuBhdEdw6Pn92fAKAcrFRv"
}
HTTP/1.1 404 Not Found
Changing event type of a registered notification hook is not supported. Please delete this notification hook and create a new one instead.
DELETE https://logisticsapi.dfds.com/api/notification/{hookId}
These api's are intended to help with development and diagnosing production problems.
A list of deliveries can be listed for a specific notification hook within a time range. The startDate and endDate parameters are in UTC time. The result is paged with max 20 items pr page. Use the response header 'X-HasMoreItems' to determine whether additional pages are available. Pages are indexed starting at 1.
GET https://logisticsapi.dfds.com/api/notification/{hookId}/delivery?startDate={startDate}&endDate={endDate}&page={page}
The response is a list of Deliveries.
{
"id": 1231123,
"eventTriggerTime": "2017-12-05T07:51:02",
"status": "Completed",
"tries": [
{
"$id": "2",
"time": "2017-12-05T07:51:17",
"isSuccess": true,
"id": "8762315"
}
]
}
HTTP/1.1 404 Not Found
Could not find a registered notification hook with id '324'
HTTP/1.1 400 Bad Request
The provided end date must be greater than the provided start date. You provided Start {startDate}, End: {endDate}
HTTP/1.1 400 Bad Request
The span between the start and end date must not be greter than 24 hours. You provided Start {startDate}, End: {endDate}, Span: {span}
Gets an audit log for notifications delivered on the specified hook. Use this to debug a notification setup.
GET https://logisticsapi.dfds.com/api/notification/{hookId}/delivery/{deliveryId}
Name | Description | Type |
id | The unique id for the delivery | number |
eventTriggerTime | The date and time the delivery was first tried in UTC | date |
status | The current status of the delivery. Eg "Completed", "PendingRetry" or "Failed" | string |
tries | A list of individual delivery tries | Array of DeliveryTry |
Each delivery try is defined with the following set of attributes
Name | Description | Type |
id | The unique id for the delivery try | number |
time | The date and time the delivery this try was started in UTC | date |
isSuccess | Indicates whether the delivery was successfull | boolean |
HTTP/1.1 404 Not Found
Could not find a registered notification hook with id '324'
HTTP/1.1 404 Not Found
Could not find a notification delivery with id '234901' for notification hook with id '324'
Gets detailed request and response information for a specific delivery try. Use this to debug an issue with a registered notification hook. This information is available up to 14 days after the delivery try.
GET https://logisticsapi.dfds.com/api/notification/{hookId}/delivery/{deliveryId}/tries/{tryId}/details
The details of an individual delivery try include the following set of attributes
Name | Description | Type |
httpStatus | The HTTP status code | number |
requestBody | The full body of the request | string |
responseBody | The full body of the response | string |
requestHeaders | The headers included with the request | string |
responseHeaders | The headers included with the response | string |
HTTP/1.1 404 Not Found
Could not find a registered notification hook with id '324'
HTTP/1.1 404 Not Found
Could not find a notification delivery with id '234901' for notification hook with id '324'
HTTP/1.1 404 Not Found
Could not find a notification delivery try with id '1231' for delivery id '234901' for notification hook with id '324'
Triggers resubmission of a previous notification delivery. This functionary is available up to 14 days after a notification delivery has either failed or completed. The notification will be delivered to the currently registered endpoint of the notification hook.
POST https://logisticsapi.dfds.com/api/notification/{hookId}/delivery/{deliveryId}/resend
HTTP/1.1 404 Not Found
Could not find a registered notification hook with id '324'
HTTP/1.1 404 Not Found
Could not find a notification delivery with id '234901' for notification hook with id '324'
This section lists different types of events that can be subscribed to.
These events are triggered when a booking operation state changes according to Booking Flow. The event names are as follows: Booking Received, Booking Approved, Booking Rejected, Booking Cancelled, Booking Withdrawn.
For details on booking flow and event message contents, see Booking Flow.
This event is triggered when the Actual Time of Arrival changes on a Collection Location on a Booking.
Property | Description | Type |
eventType | The name of the event | string |
bookingExternalId | Customer-defined booking identifier provided as the 'ExternalId' when the Booking was created | string |
locationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the collection location when the Booking was created | string |
bookingId | Booking numeric identifier assigned by DFDS | number |
trackingTime | The Actual Time of Arrival on the collection location in the timezone of that location. | date |
equipmentNumber | Identifies the Trailer used for the collection | string |
truckNumber | Identifies the Truck used for the collection | string |
Example of a Booking Collection ATA Changed event.
{
"$id": "1",
"eventType": "Booking Collection ATA Changed",
"bookingExternalId": "B24266084965",
"locationExternalId": "4020",
"bookingId": 14287212,
"trackingTime": "2024-11-07T07:08:00",
"equipmentNumber": "BM7686",
"truckNumber": "M15003"
}
This event is triggered when the Actual Time of Departure changes on a Collection Location on a Booking.
Property | Description | Type |
eventType | The name of the event | string |
bookingExternalId | Customer-defined booking identifier provided as the 'ExternalId' when the Booking was created | string |
locationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the collection location when the Booking was created | string |
bookingId | Booking numeric identifier assigned by DFDS | number |
trackingTime | The Actual Time of Departure on the collection location in the timezone of that location. | date |
equipmentNumber | Identifies the Trailer used for the collection | string |
truckNumber | Identifies the Truck used for the collection | string |
Example of a Booking Collection ATD Changed event.
{
"$id": "1",
"eventType": "Booking Collection ATD Changed",
"bookingExternalId": "B24266084965",
"locationExternalId": "4020",
"bookingId": 14287212,
"trackingTime": "2024-11-07T07:08:00",
"equipmentNumber": "BM7686",
"truckNumber": "M15003"
}
This event is triggered when the Actual Time of Arrival changes on a Delivery Location on a Booking.
Property | Description | Type |
eventType | The name of the event | string |
bookingExternalId | Customer-defined booking identifier provided as the 'ExternalId' when the Booking was created | string |
locationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the delivery location when the Booking was created | string |
bookingId | Booking numeric identifier assigned by DFDS | number |
trackingTime | The Actual Time of Arrival on the delivery location in the timezone of that location. | date |
equipmentNumber | Identifies the Trailer used for the delivery | string |
truckNumber | Identifies the Truck used for the delivery | string |
Example of a Booking Delivery ATA Changed event.
{
"$id": "1",
"eventType": "Booking Delivery ATA Changed",
"bookingExternalId": "B24266084965",
"locationExternalId": "4020",
"bookingId": 14287212,
"trackingTime": "2024-11-07T07:08:00",
"equipmentNumber": "BM7686",
"truckNumber": "M15003"
}
This event is triggered when the Actual Time of Departure changes on a Delivery Location on a Booking.
Property | Description | Type |
eventType | The name of the event | string |
bookingExternalId | Customer-defined booking identifier provided as the 'ExternalId' when the Booking was created | string |
locationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the delivery location when the Booking was created | string |
bookingId | Booking numeric identifier assigned by DFDS | number |
trackingTime | The Actual Time of Departure on the delivery location in the timezone of that location. | date |
equipmentNumber | Identifies the Trailer used for the delivery | string |
truckNumber | Identifies the Truck used for the delivery | string |
Example of a Booking Delivery ATD Changed event.
{
"$id": "1",
"eventType": "Booking Delivery ATD Changed",
"bookingExternalId": "B24266084965",
"locationExternalId": "4020",
"bookingId": 14287212,
"trackingTime": "2024-11-07T07:08:00",
"equipmentNumber": "BM7686",
"truckNumber": "M15003"
}
This event is triggered when the Equipment used for Collection or Delivery on any location changes.
Property | Description | Type |
eventType | The name of the event | string |
bookingExternalId | Customer-defined booking identifier provided as the 'ExternalId' when the Booking was created | string |
subBookings | A list of BookingEquipmentChangedSubBookings | BookingEquipmentChangedSubBooking |
A SubBooking contains Collection and Delivery details.
Property | Description | Type |
collectionLocationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the collection location when the Booking was created | string |
collectionEquipmentNumber | Identifies the Trailer used for the collection | string |
collectionTruckNumber | Identifies the Truck used for the collection | string |
deliveryLocationExternalId | Customer-defined location identifier provided as the 'ExternalId' on the delivery location when the Booking was created | string |
deliveryEquipmentNumber | Identifies the Trailer used for the delivery | string |
deliveryTruckNumber | Identifies the Truck used for the delivery | string |
Example of a Booking Actual Equipment No. Changed event.
{
"$id": "1",
"eventType": "Booking Actual Equipment No. Changed",
"BookingExternalId": "B24266084965",
"bookingId": 14287213,
"subBookings": [
{
"$id": "2",
"collectionLocationExternalId": "4020",
"collectionEquipmentNumber": "CF7732",
"collectionTruckNumber": "M15003",
"deliveryLocationExternalId": "1337",
"deliveryEquipmentNumber": "CF7732",
"deliveryTruckNumber": "M15003"
},
{
"$id": "3",
"collectionLocationExternalId": "133222",
"collectionEquipmentNumber": "CSO271",
"collectionTruckNumber": "ETX581",
"deliveryLocationExternalId": "133",
"deliveryEquipmentNumber": "H358",
"deliveryTruckNumber": "ETX581"
}
]
}
This event is triggered when the last known position of a subboking changes. See Booking Tracking for more details.