Need Support? phone 1300 803 873 or email [email protected]

Webhooks Integration Guide

Receive event notifications with webhooks

Listen for events on your Inbound account so your 3rd party system can automatically process events that occur in Inbound.

Inbound uses webhooks to notify your application when an event happens in your account. Webhooks will post data to your external system using HTTP whenever a particular event occurs in the Inbound system.

Begin using webhooks with Inbound in just three steps:
  1. Ensure webhooks are available in your account, contact [email protected] to request it to be enabled.
  2. Navigate to Administration -> Webhooks -> Webhook subscriptions
  3. Create your subscription to the events you are interested in

Action in Inbound which generate webhook events

This event is triggered whenever a booking is created, updated or cancelled for your account (for a facility this is any booking to your facility, for a transporter this is any booking made under your account). The event will include all details about the booking, excluding the actual attachments. Retrieval of attachments is coming soon.
Field Description Comments
id Unique ID for this event.
event Name of the event that generated this message. App.BookingCreatedOrUpdated always for this event type.
attempt Number of attempts it took to call your webhook endpoint.
data.bookingNumber Booking number for this booking.
data.facility Name of the facility this booking was for.
data.service The name of the service at this facility this booking was for.
data.bookingDate Date the booking was made for. Format will be yyyy-mm-dd.
data.startTimeWindow The start time of the timeslot the booking was made for. Format will be hh:mm (24 hour time).
data.endTimeWindow The end time of the timeslot the booking was made for. Format will be hh:mm (24 hour time).
data.status The current status of the booking. Will be one of “Open”, “Completed”, “CancelledByFacility”, “CancelledByTransporter”, “CancelledBySystem”.
data.transporter Name of the transport company who made this booking.
data.guestName Name of the guest user who made the booking. If a booking is made by a one-off user then they are required to provide their name. (N/A to transporter subscriptions)
data.guestEmail Email of the guest user who made the booking. If a booking is made by a one-off user then they are required to provide their email. (N/A to transporter subscriptions)
data.preProcessed Boolean value representing whether the booking has been pre-processed or not. (N/A to transporter subscriptions)
data.cancellationReason Reason the booking was cancelled. Bookings cancelled by system, facility or user can have a reason provided.
data.baseAmount Pre tax amount charged for this booking.
data.taxAmount Tax amount calculated for this booking.
data.totalIncludingTax Total amount paid for this booking including any taxes.
data.eBookingExternalReferenceId If this booking was created from an e-booking. This will be the external reference Id. If provided. (N/A to facility subscriptions)
data.fields Array of Field/Value pairs representing the field data made with this booking. Each service can have a different set of fields that are either mandatory or optional. Contact Inbound for the field names relevant to your setup.
data.attachments Array of objects about the attachments attached to a booking. The object in this array will have a fileName, attachmentType (optional), and url. The url will be a time limited secure download URL from where you can retrieve the actual attachment.

Example

{
	"id": "9fb10566-3fbd-4149-a6c5-5c24b7d1381f",
	"event": "App.BookingCreatedOrUpdated",
	"attempt": 2,
	"data": {
		"bookingNumber": "INBFAC2107161",
		"facility": "Inbound Facility",
		"service": "FAK Import Pickup",
		"bookingDate": "2021-07-16",
		"startTimeWindow": "09:00",
		"endTimeWindow": "09:59",
		"status": "CancelledBySystem",
		"transporter": "Inbound Transporter",
		"guestName": null,
		"guestEmail": null,
		"PreProcessed": null,
		"cancellationReason": "Booking automatically cancelled by Inbound – no show",
        "baseAmount": 15.00,
        "taxAmount": 1.5,
        "totalIncludingTax": 16.50,
		"fields": [
			{
				"field": "Vehicle Rego",
				"value": "VEH123"
			},
			{
				"field": "Container No.",
				"value": "MSKU1234565"
			},
			{
				"field": "AIMS Number",
				"value": ""
			},
			{
				"field": "House BL",
				"value": "HOUSEBL12345"
			},
			{
				"field": "Special Instructions",
				"value": ""
			},
			{
				"field": "UOM",
				"value": ""
			},
			{
				"field": "Vessel",
				"value": ""
			},
			{
				"field": "No. of Units",
				"value": ""
			}
		],
        "attachments": [
            {
                "fileName": "Test File 1.pdf",
                "url": "https://securedownload.blob.core.windows.net/inbound-attachments/aaaaaaaa-bbbb-cccc-eeee-ffffffff_Test_File_1.pdf?sv=xxxxxx"
            },
            {
                "fileName": "Test File 2.docx",
                "attachmentType": "Delivery order",
                "url": "https://securedownload.blob.core.windows.net/inbound-attachments/11111111-2222-3333-4444-55555555_Test_File_2.docx?sv=xxxxxx"
            }
        ]
	},
	"creationTimeUtc": "2021-07-17T13:06:44.2650968Z"
}
                                        
This event is triggered whenever a draft booking is created or updated for your company.
Field Description Comments
id Unique ID for this event.
event Name of the event that generated this message. App.DraftBookingCreatedOrUpdated always for this event type.
attempt Number of attempts it took to call your webhook endpoint.
creationTimeUtc Date time of the message creation. In coordinated universal time (UTC)
data An array of draft bookings with status Comprised with the draft booking request and the result for each request
data[].transporterCode The transporter code that was part of the request
data[].transporterName Name of the transporter If the requested transporterCode resolved
data[].error Boolean value representing whether any error has occurred or not True or False, see the errorDetails or status of the bookingDetails for details when the value is ‘False’
data[].errorDetails List of validation errors, if the value of error is true
data[].bookingDetails[] Details of the transporter
data[].bookingDetails[].externalReferenceId Unique identification that was part of the request
data[].bookingDetails[].estimatedBookingDate Estimated booking date that was part of the request
data[].bookingDetails[].error Boolean value representing whether any error has occurred or not True or False, see the errorDetails for details when the value is ‘False’
data[].bookingDetails[].errorDetails List of validation errors, if the value of error is true
data[].bookingDetails[].action State the action it performed ‘Updated’ if it finds a matching record with the given externalReferenceId, otherwise ‘Created’
data[].bookingDetails[].facilityCode The facility code that was part of the request
data[].bookingDetails[].facilityName Name of the facility If the requested facilityCode was resolved
data[].bookingDetails[].facilityServiceCode The facility service code that was part of the request
data[].bookingDetails[].facilityServiceName Name of the facility service If the requested facilityServiceCode was resolved
data[].bookingDetails[].fields List of fields that were part of the request
data[].bookingDetails[].fields[].name Name of the field
data[].bookingDetails[].fields[].value Value of the field

Example

{
	"id": "3699a8be-c423-4eb5-9ceb-64cffb0e54b1",
	"event": "App.DraftBookingCreatedOrUpdated",
	"attempt": 2,
	"data": [
		{
			"transporterCode": "InboundTransporter",
			"transporterName": "Inbound Transporter",
			"error": false,
			"errorDetails": [],
			"bookingDetails": [
				{
					"facilityCode": "INBFAC",
					"facilityName": "Inbound Facility",
					"facilityServiceName": "FAK Import Pickup",
					"facilityServiceCode": "FAKPICK",
					"externalReferenceId": "REF101",
					"error": false,
					"errorDetails": [],
                    "estimatedBookingDate": "2021-08-01T10:10:00+10:00",
					"action": "Updated",
					"fields": [
						{
							"name": "Your Ref",
							"value": "This is your reference"
						},
						{
							"name": "Vehicle Rego",
							"value": "REGO123"
						},
						{
							"name": "Container No.",
							"value": "MSDU8046775"
						},
						{
							"name": "House BL",
							"value": "TESTHOUSEBL"
						},
						{
							"name": "Special Instructions",
							"value": "Optional special instructions"
						},
						{
							"name": "Vessel",
							"value": "9307023 - OOCL DUBAI"
						}
					],
					"attachments": [
						{
							"fileTypeCode": "POP",
							"fileName": "Test01.pdf"
						},
						{
							"fileTypeCode": "POP",
							"fileName": "Test02.pdf"
						}
					]
				}
			]
		}
	]
}
                                        
This event is triggered whenever an additional charge is created or updated for your company.
Field Description Comments
id Unique ID for this event.
event Name of the event that generated this message. App.AdditionalChargeCreatedOrUpdated always for this event type.
attempt Number of attempts it took to call your webhook endpoint.
creationTimeUtc Date time of the message creation. In coordinated universal time (UTC)
data.additionalChargeId Unique ID assigned to this additional charge Integer value and won’t change once additional charge is created
data.facility Name of the facility this additional charge was for.
data.chargeCode Charge code. The charge code used for this additional charge.
data.chargeCodeDescription Charge code description.
data.fieldName Name of the field additional charge is linked to Additional charges can be linked either directly to a booking or through a particular field (usually HBL or similar). May not be specified if not linked to a field.
data.fieldValue When an additional charge is linked through a field such as HBL this is the value that it’s linked to (Eg: this is the actual HBL number).
data.bookingNumber The current booking number this additional charge is linked to. Can be empty if the booking the charge was originally linked to was cancelled by the charge was already paid.
data.facilityService The type of service that the booking linked to this additional charge was for.
data.bookingDate Date the booking was for. Format will be yyyy-mm-dd.
data.transporter Name of the transporter currently responsible for paying the additional charge. This is linked through the booking that was made by this transporter.
data.paid Boolean representing if this additional charge been paid True or False
data.paidDateTime Date and time when the additional charge was paid In coordinated universal time (UTC)
data.cancelled Boolean representing if this additional charge was cancelled True or False
data.cancellationReason User entered reason for why the additional charge was cancelled
data.baseAmount Pre-tax amount charged for this additional charge.
data.taxAmount Tax amount calculated for this additional charge.
data.totalIncludingTax Total amount applied to this additional charge including any taxes.
data.commission Total amount of commission (ex tax) applicable to this additional charge.

Example

{
    "id": "3699a8be-c423-4eb5-9ceb-64cffb0e54b1",
    "event": "App.AdditionalChargeCreatedOrUpdated",
    "attempt": 2,
    "data": [
        {
            "facility": "Inbound Facility",
            "chargeCode": "STORAGE",
            "chargeCodeDescription": "FAK Storage charges",
            "fieldName": "House BL.",
            "fieldValue": "HBL123456",
            "bookingNumber": "INBFAC20020101",
            "facilityService": "Pickup",
            "bookingDate": "2023-01-10",
            "transporter": "Inbound Transporter",
            "paid": true,
            "paidDateTime": "2023-01-13 23:23:57.089925",
            "cancelled": false,
            "cancellationReason": "",
            "baseAmount": 100,
            "taxAmount": 10,
            "totalIncludingTax": 110,
            "commission": 10,
        }
    ]
}
                                        

There are two approaches to ensuring security of the webhooks coming into your system.

  1. When creating your webhook subscription you have the option of providing a custom HTTP header that will be sent along with the request. You can provide your own custom Authentication/Authorization header with a unique secret key that your receiving system will validate is correct before processing the webhook. This is recommended for all webhook subscriptions and you must ensure your receiving system is a HTTPS endpoint to protect the security of your HTTP headers from evesdropping.
  2. In addition to the custom HTTP header, the system will provide an SHA256 hash of the body of your webhook to ensure it has not been tampered with after being sent by Inbound. The HTTP header will be called “abp-webhook-signature” and have a value similar to “sha256=05-93-50-D7-EE-8E-0C-16-B3-82-D3-D0-A6-5F-DA-8D-CD-43-D1-05-A6-57-F5-28-03-FD-78-AC-55-AB-8C-11”.

    Once you have created your webhook subscription, from within Inbound click “Details” next to the subscription to allow you to retrieve the secret key used to create the SHA hash. (Click View Webhook Secret)

This secret key should be used to generate an SHA256 hash of the body and compare it to the header received with the message. If the hashes do not match then the message may have been tampered with and should be ignored. Example C# code on how to compare the hashes can be found here: https://aspnetboilerplate.com/Pages/Documents/Webhook-System#check-signature

Share the Post: