Introduction
This is the guide and API definition to integrate Deliverymates as a logistic partner.
Authentication
An authentication token will be provided to you at the beginning of our collaboration. Include it in an authorization HTTP header to authenticate all of your API calls.
Authorization: Token token=21dfdda6f27ffb9f4f4666d25c63b9a629d563274ea5638d2e
Conventions
A base URL will also be provided in conjunction with the authentication token. All requests have to be addressed to this base URL:
https://your-middlewaye-url
This API speaks JSON so a header has to be included in each request:
Content-Type: application/json
Reponse formats
Responses are commonly JSON objects. These objects will represent entities matching both fields and methods from the backend.
The next curl command represents a sample call
curl "http://server_url/path/to/api/endpoint"
-X GET
-H "Content-Type: application/json"
-H "Authorization: Token token=04e59ae46203f6d1c218be75ea4ce76656fc5d5b2bf9fb99cf"
The above command will return a JSON represented as follows:
[
{
"field_1": "value 1",
"field_2": "value 2",
"field_3": "value 3"
}
]
Errors
Each request may siply result in a 200 HTTP code and the resulting resource information.
For those situations in which something goes wrong, these are the common errors that the server may respond:
Error Code | Meaning |
---|---|
400 | Bad Request – Your request sucks |
401 | Unauthorized – Your API key is wrong or your token has expired |
403 | Forbidden – You don’t have permission to access this object |
404 | Not Found – The specified resource could not be found |
405 | Method Not Allowed – You tried to access a resource with an invalid method |
406 | Not Acceptable – You requested a format that isn’t json |
410 | Gone – The resource requested has been removed from our servers |
418 | I’m a teapot |
422 | Unprocessable entity – The server understands the content type of the request entity, and the syntax of the request entity is correct but was unable to process the contained instructions. |
429 | Too Many Requests – You’re requesting too many resources! Slow down! |
500 | Internal Server Error – We had a problem with our server. Try again later. |
503 | Service Unavailable – We’re temporarily offline for maintenance. Please try again later. |
Orders
To push a new order the POST http method has to be used.
The typical workflow followed when managing an order using the dmates API is as follows :
You send the order to our endpoint url.
We send you a serie of predefined order status callbacks as the order progresses through its life-cycle.
Create an order
To create a new order
curl "http://server_url/api/ext/v1/orders"
-X POST
-H "Content-Type: application/json"
-d "
{
'order': {
'external_id': 'd6g7h3J8387g32jh003',
'friendly_order_reference': 'FRIENDLY_ID',
'source_provider': 'Burger King',
'price': 15.75,
'electric_vehicle_requested': true,
'paid_at': '2017-10-02T14:23:22Z',
'cash_on_delivery': false,
'ready_for_pickup': true,
'volume': '50',
'transport_type': 'small_scooter',
'basket_items':
[
{
'name': 'Kids menu',
'quantity': 1,
'original_unit_price': 10,
'discounted_unit_price': 8.5,
'volume': '50',
'barcode': '8888881112233',
'note': 'shelf: 100',
'sub_items':
[
{
'name': 'Pizza Margherita',
'quantity': 1,
'original_unit_price': 7,
'discounted_unit_price': 7,
'sub_items':
[
{
'name': 'Extra anxovies',
'quantity': 1,
'original_unit_price': 1,
'discounted_unit_price': 0.75
},
{
'name': 'Extra olives',
'quantity': 1,
'original_unit_price': 0.9,
'discounted_unit_price': 0.65
}
]
}
]
}
],
'jobs':
[
{
'type': 'pickup',
'time_window_start': '2017-10-02T14:00:00Z',
'time_window_end': '2017-10-02T14:23:22Z',
'note': 'Please do it as much toasted as possible',
'place':
{
'external_id': 'd7h3J8387g9876',
'address_line1': 'Somewhere addr',
'address_line2': 'Something else',
'postal_code': 'AR J354',
'city': 'London',
'country': 'GB',
'contact_name': 'Peter Petrelli',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'phone_number': '001122334455',
'position': [41.829709, 3.047605]
}
},
{
'type': 'delivery',
'time_window_start': '2017-10-02T13:00:00Z',
'time_window_end': '2017-10-02T15:00:27Z',
'note': 'Please call if not at home',
'place':
{
'external_id': 'd6g7h3J8382346',
'address_line1': 'Somewhere',
'address_line2': 'On Earth',
'postal_code': 'AR J354',
'city': 'London',
'country': 'GB',
'contact_name': 'Jean Louis',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'phone_number': '001122334455',
'position': [41.82971, 3.047608]
}
}
],
'callback_urls' : {
'order_status': {
'url': 'https://yourdomain.com/api/orders/:order_id/status'
},
'route_status': {
'url': 'https://yourdomain.com/api/routes'
},
'driver_position': {
'url': 'https://yourdomain.com/api/orders/:order_id/driver-position'
}
}
}
}
"
The above command returns JSON structured like this:
{
"id": "5981a5a82ade720001e571fd"
}
or if there is an error returns JSON structured like this:
{
"errors": {
"code": "other or bad_request",
"message": "Not codified messages"
}
}
HTTP Request
POST /api/ext/v1/orders
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
external_id | yes | String, The provider order Id | |
friendly_order_reference | no | String, Another provider id | |
source_provider | yes | String, The source provider | |
price | yes | Float number, the total price of the order | |
electric_vehicle_requested | no | Boolean value. Just set it to true to request an electric vehicle. | |
paid_at | yes | Iso8601 timestamp, The date when the order was paid. Set it to blank if you set cash_on_delivery as true. | |
cash_on_delivery | yes | Boolean | |
ready_for_pickup | yes | Boolean | |
volume | no | String, The packages volume of total order in cm3. | |
transport_type | no | String, the value can be: walker, bicycle, car, scooter, large_scooter, cargo_bicycle, small_van, medium_van and large_van. By default it will be used: small_scooter. |
An order can contain one or multiple basket items. Each one can also contain zero, one or multiple sub items.
Parameter | Mandatory | Default | Description |
---|---|---|---|
name | yes | String, The name of the item | |
quantity | yes | Integer, The amount of units of this item | |
volume | no | String, The volume of this item in cm3 | |
barcode | no | String, The barcode identifier | |
note | no | String, A text note with extra information, like shelf number, etc. | |
original_unit_price | no | String, Original price for a unit of this item | |
discounted_unit_price | no | String, Item price with discount applied (if any) | |
sub_items | no | A recursive array of items included in this one |
An order should contain at least two jobs (pickup and delivery)
Parameter | Mandatory | Default | Description |
---|---|---|---|
type | yes | Job type: “pickup” or “delivery” | |
time_window_start | yes/no* | Iso8601 timestamp, The start time of pickup/delivery range (*Home delivery: mandatory field in delivery job) | |
time_window_end | yes | Iso8601 timestamp, “Food delivery”: ETA for when the driver is supposed to get to this place. “Home delivery”: maximum ETA to delivery the order. | |
note | no | String, A text note that the driver can show at the place | |
place | yes | An object representing a place (restaurant, customer house, etc…) |
The place object contains the data for the pickup or the dropoff
Parameter | Mandatory | Default | Description |
---|---|---|---|
external_id | yes | String, The place Id | |
address_line1 | yes | String, First line of place address | |
address_line2 | no | String, Complementary line of place address | |
postal_code | yes | String, Postal code | |
city | yes | String, The city name | |
first_name | no | String, Name for the person targeted at this place | |
last_name | no | String, Name for the person targeted at this place | |
contact_name | yes | String, Name for the contact person in this place, can be different from the main name (eg: name is for a final customer, contact name is for a restaurant) | |
no | String, Email | ||
phone_number | yes | String, Contact phone number | |
mobile_phone_number | yes | String, Contact phone number (mobile one) | |
country | yes | String, the place country in 2-letter ISO format. | |
position | no | An array representing the geographical position for this place in the format [lat, long]. If you give us a position then we’ll trust it. If you don’t then we’ll automatically reverse geocode the address to get a position. This process is usually trustable if the address is correct, but may generate an incorrect position if the address is not exact. |
These are the field for the callback_urls object
Parameter | Mandatory | Default | Description |
---|---|---|---|
order_status | no | Object, the callback url. If you don’t send it to us, we will not send the status update for this order. | |
driver_position | no | Object, the callback url. If you don’t send it to us, we will not send the driver positions for this order. |
Update order status
This endpoint allows to update an order status. This endpoint is waiting for:
- A ready_for_pickup event to know when the food is actually ready to be collected in the restaurant.
- A order_cancelled event to know when an order is canceled.
HTTP Request
PUT /api/ext/v1/orders/:order_id
With :order_id being the id that was first returned upon order creation or you can use the external_id.
curl "http://server_url/api/ext/v1/orders/:order_id"
-X POST
-H "Content-Type: application/json"
-d "
{
'order': {
'status': 'ready_for_pickup',
'timestamp': '2017-10-02T14:23:22Z',
'message': 'test message'
}
}
"
The above command returns a 200, 400 or 422 http code or if there is an error returns JSON structured like this:
{
"errors": {
"code": "other or bad_request",
"message": "Not codified messages"
}
}
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
message | yes | Reason to cancel |
Order batches
Orders can be split into multiple parts in certain situations, such as:
If the driver arrives at the pickup location and the goods don’t fit into a single vehicle, the control room will split the order into two parts (meaning two separate orders).
If the driver attempts to deliver an order but, for any reason, the delivery cannot be completed, they can create a retry. This will also split the order into two parts.
In these cases, the order will pass through the integration as usual, but it will be split on the Delivery Mates side and treated as part of a batch.
The following fields are always present in the status callbacks and will provide information about the existence and size of the batches:
fled | description |
---|---|
batch_id | This will always match the ID of the original order. |
batch_idx | The sequence number of the order within the batch. |
batch_count | The total number of orders in the batch. |
Batch example #1
A standalone order will include the fields as follows
Order id | reference | batch_id | batch_idx | batch_count |
---|---|---|---|---|
5981a5a82ade720001e571fd | SOME_REF | 5981a5a82ade720001e571fd | 1 | 1 |
Batch example #2
An order came in, then it got split into 3 parts
Order id | reference | batch_id | batch_idx | batch_count |
---|---|---|---|---|
5981a5a82ade720001e571fd | SOME_REF | 5981a5a82ade720001e571fd | 1 | 3 |
646c8fa80310e963b3ad195a | SOME_REF/2 | 5981a5a82ade720001e571fd | 2 | 3 |
646c8fb30310e963b3ad195b | SOME_REF/3 | 5981a5a82ade720001e571fd | 3 | 3 |
Batch example #3
In this example the order starts as standalone. Then it becomes part of a bigger batch in different steps.
An order came in and behaved as an ordinary standalone one
Order id | reference | batch_id | batch_idx | batch_count |
---|---|---|---|---|
5981a5a82ade720001e571fd | SOME_REF | 5981a5a82ade720001e571fd | 1 | 1 |
At some moment, it got splitted into 2 parts
Order id | reference | batch_id | batch_idx | batch_count |
---|---|---|---|---|
5981a5a82ade720001e571fd | SOME_REF | 5981a5a82ade720001e571fd | 1 | 2 |
646c8fa80310e963b3ad195a | SOME_REF/2 | 5981a5a82ade720001e571fd | 2 | 2 |
Finally it got splitted into 3 parts
Order id | reference | batch_id | batch_idx | batch_count |
---|---|---|---|---|
5981a5a82ade720001e571fd | SOME_REF | 5981a5a82ade720001e571fd | 1 | 3 |
646c8fa80310e963b3ad195a | SOME_REF/2 | 5981a5a82ade720001e571fd | 2 | 3 |
646c8fb30310e963b3ad195b | SOME_REF/3 | 5981a5a82ade720001e571fd | 3 | 3 |
Delivery options
When an order is delivered or attempted the payload on the callbacks will contain valuable information on the finalisation status
The status delivery_done
means that the order lifecycle got to an end. The delivery_option
and delivery_sub_option
give the information of what happened with that delivery.
Successful delivery
A successful delivery will contain the next piece of payload
"status": "delivery_done",
"delivery_option": {
"code": "delivered",
"description": "Delivered"
},
"delivery_sub_option": {
"code": "delivered_to_recipient",
"description": "Delivered to recipient"
},
Some additional information about the delivery can appear in the payload (called delivery_extra
):
"delivery_extra": {
"who": "John Doe",
"where": "The door next to the main one",
"safe": false
}
None of the extras are mandatory, they can appear or not. The meaning of each one is as follows:
Parameter | type | Description |
---|---|---|
who | string | Normally the name of who picked the goods |
where | string | If the delivery address was different from the provided one |
safe | boolean | Whether the driver left a safe card or not |
Attempt
When an order can’t be delivered then we call it an ATTEMPT. In this case the payload will look like this
"status": "delivery_done",
"delivery_option": {
"code": "attempted",
"description": "Attempted"
},
"delivery_sub_option": {
"code": "customer_not_at_home",
"description": "Customer not at home"
},
List of options and suboptions
This is the list of valid delivery_options
Code | Description |
---|---|
delivered | Parcel successfully delivered |
attempted | Could not deliver |
This is the list of valid delivery_sub_options
Code | Option | Description |
---|---|---|
delivered_to_recipient | delivered | Delivered to recipient |
delivered_to_neighbour | delivered | Delivered to neighbour |
posted_through_letter_box | delivered | Posted through the letter box |
left_on_doorstep | delivered | Left on doorstep |
left_behind_bin | delivered | Left behind bin |
left_with_concierge | delivered | Left with concierge |
left_with_receptionist | delivered | Left with receptionist |
left_in_postal_area | delivered | Left in postal area |
left_behind_plant | delivered | Left behind plant pot |
left_behind_bushes | delivered | Left behind bushes |
left_by_gate | delivered | Left by gate |
left_other | delivered | Other |
customer_not_at_home | attempted | Customer not at home |
address_not_found | attempted | Could not locate address |
address_not_accessible | attempted | Unable to access address |
incorrect_address | attempted | Incorrect address |
no_safe_location | attempted | No safe location to leave |
refused_by_customer | attempted | Refused by customer |
parcel_damaged | attempted | Parcel was damaged |
parcel_missing | attempted | Parcel was missing |
poor_quality | attempted | Poor quality |
ops_delayed | attempted | Ops delayed |
Order Status Callbacks
We will perform 8 callbacks as the order progresses through its life-cycle. Those are:
order_accepted
order_rejected
order_assigned
pickup_started
pickup_arrived
pickup_done
delivery_started
delivery_arrived
delivery_done
order_cancelled
All Callbacks will be performed to the url specified in the order request (field: order_status of object callback_urls).
Plaease make sure to check the Order Batches section to understand retries.
Order accepted
This callback is sent to tell you whether we accept the order
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'order_accepted',
'timestamp': '2017-07-29T19:30:05.000Z',
'message': '',
'order_content': {
'order': {
'external_id': 'd6g7h3J8387g32jh003',
'friendly_order_reference': 'FRIENDLY_ID',
'source_provider': 'Burger King',
'price': 15.75,
'paid_at': '2017-10-02T14:23:22Z',
'cash_on_delivery': false,
'ready_for_pickup': true,
'volume': '40x40x40cm',
'basket_items':
[
{
'name': 'Kids menu',
'quantity': 1,
'original_unit_price': 10,
'discounted_unit_price': 8.5,
'volume': '40x40x40cm',
'barcode': '8888881112233',
'note': 'shelf: 100',
'sub_items':
[
{
'name': 'Pizza Margherita',
'quantity': 1,
'original_unit_price': 7,
'discounted_unit_price': 7,
'sub_items':
[
{
'name': 'Extra anxovies',
'quantity': 1,
'original_unit_price': 1,
'discounted_unit_price': 0.75
},
{
'name': 'Extra olives',
'quantity': 1,
'original_unit_price': 0.9,
'discounted_unit_price': 0.65
}
]
}
]
}
],
'jobs':
[
{
'type': 'pickup',
'time_window_start': '2017-10-02T14:00:00Z',
'time_window_end': '2017-10-02T14:23:22Z',
'note': 'Please do it as much toasted as possible',
'place':
{
'external_id': 'd7h3J8387g9876',
'address_line1': 'Somewhere addr',
'address_line2': 'Something else',
'postal_code': 'AR J354',
'city': 'London',
'country': 'GB',
'contact_name': 'Peter Petrelli',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'phone_number': '001122334455',
'position': [3.047605, 41.829709]
}
},
{
'type': 'delivery',
'time_window_start': '2017-10-02T13:00:00Z',
'time_window_end': '2017-10-02T15:00:27Z',
'note': 'Please call if not at home',
'place':
{
'external_id': 'd6g7h3J8382346',
'address_line1': 'Somewhere',
'address_line2': 'On Earth',
'postal_code': 'AR J354',
'city': 'London',
'country': 'GB',
'contact_name': 'Jean Louis',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'phone_number': '001122334455',
'position': [3.047608, 41.82971]
}
}
],
'callback_urls' : {
'order_status': {
'url': 'https://yourdomain.com/api/orders/:order_id/status'
},
'driver_position': {
'url': 'https://yourdomain.com/api/orders/:order_id/driver-position'
}
}
}
}
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, (one of order_accepted, order_rejected, order_assigned, pickup_started, pickup_arrived, pickup_done, delivery_started, delivery_arrived, delivery_done) | |
timestamp | yes | Iso8601 timestamp, the timestamp at which the decision was taken (order could be rejected at moment t and accepted at moment t+1). | |
message | no | String, extra infos regarding the rejected reasons (could be too_busy, too_far, location_not_supported, bad_address etc..). | |
order_content | yes | Order that you sent to us. |
Order rejected
This callback is sent to tell you whether we reject the order
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'order_rejected',
'timestamp': '2017-07-29T19:30:05.000Z',
'message': '',
'order_content': {
'order': {
'external_id': 'd6g7h3J8387g32jh',
'source_provider': 'Burger King',
'price': 15.75,
'paid_at': '2017-09-29T17:03:56Z',
'cash_on_delivery': false,
'ready_for_pickup': true,
'basket_items':
[
{
'name': 'Kids menu',
'quantity': 1,
'original_unit_price': 10,
'discounted_unit_price': 8.5,
'volume': '40x40x40cm',
'barcode': '8888881112233',
'sub_items':
[
{
'name': 'Pizza Margherita',
'quantity': 1,
'original_unit_price': 7,
'discounted_unit_price': 7,
'sub_items':
[
{
'name': 'Extra anxovies',
'quantity': 1,
'original_unit_price': 1,
'discounted_unit_price': 0.75
},
{
'name': 'Extra olives',
'quantity': 1,
'original_unit_price': 0.9,
'discounted_unit_price': 0.65
}
]
}
]
}
],
'jobs':
[
{
'type': 'pickup',
'estimated_time': '2017-09-29T17:03:56Z',
'note': 'Please do it as much toasted as possible',
'place':
{
'external_id': 'd7h3J8387g9876',
'address_line1': 'Somewhere addr',
'address_line2': 'Something else',
'postal_code': 'AR J354',
'city': 'London',
'contact_name': 'Peter Petrelli',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'phone_number': '001122334455',
'position': [3.047605, 41.829709]
}
},
{
'type': 'delivery',
'estimated_time': '2017-09-29T17:03:56Z',
'note': 'Please call if not at home',
'place':
{
'external_id': 'd6g7h3J8382346',
'address_line1': 'Somewhere',
'address_line2': 'On Earth',
'postal_code': 'AR J354',
'city': 'London',
'email': '[email protected]',
'mobile_phone_number': '556677889900',
'first_name': 'Jean',
'last_name': 'Louis',
'phone_number': '001122334455',
'position': [3.047608, 41.82971]
}
}
],
'callback_urls' : {
'order_status': {
'url': 'https://yourdomain.com/api/orders/:order_id/status'
},
'driver_position': {
'url': 'https://yourdomain.com/api/orders/:order_id/driver-position'
}
}
}
}
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, (one of order_accepted, order_rejected, order_assigned, pickup_started, pickup_arrived, pickup_done, delivery_started, delivery_arrived, delivery_done) | |
timestamp | yes | Iso8601 timestamp, the timestamp at which the decision was taken (order could be rejected at moment t and accepted at moment t+1). | |
message | no | String, extra infos regarding the rejected reasons (could be too_busy, too_far, location_not_supported, bad_address etc..). | |
order_content | yes | Order that you sent to us. |
Order cancelled
This callback is sent when the order has been canceled.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'order_cancelled',
'timestamp': '2017-07-29T19:30:05.000Z',
'message': ''
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
message | no | A String |
Order assigned
This callback is sent when a driver is assigned to the order. It will communicate an ETA.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'external_id': 'EXTERNAL_ID',
'status': 'order_assigned',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'pickup_arrived': "2017-07-29T19:30:05.000Z",
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘pickup_arrived’ and ‘delivery_arrived’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Pickup Started
This callback is sent when the driver is on its bike and underway
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'pickup_started',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'pickup_arrived': "2017-07-29T19:30:05.000Z",
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘pickup_arrived’ and ‘delivery_arrived’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Pickup Arrived
This callback is sent when the driver arrives at the restaurant and is ready to collect the order.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'pickup_arrived',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘delivery_arrived’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Pickup Done
This callback is sent when the driver has successfully collected the order at the restaurant.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'pickup_done',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'proof_of_collection': {
'text': "Any collected text",
'signature': "https://path.to/signature.png",
'picture': "https://path.to/picture.png"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘delivery_arrived’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
proof_of_collection | no | An Object containing text, signature and picture for the proff of collection | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Delivery Started
The driver has successfully collected the order and is on its bike underway.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'delivery_started',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘delivery_arrived’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Delivery Arrived
The driver thinks that he has arrived at the specified delivery address.
NB : This callback is distinct from the delivery_done callback, as we use this callback to understand how much time is spent locating the customer’s address.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'delivery_arrived',
'timestamp': "2017-07-29T19:30:05.000Z",
'eta': {
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
eta | yes | Object, Contains ‘delivery_done’ | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Delivery Done
This callback is sent when the driver has handed the food to the customer and completed the order.
{
'order': {
'id': '5981a5a82ade720001e571fd',
'external_id': 'EXTERNAL_ID',
'status': 'delivery_done',
'delivery_option': {
'code': 'delivered',
'description': 'Delivered successfully'
},
'delivery_sub_option': {
'code': 'left_with_neighbour',
'description': 'Successfully delivered to a neighbour'
},
'timestamp': "2017-07-29T19:30:05.000Z",
'driver_position': {
'latitude': 2,
'longitude': 3
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
},
'proof_of_delivery': {
'text': "Any collected text",
'signature': "https://path.to/signature.png",
'picture': "https://path.to/picture.png"
},
'batch_id': '644211566007421e866723df',
'batch_idx': '1',
'batch_count': '2'
}
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, Id. | |
external_id | yes | String, Id. | |
status | yes | String, the current status of the order. | |
delivery_option | no | An object containing a code and description of the delivery status | |
delivery_sub_option | no | An object containing a code and description of the sub option for the delivery status | |
timestamp | yes | Iso8601 timestamp, the timestamp for the new status. | |
driver_position | yes | An Object containing ‘latitude’ and ‘longitude’. | |
driver_infos | yes | An Object containing ‘id’ and ‘name’. | |
proof_of_delivery | no | An Object containing text, signature and picture for the proof of delivery | |
batch_id | no | ID of the batch | |
batch_idx | no | Sequence number inside the batch | |
batch_count | no | Total amount of orders inside the batch |
Driver Position Callback
We will perform a request every 10 seconds to provide you with the exact driver GPS position.
The requests will be performed to the callback url (field: driver_position of object callback_urls) specified in the order.
Driver Location
This callback is sent to tell you the exact driver location
{
'id': '5981a5a82ade720001e571fd',
'status': 'pickup_arrived',
'driver_position': {
'latitude': 2,
'longitude': 3
},
'eta': {
'pickup_arrived': "2017-07-29T19:30:05.000Z",
'delivery_arrived': "2017-07-29T19:30:05.000Z"
},
'driver_infos': {
'id': "5981a5a32ade720001e921fa",
'name': "Moto driver Parker"
'electric_vehicle: electric_vehicle': true
},
'timestamp': '2017-09-02T09:31:50Z'
}
The above command returns a 200
Query Parameters
These are the field for the Order object
Parameter | Mandatory | Default | Description |
---|---|---|---|
id | yes | String, the order Id | |
status | yes | String, the order status. | |
driver_position | yes | Object containing latitude and longitude | |
eta | yes | Object containing pickup and delivery etas | |
driver_infos | yes | Object containing ‘id’, ‘name’, and other informations of interest (ie: electric_vehicle) | |
timestamp | yes | Iso8601 Date Time timestamp |
Route optimization callback
We will send you callbacks after optimizing a route. The callbacks will be sent to the url specified in the order request (field: route_status of object callback_urls). It’s a single callback and will inform all the stops in the route, with their ETA and sequence.
If the same route needs a latr optimization (ex: a new order is added, or it’s merged with another route) then we’ll send the callback again.
{
"reference": "1727945562_AC7C540D1675",
"id": "66fe5b595b85a4623a0bc41f",
"timestamp": "1727945562",
"run_status": "opened",
"stops": [
{
"id": "66fe5b5a5b85a4623a0bc422",
"order_id": "66fe5b325b85a43166f98775",
"idx": "1",
"estimated_time_for_arrival": "2024-10-03 08:54:28 UTC"
},
{
"id": "66fe5b595b85a4623a0bc420",
"order_id": "66fe5b585b85a4623a0bc416",
"idx": "1",
"estimated_time_for_arrival": "2024-10-03 08:52:40 UTC"
},
{
"id": "66fe5b5a5b85a4623a0bc423",
"order_id": "66fe5b3d5b85a43166f98776",
"idx": "2",
"estimated_time_for_arrival": "2024-10-03 08:59:28 UTC"
},
{
"id": "66fe5b595b85a4623a0bc421",
"order_id": "66fe5b585b85a4623a0bc416",
"idx": "2",
"estimated_time_for_arrival": "2024-10-03 08:57:40 UTC"
},
{
"id": "66fe5b5a5b85a4623a0bc424",
"order_id": "66fe4c405b85a43166f98762",
"idx": "3",
"estimated_time_for_arrival": "2024-10-03 09:04:28 UTC"
}
]
}