Webhooks
Table of Contents
- Managing webhook subscriptions
- Payload
- Retry policy
- Testing webhooks
- Actions
Super Dispatch uses webhooks to update an API client when various events (or actions) happen on the platform. An API client should subscribe to an action to receive updates and unsubscribe to stop it. All webhook requests are POST
requests with a JSON
payload. All endpoints, request and response details are available in the API reference: webhooks.
You can see the diagram that explains when a webhook event is triggered in the document Flows.
Managing webhook subscriptions
The list of available webhook actions can be retrieved using the specific API endpoint: Get the list of all webhook actions. Deprecated webhook actions aren’t returned.
The API client can subscribe to a webhook action by providing a callback URL (reference):
|
|
The response is a confirmation of the subscription:
|
|
After a successful subscription, Super Dispatch starts sending POST
requests to the provided callback URL when the webhook action happened (like order.picked_up
or order.archived
). For example, if the API client is subscribed to the order.created
webhook action, the API server sends a request whenever a new order is created on Shipper TMS: via the API or manually on the user interface.
The verification_token
field is utilized to confirm that webhook notifications received by API clients are sent by Super Dispatch.
You can unsubscribe from a webhook action (reference):
|
|
The list of current webhook subscriptions can be retrieved (reference):
|
|
Payload
The payload (request body) always contains these default fields:
Field | Type | Description |
---|---|---|
action | string | The action name like order.created . See the list below. |
action_date | string | The date and time when the action happened. |
error_message | string | The error message (is sent when a previous action is failed). |
The payload also contains the target object guid like order_guid
or offer_guid
.
Retry policy
The webhook request timeout is 10 seconds. The API client that is subscribed to a webhook action should return a 2xx
response in 60 seconds. Otherwise, the webhook request is failed with timeout. Furthermore, an HTTP response codes like 3xx
, 4xx
, and 5xx
fail the webhook request.
The retry policy is linear:
- interval: 60 seconds
- retry count: 5.
This means when the API received a failed response from the callback URL, it’ll send 5 requests with 60 seconds of interval until it gets a successfull response. It stops sending a request after 5th try.
Testing webhooks
We suggest to use webhook.site during the implementation process to test the delivery and payload of webhook requests.
Actions
The actions supported by the Shipper API are below.
ignored
actions
We also send .ignored
webhook actions when a carrier updates the order which status is already delivered on the Shipper TMS. These updates are ignored by default, but the corresponding events are sent to API clients to inform them that the carrier actually changed the order status.
Here’s a quick explanation:
- A load offer is sent to a carrier (
offer.sent
is sent) - The load offer is accepted by the carrier (
offer.accepted
is sent) - The corresponding order is manually marked as picked up on Shipper TMS (
order.manually_marked_as_picked_up
is sent) - The order is manually marked as delivered on Shipper TMS (
order.manually_marked_as_delivered
is sent) - Then the order is marked as picked up on Carrier TMS (
order.picked_up.ignored
is sent, only works for shipper->carrier flow)
It is done to avoid confusion and inconsistencies in order statuses. For instance, if order with an active offer is manually marked as picked up and then as delivered prior to the carrier making any actions, an API client receives order.manually_marked_as_picked_up
and order.manually_marked_as_delivered
. If we sent order.picked_up
after carrier picks up the order, it would confuse an API client to be informed about their delivered order being picked up again.
Order related actions
Action | Is sent when… |
---|---|
order.created | Order is created |
order.cancel | Order is canceled by shipper |
order.submitted_by_customer | Order is submitted to shipper by customer |
order.picked_up | Order is picked up |
order.picked_up.ignored | Order with active offer is manually marked as delivered, then it is picked up by the carrier |
order.delivered | Order is delivered |
order.delivered.ignored | Order with active offer is manually marked as delivered, then it is delivered by the carrier |
order.picked_up_bol | Triggered when pickup BOL becomes available |
order.delivered_bol | Triggered when delivery BOL becomes available |
order.paid | Shipper marks order paid to carrier |
order.unmark_as_paid | Shipper unmarks order as paid to carrier |
order.customer_paid | Order is marked as paid by customer |
order.invoiced | Order is invoiced by the carrier |
order.customer_invoiced | Order is invoiced to the customer |
order.archived | Order is archived |
order.marked_as_on_hold | Order is marked as on hold by shipper |
order.unmarked_as_on_hold | Order is unmarked as on hold by shipper |
order.unarchived | Order is unarchived |
order.posted_to_cd | Order is posted to Central Dispatch |
order.removed_from_cd | Order is removed (unposted) from Central Dispatch |
order.posted_to_slb | Order is posted to Super Loadboard (SLB) |
order.removed_from_slb | Order is removed (unposted) from SLB |
order.booked | Order is booked by a preferred carrier via SLB |
order.manually_marked_as_new | Order is manually marked as new |
order.manually_marked_as_pending | Order is manually marked as pending |
order.manually_marked_as_accepted | Shipper manually marks order as accepted |
order.manually_marked_as_invoiced | Shipper manually marks order as invoiced by carrier |
order.manually_unmarked_as_invoiced | Shipper manually unmarks order as invoiced by carrier |
order.manually_marked_as_picked_up | Order is manually marked as picked up |
order.manually_marked_as_delivered | Order is manually marked as delivered |
order.rolled_back_manual_status_change | Order status is manually rolled back |
order.removed | Order is removed |
order.restored | Order is restored |
The order payload has only one additional field:
Field name | Type | Description |
---|---|---|
order_guid | guid | GUID of the related order |
Samples:
order.created
is triggered when order is created.
|
|
order.picked_up_bol
webhook event is triggered only when pdf_bol_url
and online_bol_url
become available, which indicates that the pickup inspection synchronization is finished.
|
|
order.delivered_bol
webhook event is triggered only when pdf_bol_url
, online_bol_url
and pdf_delivery_receipt_url
become available, which indicates that the delivery inspection synchronization is finished.
|
|
order.submitted_by_customer
webhook event is triggered when customer submits order from the customer portal or via shipper-to-broker flow. This event has customer_counterparty_guid
that indicates which customer submitted the order:
|
|
Webhooks for order and vehicle revisions
General info
Webhooks for order and vehicle revisions allow getting notifications when an order or its vehicles are updated. Using these webhook events API users are able to fully synchronize data in their system with Shipper TMS. These events allow subscribing to any subset of field changes. For example, if you are interested only in price changes you can subscribe to the price field changes and get notified only when the order price is changed.
To subscribe order or vehicle changes use the following list of events:
order.created
- order is createdorder.modified
- order is updatedvehicle.created
- vehicle is createdvehicle.modified
- vehicle is updatedvehicle.deleted
- vehicle is deleted
The payload for subscribing to these events accepts audit_field_set
field. This field should contain the list of order or vehicle fields which values will be added to the webhook payload when it’s triggered.
The triggered webhook payload has the following shape:
|
|
The nested data
field’s shape is similar to the order’s (or vehicle’s) shape except instead of primitive value leaf fields contain old and new values like "field": { "old_value": <old price value>, "new_value": <new price value>}
. For order.created
and vehicle.created
events old_value
is always null
. For vehicle.deleted
event new_value
is always null
.
order.modified
andvehicle.modified
events are triggered only when one ofaudit_field_set
fields are changed.order.created
,vehicle.created
andvehicle.deleted
events are triggered even if theaudit_field_set
is empty.
Subscription example for order revisions
Here is the example of how to subscribe to order’s number
, price
, and pickup.venue.name
field changes:
|
|
When these fields are changed the following payload will be sent:
|
|
Other fields that also may have been changed with this update aren’t included in the payload.
Some order fields could be changed by a carrier. In such cases, the webhook payload will contain the carrier information who made these changes. For example:
|
|
Subscription example for vehicle revisions
Similarly, to subscribe to vehicle’s make
, model
, and vin
fields changes you can use the following command:
|
|
When these fields are changed the following payload will be sent:
|
|
The full list of order fields to which you can subscribe
number
purchase_order_number
price
transport_type
inspection_type
broker_fee
order_instructions
loadboard_instructions
dispatcher_name
sales_representative
customer.name
customer.business_type
customer.address
customer.city
customer.state
customer.zip
customer.phone
customer.email
customer.contact_name
customer.contact_title
customer.contact_email
customer.contact_phone
customer.contact_mobile_phone
payment.terms
payment.method
payment.notes
payment.amount
payment.reference_number
customer_payment.terms
customer_payment.method
customer_payment.notes
customer_payment.amount
customer_payment.tariff
customer_payment.deposit
customer_payment.reference_number
pickup.first_available_pickup_date
pickup.date_type
pickup.schedule_at_by_customer
pickup.schedule_ends_at_by_customer
pickup.scheduled_at
pickup.schedule_ends_at
pickup.schedule_at_by_carrier
pickup.adjusted_date
pickup.notes
pickup.venue.name
pickup.venue.business_type
pickup.venue.address
pickup.venue.city
pickup.venue.state
pickup.venue.zip
pickup.venue.contact_name
pickup.venue.contact_title
pickup.venue.contact_email
pickup.venue.contact_phone
pickup.venue.contact_mobile_phone
delivery.date_type
delivery.schedule_at_by_customer
delivery.schedule_ends_at_by_customer
delivery.scheduled_at
delivery.schedule_ends_at
delivery.schedule_at_by_carrier
delivery.adjusted_date
delivery.notes
delivery.venue.name
delivery.venue.business_type
delivery.venue.address
delivery.venue.city
delivery.venue.state
delivery.venue.zip
delivery.venue.contact_name
delivery.venue.contact_title
delivery.venue.contact_email
delivery.venue.contact_phone
delivery.venue.contact_mobile_phone
The full list of vehicle fields to which you can subscribe
vehicles.make
vehicles.model
vehicles.type
vehicles.year
vehicles.color
vehicles.vin
vehicles.price
vehicles.tariff
vehicles.lot_number
Offer related actions
Action | Is sent when… |
---|---|
offer.sent | Load offer is sent |
offer.sent.failed | Sending a load offer is failed |
offer.accepted | Load offer is accepted by carrier |
offer.accepted.ignored | The carrier accepts the load offer after it was manually marked as picked up or delivered by the shipper |
offer.updated_to_accepted | The carrier has reverted the order status from picked_up to new |
offer.updated_to_accepted.ignored | The carrier has reverted the order status from delivered to new , or from delivered to picked_up to new |
offer.declined | Load offer is declined |
offer.declined.ignored | The carrier declines the load offer after it was manually marked as delivered by the shipper |
offer.canceled | Load offer is canceled by shipper |
offer.canceled_by_carrier | Load offer is canceled by carrier |
offer.canceled_by_carrier.ignored | Load offer is canceled by carrier after it was delivered |
The offer payload has these additional fields:
Field name | Type | Description |
---|---|---|
offer_guid | guid | GUID of the load offer |
order_guid | guid | GUID of the related order |
carrier_guid | guid | GUID of the carrier which the load offer was sent to |
status | string | The order status. |
id | bigint | Unique identifier (primary key) of the load offer. This is deprecated. |
order_id | bigint | Unique identifier (primary key) of the related order. This is deprecated. |
Sample payload:
|
|
Load Requests related actions
Action | Is sent when… |
---|---|
load_request.created | Carrier sends a load request to shipper |
load_request.updated | Carrier updates their own request (e.g. price, pickup or devliery dates, etc.) |
load_request.canceled_by_carrier | Carrier cancels their own request |
load_request.declined_by_shipper | Shipper declines carrier’s load request |
The load request payload has these additional fields:
Field name | Type | Description | |
---|---|---|---|
order_guid | guid | GUID of the related order | |
data.guid | guid | GUID of the load request | |
data.requested_price | number | The carrier suggested price | |
data.pickup_date | date-time | The carrier suggested pickup date | |
data.delivery_date | date-time | The carrier suggested delivery date | |
data.carrier_guid | guid | GUID of the carrier who sent the load request | |
data.carrier_email | string | Carrier’s email | |
data.carrier_phone | string | Carrier’s phone number | |
data.carrier_name | string | Carrier’s business name | |
data.carrier_contact_name | string | Carrier’s contact person’s name | |
data.carrier_address | string | Carrier’s address | |
data.carrier_city | string | Carrier’s city | |
data.carrier_state | string | Carrier’s state | |
data.carrier_zip | string | Carrier’s ZIP | |
data.carrier_usdot | string | Carrier’s USDOT |
Sample payload:
|
|
The payload above is similar for load request actions such as load_request.declined_by_shipper
,
load_request.canceled_by_carrier
, load_request.created
or load_request.updated
.