Use Case
This API is used to provide updates for a transport from the implementer's inhouse system, usually a TMS. It is possible to send updates for various aspects of the transport:
GPS positions and temperature data from the sensors.
Delivery Events (Arrival to, departure from,...)
Delivery loading/unloading statuses (ETA, remaining distance)
License plate of the truck carrying the order out (To let stakeholders know about it)
Note that the payloads sent are cumulative for data which is timestamped, like events or GPS positions. This means that each new payload will add on top of the previous payload, but will not replace it. Previously sent data does not need to be re-sent with each new update. For deleting a previously sent event there is a special deleted_at flag available, which should be used together with correct event_id.
Endpoint
Code Block | ||
---|---|---|
| ||
POST https://api.transporeon.com/rtv/v1/transports/status |
Identifiers used in the payload
The API allows the user to specify transport or delivery based identifier. The transport_id and transport_number refer to the identifiers provided by Transporeon or the shipper respectively. Alternative is to use the delivery based identifier delivery_id or delivery_number.
Aura panel | ||||
---|---|---|---|---|
| ||||
While Transporeon Visibility Hub supports certain simpler delivery based tracking, it is currently a feature in development and more complex delivery models might result in unexpected behavior. Contact your Transporeon support person to find out more about current limitations about delivery based tracking. |
Generally, a transport specific update applies to all deliveries within that transport. So for most cases a transport specific update is enough.
Sending Transport GPS Positioning Data
The transport_updates array in the payload allows to send multiple updates at once for the same transport with different timestamps or for different transports.
Code Block |
---|
{ "transport_updates": [ { "transport_id": "983549358", "vehicle_telemetry": { "timestamp": "2019-08-24T14:15:22Z", "position": { "lat": 59.4365094, "lng": 24.7428656 }, "direction": 132.6, "speed": 75, "odometer": 523145, "is_engine_running": false, "front_axle_weight_kg": 0, "rear_axle_weight_kg": 0, "total_weight_kg": 0, "altitude_meters": 143, "fuel_level_pct": 20.4, "clean_source_pct": 20.4, "total_fuel_consumption_liters": 4004.11 } }, { "transport_id": "12345678", "vehicle_telemetry": { "timestamp": "2019-08-24T15:12:22Z", "position": { "lat": 57.4365094, "lng": 23.7428656 }, "direction": 132.6, "speed": 75 } } ] } |
Note that once the transport has received a GPS data, it's considered permanent and the next GPS datapoint must have a timestamp newer than the previous one to avoid it being discarded. Therefor the GPS tracking timestamps must always be monotonically increasing within the context of one transport/delivery, it's not possible to backfill older points in history after there has been a newer GPS position.
Sending Transport Loading/Unloading Statuses and Events
Transport events can be sent to indicate any event, for example a loading or unloading has taken place or the vehicle has reached the station for loading/unloading.
Transport events are limited by timestamp to be a maximum of one year in the past and 30 minutes in the future.
For a Transport
Code Block |
---|
{ "transport_updates": [ { "transport_number": "1234567", "loading_status": { "timestamp": "2019-08-24T14:15:22Z", "eta": "2019-08-24T15:15:22Z", "events": [ { "event_id": "1a2b3c", "timestamp": "2019-08-23T15:15:22Z", "qualifier": "heading_towards", "position": { "lat": 59.4365094, "lng": 24.7428656 } } ] } } ] } |
For Multiple Deliveries
Code Block |
---|
{ "transport_updates": [ { "delivery_id": "123456", "loading_status": { "timestamp": "2019-08-24T15:00:00.00Z", "eta": "2019-08-24T14:15:22Z", "estimated_remaining_distance_meters": 5000.151, "events": [ { "event_id": "6f6f6f", "timestamp": "2019-08-24T15:00:00.00Z", "qualifier": "started", "position": { "lat": 59.4365094, "lng": 24.7428656 } } ] } }, { "delivery_id": "123457", "loading_status": { "timestamp": "2019-08-24T15:00:00.00Z", "eta": "2019-08-24T14:15:22Z", "estimated_remaining_distance_meters": 5000.151, "events": [ { "event_id": "1a2b3c", "timestamp": "2019-08-24T15:00:00.00Z", "qualifier": "started", "position": { "lat": 59.4365094, "lng": 24.7428656 } } ] } } ] } |
Sending a Custom Qualifier
Custom qualifier can be sent for an event in case the predefined qualifiers don't match the specific event nature. Custom qualifiers do not trigger any specific action within the status calculation system, but the event will be visible on examination of the transport.
Code Block |
---|
{ "transport_updates": [ { "transport_number": "1234567", "unloading_status": { "timestamp": "2019-08-24T14:15:22Z", "eta": "2019-08-24T15:15:22Z", "events": [ { "event_id": "1a2b3c", "timestamp": "2019-08-23T15:15:22Z", "qualifier_custom": "Waiting for unloading / Idle", "position": { "lat": 59.4365094, "lng": 24.7428656 } } ] } } ] } |
Sending Temperature Data
Temperature data can be sent similarly to GPS data in larger batches. Similarly to GPS data, the timestamps in temperatures are expected to be monotonically increasing within the reefer context. If a temperature is sent for a reefer which has already received a later value, then the temperature with older timestamp is not processed and is discarded.
Code Block |
---|
{ "transport_updates": [ { "transport_number": "1234567", "temperatures": [ { "timestamp": "2018-01-01T01:00:00Z", "reefer_id": "default", "sensor_readings": [ { "compartment_id": "default", "sensor_id": "main", "temperature": -1.015 }, { "compartment_id": "default", "sensor_id": "back", "temperature": -0.1 } ] }, { "timestamp": "2018-01-01T00:00:00Z", "reefer_id": "default", "sensor_readings": [ { "compartment_id": "default", "sensor_id": "main", "temperature": -0.9 }, { "compartment_id": "default", "sensor_id": "back", "temperature": -0.1 } ] } ] } ] } |
The structure of the data looks as follows:
Code Block |
---|
---------------------------------------- ---------------------------------------- | reefer 1 | | reefer N | | --compartment1- --compartmentN- | | --compartment1- --compartmentN- | | | sensor 1 | | sensor 1 | | | | sensor 1 | | sensor 1 | | | | | | | | | | | | | | | | sensor 2 | | sensor 2 | | | | sensor 2 | | sensor 2 | | | | | | | | | | | | | | | | senor n | | senor n | | | | senor n | | senor n | | | --------------- --------------- | | --------------- --------------- | | | | | ----------------------------------------|===|---------------------------------------- |
There can be one to many reefers.
Each reefer can serve one to many compartments.
Each compartment can have one or more sensors
Completing a Transport
In case the transport does not complete automatically due to lack of signal or unloading events, it is possible to complete the transport by using completed event qualifier.
Code Block |
---|
{ "transport_updates": [ { "transport_number": "1234567", "transport_events": [ { "event_id": "123cf31a", "timestamp": "2018-01-01T00:00:00Z", "qualifier": "completed", "position": { "lat": 51.5074, "lng": 0.1278 } } ] } ] } |
Deleting an Existing Event
In some cases you might want to delete a previously sent event. The API allows it by redefining the event with the deleted_at property being set at current time.
Code Block |
---|
{ "transport_updates": [ { "transport_number": "1234567", "loading_status": { "events": [ { "event_id": "1a2b3c", "timestamp": "2019-08-23T15:15:22Z", "deleted_at": "2019-08-23T18:15:22Z" } ] } } ] } |