Failed delivery reasons
Introduction
If a delivery failed, a delivery failure reason is provided. This failure reason is available via the delivery webhook as well as the Get delivery endpoint
| Reason | Description |
|---|---|
| CANNOT_FIND_CUSTOMER | Customer could not be found by rider at delivery |
| LEFT_AT_SAFE_PLACE | Rider has left the cargo in a safe place |
| COLLECTING_DELIVERY | Issue happened while the rider is collecting the delivery |
| COMPLETING_DELIVERY | Issue happened while the rider is completing the delivery |
| DELIVERY_LOCATION_ISSUE | Rider failed to find the customer location |
| HANDOVER_CODE_MISMATCH | Handover code provided by customer does not match the expected value |
| ID_CHECK_FAILURE | Customer ID check was unsuccessful |
| INCIDENT | Delivery could not be completed by to an ongoing Deliveroo incident |
| UNEXPECTED_DELAY | Rider faced unforeseen delay in completing the delivery |
| VEHICLE_PROBLEMS | Rider faced vehicle issues (breakdown etc...) |
| CARGO_ISSUE | An issue with the cargo state has been reported (broken items etc ...) |
| UNKNOWN | No reason has been recorded for the failed delivery |
| OTHER | The failed delivery reason isn't covered by the existing options |
If a delivery is cancelled, a delivery cancellation reason is provided. This cancellation reason is available via the delivery webhook as well as the Get delivery endpoint
| Reason | Description |
|---|---|
| CANCELLED_AUTOMATICALLY | Delivery cancelled automatically by Deliveroo auto cancellation system as it has been alive but not active for too long |
| CANCELLED_BY_PARTNER | Delivery cancelled at partner's request |
| CANCELLED_PICKUP_ISSUE | Delivery cancelled automatically after repeated rider-reported pickup (collecting) issues |
Failed delivery & rider status update
Due to current technical limitations of the Deliveroo systems, a failed rider delivery is first marked as DELIVERED before the failure processing happens asynchronously.
This results in a failed delivery processing sending potentially 2 delivery update messages and 2 rider update messages via the webhook as follows :
First a DELIVERED message :
Delivery Update
{
"event": "delivery.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"status": {
"effective_at": "2025-02-20T14:15:31Z",
"status": "DELIVERED"
}
}
}Rider Update
{
"event": "riders.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"riders": [
{
"delivery_type": "MAIN",
"rider_id": "27a70a27-5b7e-48ca-af52-1b5f0bf83abc",
"status": {
"effective_at": "2025-02-20T14:15:31Z",
"status": "COMPLETED_DELIVERY"
}
}
]
}
}Followed by a UNFULFILLED message that updates the delivery status and provides the failure reason :
Delivery Update
{
"event": "delivery.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"status": {
"effective_at": "2025-02-20T14:15:43Z",
"reason": "VEHICLE_PROBLEMS",
"status": "UNFULFILLED"
}
}
}Rider Update
{
"event": "riders.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"riders": [
{
"delivery_type": "MAIN",
"rider_id": "27a70a27-5b7e-48ca-af52-1b5f0bf83abc",
"status": {
"effective_at": "2025-02-20T14:15:43Z",
"reason": "VEHICLE_PROBLEMS",
"status": "FAILED_DELIVERY"
}
}
]
}
}The effective_at timestamp of the UNFULFILLED message will always be greater than the DELIVERED one for the failed delivery.
[!WARNING]
This behaviour can be avoided by enabling the Delayed Webhooks Feature. When enabled, the initialDELIVEREDwebhook is suppressed and only the final accurate status (UNFULFILLED) is sent.
Left at safe place delivery & rider status update
If a rider can't reach the customer but is able to leave the delivery at safe place, a safe place reason will be provided
| Reason | Description |
|---|---|
| LEFT_AT_DOORSTEP | Rider can't reach customer but left delivery at doorstep |
| LEFT_AT_CONCIERGE | Rider can't reach customer but left delivery at concierge |
| LEFT_AT_FRONT_GARDEN | Rider can't reach customer but left delivery at front garden |
| LEFT_AT_NEIGHBOUR | Rider can't reach customer but left delivery at neighbour |
| LEFT_AT_RECEPTION | Rider can't reach customer but left delivery at reception |
| LEFT_AT_OTHER_LOCATION | Rider can't reach customer but left delivery at other location |
Due to current technical limitations of the Deliveroo systems, a left at safe place delivery is first marked as DELIVERED without a reason.
Another message will be sent where the reason is provided
This results in sending 2 delivery update messages and 2 rider update messages via the webhook as follows :
First a DELIVERED without reason message :
Delivery Update
{
"event": "delivery.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"status": {
"effective_at": "2025-02-20T14:15:31Z",
"status": "DELIVERED"
}
}
}Rider Update
{
"event": "riders.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"riders": [
{
"delivery_type": "MAIN",
"rider_id": "27a70a27-5b7e-48ca-af52-1b5f0bf83abc",
"status": {
"effective_at": "2025-02-20T14:15:31Z",
"status": "COMPLETED_DELIVERY"
}
}
]
}
}Followed by another message that adds the reason
Delivery Update
{
"event": "delivery.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"status": {
"effective_at": "2025-02-20T14:15:43Z",
"reason": "LEFT_AT_RECEPTION",
"status": "DELIVERED"
}
}
}Rider Update
{
"event": "riders.update_status",
"body": {
"delivery_id": "3ed26a29-5a66-402b-bb9e-55d34781be3d",
"external_ref_id": "f6fccb39-587a-4d99-af2f-676baa7df952",
"riders": [
{
"delivery_type": "MAIN",
"rider_id": "27a70a27-5b7e-48ca-af52-1b5f0bf83abc",
"status": {
"effective_at": "2025-02-20T14:15:43Z",
"reason": "LEFT_AT_RECEPTION",
"status": "COMPLETED_DELIVERY"
}
}
]
}
}The effective_at timestamp of the DELIVERED with reason message will always be greater than the DELIVERED without a reason message.
Updated 17 days ago
