Webhooks

Webhooks are available from version 3.3 of the Dataloy API


Webhooks

Webhooks are user-defined HTTP callbacks that receive events for the subscribed event types. Webhook notifications are asynchronous, the order is not guaranteed.

Events are categorised into event types. Events occur due to changes in the state of a resource, such as when a voyage is updated. When an event occurs, the registered applications are notified via HTTP POST. The POST contains the event details, including the event type that triggered the event. 

When an application receives the event, it must respond with a 200-level HTTP status code.

Subscription

When a webhook subscription is made for a Dataloy object, BunkerOrder for instance, the subscribed webhook will be pushed with all the changes that occurred to the subscribed object and its object hierarchy. So if a PortCall of the subscribed BunkerOrder is updated the webhook will be notified.

The Remarks are not part of the webhook process. It is not possible to get notifications of changes in Remarks.


The Dataloy webhook event type is a concatenation of the following attributes:

  • Resource name (Document, Voyage, ..)

  • Operation type (C,U, D create, update, delete)

  • Object key


The user can subscribe to a webhook for a given event, for example:

Cargo.CNotifies when a Cargo is created
Document.DNotifies when a Document is deleted.
Voyage.UNotifies when a Voyage is updated.
Voyage.U.793628Will notify when voyage, having voyage.key = 793628, is updated.



Automatic Deactivation of subscription

If the subscribing system is unavailable or takes too long to respond, the server will deactivate the subscription after attempting 5 times (once a minute). The number of attempts and the interval between each attempt can be configured.

Deactivated subscriptions cannot be reactivated, a new subscription must be created if needed. 

Email alert when a subscription is de-activated: Add the desired email address (e.g. to the IT ops team) to the API user (in User Administration) to receive an email notification if a subscription is de-activated.

From, version 6.10, there is a possibility for the users to choose not to deactivate the subscription even after the max failed attempts.This is made possible through the checkbox "Do Not Unsubscribe" when creating a webhook subscription on VMS. Ticking the checkbox means that the subscription will not be unsubscribed and deactivated automatically after the max failed attempts. If using API endpoint to create/update subscription, the input curl should include the attribute and value as in

{

"doNotUnsubscribe": false/true

}


The message sent to the subscribed endpoint is set in the body of the POST method. The message is a JSON object and has the following structure:

{
 "id": "1573335-244070007",
 "eventTime": "2016-09-14T13:37:26",
 "objectType": "PortCall",
 "eventType": "U",
 "dataloyObject":189126972,
 "dataloyObjectSelf":"http://localhost:8080/ws/rest/PortCall/7823672"
 "subscription":{
            "key":243885046,
            "self":"http://localhost:8080/ws/rest/WebhookSubscription/243885046"
            "objectType":"BunkerOrder",
            "dataloyObject":244070007,
            "eventType": "U",
		     "url":"http://test1.dataloy.com:8080/webhook/"
   }
"resource":{  
      "key":244070007,
      "self":"http://localhost:8080/ws/rest/BunkerOrder/244070007",
      "vessel":{  
         "vesselName":"VESSEL1",
         "key":188616815,
         "self":"http://localhost:8080/ws/rest/Vessel/188616815"
      },
      "currency":{  
         "currencyCode":"USD",
         "currencyName":"U.S. DOLLAR",
         "key":400132,
         "self":"http://localhost:8080/ws/rest/Currency/400132"
      },
      "exchangeRate":3.0,
      "modifiedDate":"2016-09-21T06:38:29",
      "portCall":{  
         "key":189126972,
         "self":"http://localhost:8080/ws/rest/PortCall/189126972",
         "eventLogs":[  
            {  
               "key":189126978,
               "self":"http://localhost:8080/ws/rest/EventLog/189126978",
               "event":{  
                  "key":1000052,
                  "self":"http://localhost:8080/ws/rest/Event/1000052",
                  "eventCode":"DEP",
                  "eventDesc":"Departed"
               },
               "eventLogDate":"2015-02-13T17:18:00"
            },
            {  
               "key":189126974,
               "self":"http://localhost:8080/ws/rest/EventLog/189126974",
               "event":{  
                  "key":1000050,
                  "self":"http://localhost:8080/ws/rest/Event/1000050",
                  "eventCode":"ARR",
                  "eventDesc":"Arrived"
               },
               "eventLogDate":"2015-02-06T20:18:00"
            },
            {  
               "key":189126976,
               "self":"http://localhost:8080/ws/rest/EventLog/189126976",
               "event":{  
                  "key":1000051,
                  "self":"http://localhost:8080/ws/rest/Event/1000051",
                  "eventCode":"BRT",
                  "eventDesc":"Berthed"
               },
               "eventLogDate":"2015-02-07T10:06:00"
            }
         ]
      },
      "extraCost":0.0,
      "bunkeredDate":"2016-01-01T00:00:00",
      "orderDate":"2016-09-06T10:16:36",
      "bunkerPaidBy":null,
      "createdDate":"2016-09-21T06:12:42",
      "createdById":999999,
      "bunkerOrderStatus":{  
         "key":243093653,
         "self":"http://localhost:8080/ws/rest/StatusType/243093653",
         "statusTypeDesc":"Requirement",
         "statusTypeCode":"REQBO"
      },
      "externalReferenceNo":null,
      "bunkerOrderLines":[  
         {  
            "key":244070009,
            "self":"http://localhost:8080/ws/rest/BunkerOrderLine/244070009",
            "minQuantity":50.0,
            "maxQuantity":100.0,
            "extraCost":0.0,
            "bunkeredQuantity":111.0,
            "unitPrice":100.0,
            "bunkerType":{  
               "key":73564540,
               "self":"http://localhost:8080/ws/rest/BunkerType/73564540",
               "isoCode":null,
               "isoYear":null,
               "bunkerTypeCode":"FO",
               "bunkerTypeDesc":"FO",
               "sulphurPercent":null
            }
         }
      ],
      "company":null,
      "bunkerBroker":{  
         "businessPartnerName":"BUSINESS PARTNER 1",
         "businessPartnerSort":"BUSINESS PARTNER 1",
         "businessPartnerCode":"1111",
         "businessPartnerType":{  
            "businessPartnerType":"BS",
            "businessPartnerTypeDesc":"Bunker Supplier",
            "key":1000034,
            "self":"http://localhost:8080/ws/rest/BusinessPartnerType/1000034"
         },
         "key":39697371,
         "self":"http://localhost:8080/ws/rest/BusinessPartner/39697371"
      },
      "bunkerAccountOf":null,
      "bunkerSupplier":{  
         "businessPartnerName":"BUSINESS PARTNER 2",
         "businessPartnerSort":"BUSINESS PARTNER 2",
         "businessPartnerCode":"22222",
         "businessPartnerType":{  
            "businessPartnerType":"BS",
            "businessPartnerTypeDesc":"Bunker Supplier",
            "key":1000034,
            "self":"http://localhost:8080/ws/rest/BusinessPartnerType/1000034"
         },
         "key":39697206,
         "self":"http://localhost:8080/ws/rest/BusinessPartner/39697206"
      },
      "remarks":[  

      ]
   } 
}


The attributes have the following meaning:


id

Unique identifier of the notification

eventTime

The time when the event occurred

objectType

Name of the changed Dataloy object

dataloyObject

The primary key of the changed Dataloy object (it can be different from the subscribed object, it can be an object in the hierarchy of the subscribed object )

eventType

C for creation, U for update, D for deletion

dataloyObjectSelf

the Dataloy URL of the changed object

subscription

Subscription data:


key

The primary key of the subscription

objectType

Name of the subscribed Dataloy object

self

API URL for the webhook subscription

dataloyObject

The primary key of the subscribed Dataloy object

resourceThe JSON of the DataloyObject that the subscription refers to


New functionalities since version 3.9

With API 3.9 the following new functionalities have been introduced:

  • Possibility to be notified  of changes via email
  • Possibility to customize the JSON pushed as Adjust Number of Fields to be Returned from a Request
  • Possibility to filter  changes that have to be pushed via expressions
  • Possibility to filter  changes that have to be pushed via scripts

Notifications via email

To be notified via email in the WebhookSubscription must be specified the channelInfo property with channelType EMAIL and the URL with the email address:

 {
        "channelInfo": {
            "url": "info@dataloy.com",
            "channelType": "EMAIL"
        }
    }

channelType can be EMAIL or HTTP if HTTP is set the URL attribute must contain the endpoint where to push notifications.

Possibility to customize the JSON pushed

Through the attribute json of WebhookSubscription is possible to specify which attributes of the object must be pushed (see Adjust Number of Fields to be Returned from a Request). The value of json must be encoded with Base64.

For instance, if the subscription is for the object BunkerOrderLine a possible value for the json attribute could be:

{"extraCost":"*"}


that encoded will be 

"json": "ew0KCSJleHRyYUNvc3QiOiIqIg0KfQ=="


In this way the sub-object in the attribute resource  will be smaller:

{  
   "id":"245-320996749",
   "eventTime":"2018-01-30T10:42:11",
   "eventType":"U",
   "objectType":"BunkerOrderLine",
   "dataloyObject":320996749,
   "dataloyObjectSelf":"http://platform-dev.dataloy.com:80/ws/rest/BunkerOrderLine/320996749",
   "subscription":{  
      "key":332501529,
      "self":"http://platform-dev.dataloy.com:80/ws/rest/WebhookSubscription/332501529",
      "isSubscriptionActive":true,
      "user":{  
         "key":999999,
         "self":"http://platform-dev.dataloy.com:80/ws/rest/User/999999",
         "userCode":"DATALOY",
         "userName":"dataloy"
      },
      "objectType":null,
      "dataloyObject":null,
      "url":null,
      "dlpAlertScript":{  
         "key":318269643,
         "self":"http://platform-dev.dataloy.com:80/ws/rest/DlpAlertScript/318269643",
         "scriptCode":"BUP",
         "scriptName":"Bunkered Unit Price updated"
      },
      "eventType":null,
      "unsubscriptionDate":null,
      "channelInfo":{  
         "key":332501528,
         "self":"http://platform-dev.dataloy.com:80/ws/rest/ChannelInfo/332501528",
         "channelType":{  
            "key":311504704,
            "self":"http://platform-dev.dataloy.com:80/ws/rest/ChannelType/311504704",
            "channelTypeCode":"EMAIL"
         },
         "url":"ab@dataloy.com"
      }
   },
   "resource":{  
      "key":320996749,
      "self":"http://platform-dev.dataloy.com:80/ws/rest/BunkerOrderLine/320996749",
      "extraCost":0.0
   }
}


Possibility to filter  changes that have to be pushed via expressions

Through the attribute expression of WebhookSubscription is possible to write a Java expression against the object changed. At runtime If the expression return true the notification will be sent,  otherwise no.

For instance, if the subscription is done for the object BunkerOrderLine a possible expression could be:

dlpObject.getUnitPrice()!=null && ( dlpObject.getUnitPrice()>10 )

that for any changes at any BunkerOrderLine object will check if the unit price is not null and its value is between 10 and 100, if yes the notification will be sent. 

In the expression must be used the variable dlpObject to refer to the changed object, the object will contain the new values. If the expression needs to check also the previous values of the object, the variable oldDlpObject can be used.

For instance:

oldDlpObject.getExtraCost()!=null && dlpObject.getExtraCost()!=null && dlpObject.getExtraCost()> oldDlpObject.getExtraCost()

that will check if the new extra cost of a BunkerOrder is greater that the previous one.

If you want to be notified when an attribute change value from null to not null:

oldDlpObject.getReferenceNo() == null && dlpObject.getReferenceNo() != null


The old values cannot be used for all object, please contact Dataloy support.

Possibility to filter  changes that have to be pushed via scripts

Contact Dataloy to have info regarding scripts.

Raw and Postable notifications

It is possible to decide if a webhook subscription should only be notified with the raw object, without the envelope payload.  To achieve this behavior a new boolean attribute called rawObject in WebhookSubscription has been added, setting it to true the raw object will be sent.

It is possible to decide if a webhook subscription should only be notified with the postable object, without the envelope payload. and keys.  To achieve this behavior a new boolean attribute called postableObject in WebhookSubscription has been added, setting it to true the raw object will be sent.


New functionalities since version 3.16

In version 3.16 (and later) it is possible to decide if a webhook subscription should only be  notified on changes to the object subscribed. So for instance making a subscription for the Voyage object, the changes that will occur to linked objects, like PortCall, Cargo, etc, will be not notified. To achieve this behavior a new boolean attribute called onlyMainObject in WebhookSubscription has been added, setting it to true only the changes for the subscribed will be sent.

A new endpoint in WebhookSubscription POST:sendFailedNotifications has been added to resend manually the failed webhook notification.

New functionalities since version 5.24

A new attribute xsl has been added which allows you to store an XSL stylesheet to transform the subscribed object to XML. The value of the field must be encoded with Base64. This is part only of Enterprise API.




Supported Methods

GET /WebhookSubscription

Get a list of WebhookSubscription objects. Filter to avoid huge amounts of data (see Filtering documentation for examples).  

GET /WebhookSubscription/{key}

Get a single WebhookSubscription object.

Example GET Return Body 

{
  "key": 243907762,
  "self": "http://localhost:8080/ws/rest/WebhookSubscription/243907762",
  "isSubscriptionActive": true,
  "unsubscribed": false,
  "eventType": "U",
  "dataloyObject": 243896793,
  "createdDate": "2016-09-16T08:35:46",
  "modifiedDate": "2016-09-16T08:35:46",
  "createdById": 999999,
  "objectType": "BunkerOrder",
  "user": {
    "key": 999999,
    "self": "http://localhost:8080/ws/rest/User/999999",
    "userName": "dataloy",
    "userCode": "DATALOY"
  },
  "url": "http://test1.dataloy.com:8080/webhook/",
  "unsubscriptionDate": null,
  "webhookUsername": null,
  "webhookPassword": null,
  "remarks": []
}

since API 3.9:

{
    "key": 320298564,
    "self": "http://platform-dev.dataloy.com:80/ws/rest/WebhookSubscription/320298564",
    "isSubscriptionActive": true,
    "unsubscribed": false,
    "user": {
        "key": 999999,
        "self": "http://platform-dev.dataloy.com:80/ws/rest/User/999999",
        "userCode": "DATALOY",
        "userName": "dataloy"
    },
    "objectType": "BunkerOrder",
    "createdDate": "2018-01-11T10:53:14",
    "url": "http://platform-dev.dataloy.com/ws/rest/dataloy/sendJson",
    "modifiedDate": "2018-01-11T10:53:14",
    "createdById": 999999,
    "dataloyObject": null,
    "expression": null,
    "dlpAlertScript": null,
    "eventType": "U",
    "unsubscriptionDate": null,
    "scriptParameterValues": [],
    "useMsg": false,
    "json": "{}",
    "webhookPassword": "XXX",
    "webhookUsername": "dataloy",
    "channelInfo": null,
    "remarks": []
}


POST /WebhookSubscription

Create a new WebhookSubscription.

Examples

Create a subscription to get notifications when the BunkerOrder with primary key 243896793 is updated:

{
	"eventType":"U",
	"user":999999,
	"objectType":"BunkerOrder",
	"dataloyObject":243896793,
	"url":"http://test1.dataloy.com:8080/webhook/"
	
}


Create a subscription to get notifications when any BunkerOrder is updated:

{
	"eventType":"U",
	"user":999999,
	"objectType":"BunkerOrder",
	"url":"http://test1.dataloy.com:8080/webhook/"
	
}

 

Create a subscription to get notifications when a BunkerOrder is created: 

{
	"eventType":"C",
	"user":999999,
	"objectType":"BunkerOrder",
	"url":"http://test1.dataloy.com:8080/webhook/"
	
}


Create a subscription to get notifications when the BunkerOrder with primary key 243896793 is deleted: 

{
	"eventType":"D",
	"user":999999,
	"objectType":"BunkerOrder",
	"dataloyObject":243896793,
	"url":"http://test1.dataloy.com:8080/webhook/"
	
}


Create a subscription to get notifications when any BunkerOrder is deleted: 

{
	"eventType":"D",
	"user":999999,
	"objectType":"BunkerOrder",
	"url":"http://test1.dataloy.com:8080/webhook/"
	
}

Create a subscription to get notifications when any BunkerOrder is updated  via email, since API 3.9:

{
	"eventType":"U",
	"user":999999,
	"objectType":"BunkerOrder",
	"channelInfo":{  
		 "url": "info@dataloy.com",
         "channelType": "EMAIL"
	}
}

 

Create a subscription to get notifications only when a Voyage object is changed, since API 3.16:

 

{
	"eventType":"U",
	"user":999999,
	"objectType":"Voyage",
	"channelInfo":{  
		 "url": "info@dataloy.com",
         "channelType": "EMAIL"
	},
    "onlyMainObject": true
}

 



PUT /WebhookSubscription/{key}

Only the following attributes can be updated:

  • unsubscribed
  • url
  • webhookUsername
  • webhookPassword

Since API 3.9 is possible to change also these other attributes:

  • channelInfo
  • json
  • expression
  • dlpAlertScript
  • scriptParameterValues
  • useMsg


To unsubscribe a subscription the following JSON must be sent. It is not possible to update the subscription if it has been unsubscribed:

{
	"unsubscribed": true	
}


DELETE /WebhookSubscription/{key}

To delete a WebhookSubscription first it has to be unsubscribed. It is not possible to delete WebhookSubscription that got Webhook notifications, regardless that it has been unsubscribed or not.


Top

Back

Related Content

 Expand to see related content


Unknown macro: {dynamiccontentbylabel}