Conroo Trucking Api Version 1.0.0
Trucking api process graph
This Api description explains how the various endpoints in this api can be used to effectively used to communicate with conroo. Correct authentication is required to interact with this api through an Api Key, conroo must be contacted for access.
Since this is a server to server api communication shall be done by an api key which will be distributed by us. It should be sent as a header with name "X-API-KEY" and the value provided. Also the truckingSystemId should be provided in authentication api calls as it is needed to identify if the current api key belongs to the trucking system.
const headers = new Headers({
'X-API-KEY': apiKey,
'Content-Type': 'application/json',
});
// Make the API call using fetch
fetch(apiEndpoint, {
method: 'GET', // You can use other HTTP methods (e.g., 'POST', 'PUT', 'DELETE')
headers: headers,
})
.then(response => response.json())
.then(data => {
console.log('API Response:', data);
})
.catch(error => {
console.error('API Error:', error);
});
Tours are the main component of the api and describe a route taken by a trucker. Tours are a collection of loading units which represent the bookings (whether they may be pickups or deliveries), and they are specified for a specific timeslot (time to be completed) together.
Tours entities
The first step on interacting with tours is getting the necessary information of the loading units. We offer that through the endpoint "get status" in which an array of requets containing loadUnitNumber and referenceNumber are provided along with the type. The response contains data for the loading units and also a shared timeslot between all these loading units.
const endpointUrl = '/v1/truckingSystems/{truckingSystemId}/forwarders/{forwarderId}/facilities/{facilityId}/loadingunits';
// Define the request payload (body data)
const requestBody = {
"requests": [
{
"loadUnitNumber": "CERU1234567",
"referenceNumber": "90090061924532",
"type": "delivery"
}
]
};
// Define the path parameters
const truckingSystemId = 123; // Replace with the actual truckingSystemId
const forwarderId = 456; // Replace with the actual forwarderId
const facilityId = 789; // Replace with the actual facilityId
// Generate the complete URL by replacing path parameters
const completeUrl = endpointUrl
.replace('{truckingSystemId}', truckingSystemId)
.replace('{forwarderId}', forwarderId)
.replace('{facilityId}', facilityId);
// Define request headers
const headers = new Headers({
'Content-Type': 'application/json',
'X-API-KEY': 'YOUR_API_KEY_HERE', // Replace with your actual API key
// Add any additional headers if required
});
// Create the Fetch API request
const fetchOptions = {
method: 'POST',
headers: headers,
body: JSON.stringify(requestBody),
};
// Make the API call
fetch(completeUrl, fetchOptions)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the successful response data here
console.log('API Response:', data);
})
.catch(error => {
// Handle errors here
console.error('API Error:', error);
});
[
{
"responses": {
"loadUnitNumber": "CERU1234567",
"referenceNumber": "90090061924532",
"type": "delivery",
"loadUnit": {
"loadUnitLength": 40,
"loadUnitNumber": "CERU1234567",
"loadUnitType": "string",
"emptyWeight": 2000,
"id": 1,
"listDangerousGoodsData": [
{
"clazz": "string",
"id": 0,
"lq": true,
"uNNr": "string"
}
],
"listSealData": [
{
"id": 0,
"number": "string"
}
],
"listCustomsData": [
{
"documentNumber": "string",
"documentType": "string",
"id": 0
}
],
"listWasteData": [
{
"aVVNumber": "string",
"eAKKeyNumber": "string",
"id": 0,
"voucherNumber": "string"
}
],
"netWeight": 20000,
"overhang": 0
},
"errorCode": "string"
},
"timeSlots": [
{
"remainingCapacity": 50,
"expectedCycleTime": 20,
"id": 0,
"slotBegin": "2022-08-10T07:34:58.294Z",
"slotEnd": "2022-08-10T07:35:15.886Z"
}
]
}
]
After the prerequisite of getting the loading units we are ready to create a tour. Tours are created in the level of forwarders, and also per trucker with the information of loading units being part of a facility. Here the same information should be still sent of loadUnitNumber, referenceNumber and type and also the timeslotId. Get status is important because it provides the information of the loadiung units along with the timeslots available in which we can use here to create the tour.
const endpointUrl = '/v1/truckingSystems/{truckingSystemId}/forwarders/{forwarderId}/truckers/{truckerId}/facilities/{facilityId}/tours';
// Define the request payload (body data)
const requestBody = {
"timeSlotId":346,
"containerBookings": [
{
"loadUnitNumber": "CERU1234567",
"referenceNumber": "90090061924532",
"type": "delivery"
}
]
};
// Define the path parameters
const truckingSystemId = 123; // Replace with the actual truckingSystemId
const forwarderId = 456; // Replace with the actual forwarderId
const facilityId = 789; // Replace with the actual facilityId
const truckerId = "419242-10941-01249f";
// Generate the complete URL by replacing path parameters
const completeUrl = endpointUrl
.replace('{truckingSystemId}', truckingSystemId)
.replace('{forwarderId}', forwarderId)
.replace('{facilityId}', facilityId)
.replcae('{truckerId}',truckerId);
// Define request headers
const headers = new Headers({
'Content-Type': 'application/json',
'X-API-KEY': 'YOUR_API_KEY_HERE', // Replace with your actual API key
// Add any additional headers if required
});
// Create the Fetch API request
const fetchOptions = {
method: 'POST',
headers: headers,
body: JSON.stringify(requestBody),
};
// Make the API call
fetch(completeUrl, fetchOptions)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the successful response data here
console.log('API Response:', data);
})
.catch(error => {
// Handle errors here
console.error('API Error:', error);
});
If all goes well a 200 http response should be returned, mirroring back the tour data saved.
After we create the tours, the tours can be manipulated as most basic entities in a rest api:
All these endpoints are specified in the swagger specification, we will be explaining only the non trivial ones in this documentation.
In cases when a tour can not be completed at the agreed time, the time can be changed.First the available times must be fetched from the endpoint "get timeslots per tour", and then an id must be sent for that timeslot to update the tour in the next endpoint.
Adding a container booking mostly follows the same schema, with the only important point that if the loadingunit does not have the shared timeslot with the other existing loading units in the tour this action will not work.
Loading units as specified before on the tours section are objects which represent loading units in facilities(terminals/depots). Fetching loading units was already explained on tours, the only other action is updating the information of an update load unit. This may happen on cases where the facility does not give the correct information or does not even have it. Cases where this may be applicable are a missing loadUnitNumber for deliveries.
const endpointUrl = '/v1/truckingSystems/{truckingSystemId}/forwarders/{forwarderId}/tours/{tourId}/containerBooking/{containerBookingId}/loadUnits';
// Define the request payload (body data)
const requestBody = {
"loadUnit": {
"loadUnitLength": 40,
"loadUnitNumber": "CERU1234567",
"loadUnitType": "string",
"emptyWeight": 2000,
"id": 1,
"listDangerousGoodsData": [
{
"clazz": "string",
"id": 0,
"lq": true,
"uNNr": "string"
}
],
"listSealData": [
{
"id": 0,
"number": "string"
}
],
"listCustomsData": [
{
"documentNumber": "string",
"documentType": "string",
"id": 0
}
],
"listWasteData": [
{
"aVVNumber": "string",
"eAKKeyNumber": "string",
"id": 0,
"voucherNumber": "string"
}
],
"netWeight": 20000,
"overhang": 0
}
};
// Define the path parameters
const truckingSystemId = 123; // Replace with the actual truckingSystemId
const forwarderId = 456; // Replace with the actual forwarderId
const tourId = 789; // Replace with the actual tourId
const containerBookingId = 32;
// Generate the complete URL by replacing path parameters
const completeUrl = endpointUrl
.replace('{truckingSystemId}', truckingSystemId)
.replace('{forwarderId}', forwarderId)
.replace('{tourId}', tourId)
.replcae('{containerBookingId}',containerBookingId);
// Define request headers
const headers = new Headers({
'Content-Type': 'application/json',
'X-API-KEY': 'YOUR_API_KEY_HERE', // Replace with your actual API key
// Add any additional headers if required
});
// Create the Fetch API request
const fetchOptions = {
method: 'POST',
headers: headers,
body: JSON.stringify(requestBody),
};
// Make the API call
fetch(completeUrl, fetchOptions)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the successful response data here
console.log('API Response:', data);
})
.catch(error => {
// Handle errors here
console.error('API Error:', error);
});
All attributes that belong to this object can be manipulated. Basic validation is applicable like iso 6346 for loadunitnumber or weight and length validations.
Forwarders are part of the trucker objects and through this object we know which truckers "belong" to which forwarders.
The saving forwarder endpoint saves the forwarder by name and email if not existing, and if it is already in our system, it is returned. In either case an appropriate forwarder instance with an id will be returned.
The get forwarders endpoint is quite simplistic in which it returns all forwarders for your truckiong system.
[
{
"email": "forwarder@truck.com",
"id": 3,
"name": "Example Forwarder"
}
]
All information for these endpoints is available in the swagger documentation at the top of the page.
const WebSocket = require('websocket').client;
const wsClient = new WebSocket();
const serverUrl = 'ws://your-websocket-server-url';
const apiKey = 'your-api-key';
wsClient.on('connectFailed', (error) => {
console.error('Connection failed:', error);
});
wsClient.on('connect', (connection) => {
console.log('WebSocket Client Connected');
connection.on('error', (error) => {
console.error('Connection Error:', error);
});
connection.on('close', () => {
console.log('Connection Closed');
});
connection.on('message', (message) => {
if (message.type === 'utf8') {
console.log('Received message:', message.utf8Data);
}
});
// Set the API key in the headers
connection.setHeader('X-API-KEY', apiKey);
// Connect to the WebSocket server
connection.connect(serverUrl);
});
These events are events conroo sends to update the state about truckers and their connected entities like load units, tours and other components.
This event is sent on cases where the facility(terminal/depot) has new information and updates the data of one of the load units that is part of the tour. The load unit must be updated acoordingly after this messsage
{
"type": "update_booking_loading_unit_data",
"event": {
"loadUnit": {
"loadUnitLength": 0,
"loadUnitType": "string",
"loadUnitNumber": "string",
"emptyWeight": 0,
"listDangerousGoodsData": [
{
"uNNr": "string",
"lq": true,
"clazz": "string"
}
],
"listSealData": [
{
"sealNumber": "string"
}
],
"listCustomsData": [
{
"documentNumber": "string",
"documentType": "string"
}
],
"listWasteData": [
{
"voucherNumber": "string",
"aVVNumber": "string",
"eAKKeyNumber": "string"
}
],
"netWeight": 0,
"overhang": 0
},
"tourId": 0,
"containerBookingId": 0
}
}
On updates of trains or other entities in which loadunits may cause changes in time schedule, the available timeslots change, this messsage calculates the new available timeslots for a tour. In this case a new timeslot should be picked with the endpoint updateTimeslotForTour.
{
"type": "update_tour_slot_times",
"event": {
"tourId": 0,
"timeSlots": [
{
"id": 0,
"slotBegin": "2019-08-24T14:15:22Z",
"slotEnd": "2019-08-24T14:15:22Z"
}
]
}
}
On cases where a container is deleted by a facility or other entity, this information is passed on acoordingly.
{
"type": "delete_booking",
"event": {
"tourId": 0,
"containerBookingId": 0,
"reason": "string",
"truckerId": "string",
"author": "FACILITY"
}
}
This message is equivalent to the previous one, with the only key difference being that this deletes the whole tour and not just one specific booking.
{
"type": "delete_tour",
"event": {
"tourId": 0,
"reason": "string",
"truckerId": "string",
"author": "FACILITY"
}
}
This message informs that the crane task has been complete for the specific loadunit and everything is complete in the side of the facility successfully on the process of picking/delivering.
{
"type": "transhipment_task_confirmation",
"event": {
"tourId": "string",
"containerBookingId": "string",
"truckerId": "string"
}
}
Modules as part of facilities may be closed and opened due to internal needs of the facility.This message informs about such a change along with all the ids of the loadunits that are affected, this can be useful for informing the truckers whose these containers belong to.
{
"type": "update_module_state",
"event": {
"state": "opened",
"facilityId": 0,
"module": "string",
"containerBookingIds": [
0
]
}
}