Orders At Risk
Webhook payload sent when the risk state of an order changes, how to read the intensity of each risk, and risk_status on GET /orders.
Order at risk Webhook Payload
[
{
"created_at":"2021-01-01T14:01:00.000000Z",
"recorded_at":"2021-01-01T14:00:00.000000Z",
"device_id":"00112233-4455-6677-8899-AABBCCDDEEFF",
"worker_handle": "Worker-1",
"account_id":"6784e919-7168-4f61-b686-2020f547637f",
"type":"order",
"data":{
"value":"risk_updated",
"order_handle":"DGC127092",
"route_handle":"4359cc65-90dd-4b2b-875b-26e6d2eba11d",
"status":"ongoing",
"share_url":"https://trck.at/vr1RNLq",
"risks":{
"deviating_from_expected_route":{
"intensity_label": "red",
"intensity_value": 0.85,
"previous_intensity_label": "yellow"
},
"moving_too_slow":{
"intensity_label": "yellow",
"intensity_value": 0.45,
"previous_intensity_label": "green"
}
},
"metadata":{
"storeId":"123490809808",
"customerName":"Andrew"
}
},
"version":"3.0.0"
}
]The example shows two risk elements to keep it short. A real webhook holds every risk element that we evaluate for the order.
Following are the Risk elements:
delayed_from_scheduled_at: risk element that an order is delayed from the scheduled time of delivery.delayed_from_initial_eta: risk element that an order is delayed beyond the initial ETA communicated to the customeris_offline: risk element that an order is at risk because the device is not sending updates.deviating_from_expected_route: risk element that an order will be at risk because the worker is deviating from the expected route.moving_away_from_destination: risk element that an order will be at risk because the worker is moving away from the destination.in_low_battery: risk element that an order is at risk because the device may shut off before order completion.moving_too_slow: risk element that an order will be at risk because the worker is moving too slowly to fulfil the order.in_outage: risk element that an order is at risk because of a user-driven or software-driven action. eg: turn off GPS, background process killed etc.
How to read intensity
Each risk has an intensity_value from 0 to 1 and an intensity_label. Two things go into the value: how strong the signal is (an ETA 20 min past the scheduled time is stronger than 5 min; a device dark for 30 min is stronger than 5 min) and how sure we are about it (a fresh GPS fix and a steady ETA are sure; a stale fix or a jumpy ETA is not). When we are sure, the value is the signal. When we are not sure, the value moves toward the middle (0.5), so a red only appears when the signal is strong and the evidence is good, and a green only appears when the evidence is good too.
intensity_label | intensity_value | Meaning |
|---|---|---|
green | below 0.45 (< 0.45) | Fine. |
yellow | 0.45 up to, but not including, 0.75 (>= 0.45 and < 0.75) | Watch, or we are not sure yet. |
red | 0.75 and above (>= 0.75) | Act. |
We compare each label with the last risk_updated webhook we sent for the order. We send a new one when a label moves up (the first one when a risk reaches yellow or red), and when a label moves down and its intensity_value changes by more than 0.1. We send at most one per order per minute. Each webhook includes previous_intensity_label, so you can see what moved.
Parameters
| Name | Type | Mandatory | Description |
|---|---|---|---|
| data.value | string | Yes | risk_updated |
| data.order_handle | string | Yes | Unique handle for the Order |
| data.route_handle | string | Yes | Unique identifier of the route containing the order |
| data.status | string | Yes | Status of the order - ongoing |
| data.share_url | string | Yes | Contains tracking url of the order to provide real time visibility of worker on route of this order |
| data.metadata | object | No | Metadata that you have assigned to this order |
| data.risks | object | Yes | Order at risk state. Holds every risk element we evaluate for the order, not only the ones that changed. Orders on a flexible route, and orders that do not have a route estimate yet, get only is_offline, in_outage, moving_too_slow, and in_low_battery. |
| data.risks.delayed_from_scheduled_at | object | No | Risk element evaluating if the order is delayed from the scheduled time of delivery. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.delayed_from_initial_eta | object | No | Risk element evaluating if the order is delayed beyond the initial ETA communicated to the customer. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.is_offline | object | No | Risk element evaluating the online/offline status of the worker. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.deviating_from_expected_route | object | No | Risk element evaluating the deviation in route taken by the worker against the expected route. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.moving_away_from_destination | object | No | Risk element evaluating the direction of the worker, if the worker is moving away from the destination. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.in_low_battery | object | No | Risk element evaluating the battery status of the worker's device. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.moving_too_slow | object | No | Risk element evaluating the speed of the worker. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.in_outage | object | No | Risk element evaluating the outage status of the worker. Object with intensity_value, intensity_label (green, yellow, or red), and previous_intensity_label. |
| data.risks.*.intensity_label | string | Yes | Label of the risk element: green (fine), yellow (watch, or not sure yet), or red (act). See How to read intensity. |
| data.risks.*.intensity_value | number | Yes | Number from 0 to 1. It combines the strength of the signal and how sure we are about it. See How to read intensity. |
| data.risks.*.previous_intensity_label | string | No | Label of the risk element in the previous risk_updated webhook for this order. Not present when the element was not in the previous webhook, for example on the first webhook. |
risk_status on GET /orders
GET /orders returns risk_status on each order, and accepts risk_status as a query filter. risk_status is a rollup of the risk element labels on this page.
- Response field:
truewhen at least one risk element of the order hasintensity_labelyelloworred.falsewhen all risk elements aregreen, or when the order has no risk elements. - Query filter:
risk_status=Truereturns only the orders at risk.risk_status=Falsereturns only the orders that are not at risk. Withaggregate=true, onlyrisk_status=Trueis applied:risk_status=Falseis ignored and the counts include all orders. The value is case-sensitive:trueandfalsein lowercase are not valid. To get all orders, do not send the parameter.
risk_status does not tell you which risk changed. To see the label of each risk element, use this webhook.