Skip to main content

Trips

12 API calls in this section.

List Trips

Delivery & Last-Mile / Trips
GET/delivery/trips?page=1&limit=20&status=planned&driver_id=&trip_type=&trip_number=&from_date=&to_date=&sort_by=created_at&sort_order=desc&column_filters=

List trips with optional filters, column-level filters, sorting, and pagination. Returns item_count per trip.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/trips?page=1&limit=20&status=planned&driver_id=&trip_type=&trip_number=&from_date=&to_date=&sort_by=created_at&sort_order=desc&column_filters=" \2  --header "Authorization: Bearer {{access_token}}"

Query parameters

pageOptional
query string

1

Page number

limitOptional
query string

20

Items per page (max 100)

statusOptional
query string

planned

Filter by status: planned, in_progress, completed, cancelled

driver_idOptional
query string

Filter by driver UUID

trip_typeOptional
query string

Filter by type: multi_pickup, multi_dropoff, mixed

trip_numberOptional
query string

Search by trip number (partial)

from_dateOptional
query string

Start date YYYY-MM-DD (normalized to 00:00:00)

to_dateOptional
query string

End date YYYY-MM-DD (normalized to 23:59:59)

sort_byOptional
query string

created_at

Sort by: trip_number, status, trip_type, notes, created_at, updated_at, started_at, completed_at

sort_orderOptional
query string

desc

Sort order: asc or desc

column_filtersOptional
query string

JSON object. Supported keys: trip_number, status, trip_type, driver_id, vehicle_id, notes, created_at, updated_at, started_at, completed_at. Date keys accept {"from":"...","to":"..."}.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trips retrieved successfully",4  "data": {5    "trips": [6      {7        "id": "trip-uuid",8        "trip_number": "TRIP-00001",9        "status": "planned",10        "trip_type": "multi_pickup",11        "notes": "Morning run",12        "started_at": null,13        "completed_at": null,14        "created_at": "2026-04-11T10:00:00Z",15        "updated_at": "2026-04-11T10:00:00Z",16        "item_count": 3,17        "driver": {18          "id": "driver-uuid",19          "full_name": "Ahmed Hassan",20          "phone": "+9647501234567"21        },22        "vehicle": {23          "id": "vehicle-uuid",24          "name": "Toyota Hiace",25          "code": "VH-001"26        }27      }28    ],29    "total": 1,30    "page": 1,31    "limit": 2032  }33}

Create Trip

Delivery & Last-Mile / Trips
POST/delivery/trips

Create a new trip. All fields are optional at creation. Deliveries can be attached at creation time or added later. - trip_type: multi_pickup | multi_dropoff | mixed (optional, informational) - deliveries: optional array of {delivery_id, sequence?}. Sequence auto-assigned if not provided. - Eligible delivery statuses: draft, pending, assigned, staged_at_warehouse - Hybrid parent deliveries are rejected

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request POST "$ONDI_BASE_URL/delivery/trips" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "driver_id": "driver-uuid",7  "vehicle_id": "vehicle-uuid",8  "trip_type": "multi_pickup",9  "notes": "Morning delivery run",10  "deliveries": [11    {12      "delivery_id": "delivery-uuid-1",13      "sequence": 114    },15    {16      "delivery_id": "delivery-uuid-2",17      "sequence": 218    }19  ]20}'
Request body
json
1{2  "driver_id": "driver-uuid",3  "vehicle_id": "vehicle-uuid",4  "trip_type": "multi_pickup",5  "notes": "Morning delivery run",6  "deliveries": [7    {8      "delivery_id": "delivery-uuid-1",9      "sequence": 110    },11    {12      "delivery_id": "delivery-uuid-2",13      "sequence": 214    }15  ]16}

Request body fields

driver_idExample
string

Example field from the request body.

vehicle_idExample
string

Example field from the request body.

trip_typeExample
string

Example field from the request body.

notesExample
string

Example field from the request body.

deliveriesExample
array<object>

Example field from the request body.

deliveries.delivery_idExample
string

Example field from the request body.

deliveries.sequenceExample
number

Example field from the request body.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Content-TypeOptional
header string

application/json

Responses

Success201Created
Response body
json
1{2  "success": true,3  "message": "Trip created successfully",4  "data": {5    "id": "trip-uuid",6    "trip_number": "TRIP-00001",7    "status": "planned",8    "trip_type": "multi_pickup",9    "notes": "Morning delivery run",10    "driver": {11      "id": "driver-uuid",12      "full_name": "Ahmed Hassan",13      "phone": "+9647501234567"14    },15    "vehicle": {16      "id": "vehicle-uuid",17      "name": "Toyota Hiace",18      "code": "VH-001"19    },20    "deliveries": [21      {22        "id": "delivery-uuid-1",23        "delivery_code": 1001,24        "barcode": "BC001",25        "status": "pending",26        "trip_sequence": 127      },28      {29        "id": "delivery-uuid-2",30        "delivery_code": 1002,31        "barcode": "BC002",32        "status": "pending",33        "trip_sequence": 234      }35    ],36    "summary": {37      "total": 2,38      "planned": 2,39      "in_progress": 0,40      "delivered": 0,41      "returned": 0,42      "cancelled": 0,43      "with_return_request": 044    },45    "driver_execution": {46      "stop_list": [47        {48          "stop_type": "pickup",49          "location": {50            "latitude": 33.3,51            "longitude": 44.452          },53          "deliveries": [54            {55              "delivery_id": "delivery-uuid-1",56              "delivery_code": 1001,57              "barcode": "BC001",58              "status": "pending",59              "trip_sequence": 160            }61          ],62          "is_complete": false63        }64      ],65      "current_stop": {66        "stop_type": "pickup",67        "location": {},68        "deliveries": []69      },70      "next_stop": null71    }72  }73}
Delivery not eligible409Conflict
Response body
json
1{2  "success": false,3  "message": "Delivery is not eligible to be added to a trip",4  "data": null5}

Get Trip Detail

Delivery & Last-Mile / Trips
GET/delivery/trips/{{trip_id}}

Get full trip detail including: - Trip header (number, status, type, notes) - Driver and vehicle info - Ordered deliveries (sorted by trip_sequence) - Summary counts (total, per-status) - driver_execution: stop_list grouped by shared pickup/dropoff location, current_stop, next_stop The driver_execution field is what the driver app uses. It groups deliveries that share the same pickup/dropoff into one stop so the driver does not do unnecessary back-and-forth.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/trips/{{trip_id}}" \2  --header "Authorization: Bearer {{access_token}}"

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip retrieved successfully",4  "data": {5    "id": "trip-uuid",6    "trip_number": "TRIP-00001",7    "status": "in_progress",8    "trip_type": "mixed",9    "notes": "Morning run",10    "started_at": "2026-04-11T08:00:00Z",11    "completed_at": null,12    "created_at": "2026-04-11T07:00:00Z",13    "updated_at": "2026-04-11T08:00:00Z",14    "driver": {15      "id": "driver-uuid",16      "full_name": "Ahmed Hassan",17      "phone": "+9647501234567",18      "avatar_url": null19    },20    "vehicle": {21      "id": "vehicle-uuid",22      "name": "Toyota Hiace",23      "code": "VH-001"24    },25    "deliveries": [26      {27        "id": "d1",28        "delivery_code": 1001,29        "barcode": "BC001",30        "status": "picked_up",31        "trip_sequence": 1,32        "pickup_location": {33          "latitude": 33.3,34          "longitude": 44.435        },36        "dropoff_location": {37          "latitude": 33.5,38          "longitude": 44.639        },40        "payment_method": "cod",41        "cod_amount": 15000,42        "unit_size": 1,43        "return_requests": []44      },45      {46        "id": "d2",47        "delivery_code": 1002,48        "barcode": "BC002",49        "status": "pending",50        "trip_sequence": 2,51        "pickup_location": {52          "latitude": 33.3,53          "longitude": 44.454        },55        "dropoff_location": {56          "latitude": 33.6,57          "longitude": 44.758        },59        "payment_method": "prepaid",60        "cod_amount": 0,61        "unit_size": 1,62        "return_requests": []63      }64    ],65    "summary": {66      "total": 2,67      "planned": 1,68      "in_progress": 1,69      "delivered": 0,70      "returned": 0,71      "cancelled": 0,72      "with_return_request": 073    },74    "driver_execution": {75      "stop_list": [76        {77          "stop_type": "pickup",78          "location": {79            "latitude": 33.3,80            "longitude": 44.481          },82          "deliveries": [83            {84              "delivery_id": "d1",85              "delivery_code": 1001,86              "status": "picked_up",87              "trip_sequence": 188            },89            {90              "delivery_id": "d2",91              "delivery_code": 1002,92              "status": "pending",93              "trip_sequence": 294            }95          ],96          "is_complete": false97        },98        {99          "stop_type": "dropoff",100          "location": {101            "latitude": 33.5,102            "longitude": 44.6103          },104          "deliveries": [105            {106              "delivery_id": "d1",107              "delivery_code": 1001,108              "status": "picked_up",109              "trip_sequence": 1110            }111          ],112          "is_complete": false113        },114        {115          "stop_type": "dropoff",116          "location": {117            "latitude": 33.6,118            "longitude": 44.7119          },120          "deliveries": [121            {122              "delivery_id": "d2",123              "delivery_code": 1002,124              "status": "pending",125              "trip_sequence": 2126            }127          ],128          "is_complete": false129        }130      ],131      "current_stop": {132        "stop_type": "pickup",133        "location": {134          "latitude": 33.3,135          "longitude": 44.4136        },137        "is_complete": false138      },139      "next_stop": {140        "stop_type": "dropoff",141        "location": {142          "latitude": 33.5,143          "longitude": 44.6144        },145        "is_complete": false146      }147    }148  }149}
Not Found404Not Found
Response body
json
1{2  "success": false,3  "message": "Trip not found",4  "data": null5}

Update Trip

Delivery & Last-Mile / Trips
PATCH/delivery/trips/{{trip_id}}

Update trip metadata. Only allowed while trip is planned. All fields are optional — only include the fields you want to change. Pass null to clear driver_id, vehicle_id, or trip_type.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request PATCH "$ONDI_BASE_URL/delivery/trips/{{trip_id}}" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "driver_id": "new-driver-uuid",7  "vehicle_id": "new-vehicle-uuid",8  "trip_type": "multi_dropoff",9  "notes": "Updated notes"10}'
Request body
json
1{2  "driver_id": "new-driver-uuid",3  "vehicle_id": "new-vehicle-uuid",4  "trip_type": "multi_dropoff",5  "notes": "Updated notes"6}

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Request body fields

driver_idExample
string

Example field from the request body.

vehicle_idExample
string

Example field from the request body.

trip_typeExample
string

Example field from the request body.

notesExample
string

Example field from the request body.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Content-TypeOptional
header string

application/json

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip updated successfully",4  "data": {5    "id": "trip-uuid",6    "status": "planned"7  }8}
Not in planned status409Conflict
Response body
json
1{2  "success": false,3  "message": "Trip cannot be edited in its current status",4  "data": null5}

List Eligible Deliveries for Trip

Delivery & Last-Mile / Trips
GET/delivery/trips/eligible-deliveries?page=1&limit=20&search=&tenant_id=&language=en

Returns deliveries that can be added to a trip. Eligibility rules: - Status is one of: draft, pending, assigned, staged_at_warehouse - Not deleted - Not a hybrid parent delivery - Not already assigned to a trip (trip_id is null) Supports search by barcode or external_reference_id.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/trips/eligible-deliveries?page=1&limit=20&search=&tenant_id=&language=en" \2  --header "Authorization: Bearer {{access_token}}"

Query parameters

pageOptional
query string

1

Page number

limitOptional
query string

20

Items per page (max 100)

searchOptional
query string

Search by barcode or external_reference_id

tenant_idOptional
query string

Tenant ID

languageOptional
query string

en

Language

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Eligible deliveries retrieved successfully",4  "data": [5    {6      "id": "delivery-uuid-1",7      "delivery_code": 1001,8      "barcode": "BC001",9      "status": "pending",10      "external_reference_id": null,11      "payment_method": "cod",12      "cod_amount": 15000,13      "unit_size": 1,14      "pickup_location": {15        "latitude": 33.3,16        "longitude": 44.417      },18      "delivery_location": {19        "latitude": 33.5,20        "longitude": 44.621      },22      "pickup_warehouse": {23        "id": "wh-uuid",24        "name": "Main WH",25        "code": "WH01"26      },27      "dropoff_warehouse": null,28      "pickup_zone": {29        "id": "zone-uuid",30        "name": "Zone A",31        "code": "ZA"32      },33      "dropoff_zone": null34    }35  ],36  "total": 5,37  "page": 1,38  "limit": 2039}

Sync Trip Deliveries

Delivery & Last-Mile / Trips
POST/delivery/trips/{{trip_id}}/deliveries

Sync the full delivery membership of a trip. Only allowed while trip is planned. This is a replace operation — the array sent becomes the exact set of deliveries on the trip: - Deliveries in the array are attached/updated with the given sequence - Deliveries currently in the trip but absent from the array are detached (trip_id cleared) - sequence is optional; if omitted, position index (1-based) is used - Send an empty array [] to detach all deliveries from the trip Eligibility rules for incoming deliveries: - Status: draft, pending, assigned, staged_at_warehouse - Not deleted, not a hybrid parent - Not assigned to a different trip

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request POST "$ONDI_BASE_URL/delivery/trips/{{trip_id}}/deliveries" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "deliveries": [7    {8      "delivery_id": "delivery-uuid-1",9      "sequence": 110    },11    {12      "delivery_id": "delivery-uuid-3",13      "sequence": 214    },15    {16      "delivery_id": "delivery-uuid-4",17      "sequence": 318    }19  ]20}'
Request body
json
1{2  "deliveries": [3    {4      "delivery_id": "delivery-uuid-1",5      "sequence": 16    },7    {8      "delivery_id": "delivery-uuid-3",9      "sequence": 210    },11    {12      "delivery_id": "delivery-uuid-4",13      "sequence": 314    }15  ]16}

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Request body fields

deliveriesExample
array<object>

Example field from the request body.

deliveries.delivery_idExample
string

Example field from the request body.

deliveries.sequenceExample
number

Example field from the request body.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Content-TypeOptional
header string

application/json

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip deliveries synced successfully",4  "data": {5    "id": "trip-uuid",6    "summary": {7      "total": 38    }9  }10}
Delivery already in another trip409Conflict
Response body
json
1{2  "success": false,3  "message": "Delivery is already assigned to another trip",4  "data": null5}

Remove Delivery from Trip

Delivery & Last-Mile / Trips
DELETE/delivery/trips/{{trip_id}}/deliveries/{{delivery_id}}

Remove a delivery from the trip. Only allowed while trip is planned. Clears trip_id and trip_sequence on the delivery row. Does not delete the delivery.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request DELETE "$ONDI_BASE_URL/delivery/trips/{{trip_id}}/deliveries/{{delivery_id}}" \2  --header "Authorization: Bearer {{access_token}}"

Path parameters

trip_idRequired
path string

Variable used inside the request path.

delivery_idRequired
path string

Variable used inside the request path.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Delivery removed from trip successfully",4  "data": {5    "id": "trip-uuid",6    "summary": {7      "total": 18    }9  }10}

Reorder Trip Deliveries

Delivery & Last-Mile / Trips
PATCH/delivery/trips/{{trip_id}}/reorder

Reorder deliveries in the trip by providing all delivery IDs in the desired order. - Must include all current trip deliveries — no missing, no extra - trip_sequence will be reassigned as 1, 2, 3... - Only allowed while trip is planned - The driver_execution.stop_list in the detail response will reflect the new order

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request PATCH "$ONDI_BASE_URL/delivery/trips/{{trip_id}}/reorder" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "delivery_ids": [7    "delivery-uuid-2",8    "delivery-uuid-1",9    "delivery-uuid-3"10  ]11}'
Request body
json
1{2  "delivery_ids": [3    "delivery-uuid-2",4    "delivery-uuid-1",5    "delivery-uuid-3"6  ]7}

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Request body fields

delivery_idsExample
array<string>

Example field from the request body.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Content-TypeOptional
header string

application/json

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip stop order updated successfully",4  "data": {5    "id": "trip-uuid",6    "status": "planned"7  }8}
Membership mismatch409Conflict
Response body
json
1{2  "success": false,3  "message": "Reorder list must contain all trip deliveries — no more, no less",4  "data": null5}

Cancel Trip

Delivery & Last-Mile / Trips
POST/delivery/trips/{{trip_id}}/cancel

Cancel a trip. Only allowed while trip is planned. Sets trip status to cancelled. Preserves delivery linkage for audit purposes (trip_id and trip_sequence stay on deliveries, but the trip status clearly indicates the plan was cancelled).

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request POST "$ONDI_BASE_URL/delivery/trips/{{trip_id}}/cancel" \2  --header "Authorization: Bearer {{access_token}}"

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip cancelled successfully",4  "data": {5    "id": "trip-uuid",6    "status": "cancelled"7  }8}
Not cancellable409Conflict
Response body
json
1{2  "success": false,3  "message": "Trip cannot be cancelled in its current status",4  "data": null5}

Driver: List My Trips

Delivery & Last-Mile / Trips
GET/delivery/driver-trips?page=1&per_page=20&status=in_progress

Driver-facing: list trips assigned to the authenticated driver. Driver sees trip_number, status, item_count, and timestamps. They can then call GET /delivery/trips/:id to get the full stop list for execution.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/driver-trips?page=1&per_page=20&status=in_progress" \2  --header "Authorization: Bearer {{access_token}}"

Query parameters

pageOptional
query string

1

Page number

per_pageOptional
query string

20

Items per page

statusOptional
query string

in_progress

Filter by status

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trips retrieved successfully",4  "data": {5    "trips": [6      {7        "id": "trip-uuid",8        "trip_number": "TRIP-00001",9        "status": "in_progress",10        "trip_type": "multi_pickup",11        "item_count": 3,12        "started_at": "2026-04-11T08:00:00Z",13        "completed_at": null14      }15    ],16    "total": 1,17    "page": 1,18    "per_page": 2019  }20}

Get Trip Partial Returns

Delivery & Last-Mile / Trips
GET/delivery/trips/{{trip_id}}/returns

Convenience endpoint — returns only the deliveries in this trip that have one or more return requests. Useful for a focused 'returns' tab on the trip detail screen without loading the full trip payload. Each item includes: - delivery_id, delivery_code, barcode, delivery_status, return_status, trip_sequence - return_requests array with id, status, return_reason, return_delivery_id, requested_at, notes Note: return requests are created via the existing POST /delivery/returns endpoint — no new endpoint needed for creation.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/trips/{{trip_id}}/returns" \2  --header "Authorization: Bearer {{access_token}}"

Path parameters

trip_idRequired
path string

Variable used inside the request path.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success — with returns200OK
Response body
json
1{2  "success": true,3  "message": "Trip returns retrieved successfully",4  "data": [5    {6      "delivery_id": "uuid-d2",7      "delivery_code": 1002,8      "barcode": "BC002",9      "delivery_status": "returned",10      "return_status": "return_approved",11      "trip_sequence": 2,12      "return_requests": [13        {14          "id": "rr-uuid",15          "status": "approved",16          "return_reason": "Customer refused delivery",17          "return_delivery_id": "uuid-return-delivery",18          "requested_at": "2026-04-11T10:30:00Z",19          "notes": null20        }21      ]22    },23    {24      "delivery_id": "uuid-d5",25      "delivery_code": 1005,26      "barcode": "BC005",27      "delivery_status": "returned",28      "return_status": "return_requested",29      "trip_sequence": 5,30      "return_requests": [31        {32          "id": "rr-uuid-2",33          "status": "pending",34          "return_reason": "Wrong address",35          "return_delivery_id": null,36          "requested_at": "2026-04-11T11:00:00Z",37          "notes": null38        }39      ]40    }41  ]42}
Success — no returns yet200OK
Response body
json
1{2  "success": true,3  "message": "Trip returns retrieved successfully",4  "data": []5}
Trip not found404Not Found
Response body
json
1{2  "success": false,3  "message": "Trip not found",4  "data": null5}

Driver: Trip Status Summary

Delivery & Last-Mile / Trips
GET/delivery/driver-trips/status-summary

Driver-facing: returns count of trips per status for the authenticated driver.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/driver-trips/status-summary" \2  --header "Authorization: Bearer {{access_token}}"

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Trip status summary retrieved successfully",4  "data": {5    "planned": 2,6    "in_progress": 1,7    "completed": 15,8    "cancelled": 09  }10}