Skip to main content

Bulk Operations

5 API calls in this section.

Validate Bulk Action

Delivery & Last-Mile / Bulk Operations
POST/delivery/bulk/validate

Pre-flight check: validates whether each order is eligible for the requested action without making any changes. action_id values: - mark_pending — params: reason (optional) - assign_driver — params: driver_id (required). Each delivery is also checked against the driver's allowed zones at execute time; deliveries outside the driver's zones fail with driver_not_allowed_in_pickup_zone / driver_not_allowed_in_delivery_zone. - mark_picked_up — params: none. Requires an active assignment/driver on every delivery. - mark_in_transit — params: none. Requires an active assignment/driver on every delivery. - mark_delivered — params: none. Requires an active assignment/driver on every delivery. - mark_staged_at_warehouse — params: driver_id (optional, required when any inbound child has no active assignment). Children outside the driver's zones are rejected per-row. - cancel_orders — params: reason (required) - mark_returned — params: none - reassign_driver — params: driver_id (required). Same zone check as assign_driver. Also supports deliveries that were self-unassigned after pickup or in transit; the new driver continues from the current delivery progress. - unassign — params: reason (optional) - assign_to_route — params: route_id (required) Max 500 order_codes per request.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request POST "$ONDI_BASE_URL/delivery/bulk/validate" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "order_codes": [7    "1865",8    "1853"9  ],10  "action_id": "assign_driver",11  "params": {12    "driver_id": "uuid-of-driver"13  }14}'
Request body
json
1{2  "order_codes": [3    "1865",4    "1853"5  ],6  "action_id": "assign_driver",7  "params": {8    "driver_id": "uuid-of-driver"9  }10}

Request body fields

order_codesExample
array<string>

Example field from the request body.

action_idExample
string

Example field from the request body.

paramsExample
object

Example field from the request body.

params.driver_idExample
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": "Validation completed",4  "data": {5    "results": [6      {7        "order_code": "1865",8        "valid": true9      },10      {11        "order_code": "1853",12        "valid": false,13        "error_message": "Order status does not allow this action"14      }15    ],16    "total_valid": 1,17    "total_failed": 118  }19}

Execute Bulk Action

Delivery & Last-Mile / Bulk Operations
POST/delivery/bulk/execute

Execute the bulk action on the given orders. Re-validates each order at execution time (optimistic concurrency). Orders that fail re-validation are skipped and reported in results. Same request body as validate. Each order is processed in a single batched DB round-trip. Driver progress actions (mark_picked_up, mark_in_transit, mark_delivered): - Every delivery must still have an active assignment. If the driver self-unassigned, these actions fail with bulk_no_active_assignment until the delivery is reassigned. Driver-assignment actions (assign_driver, reassign_driver, and mark_staged_at_warehouse when creating new assignments): - All target deliveries are validated against the driver's allowed zones in O(1) DB calls. Per-delivery failures (driver_not_allowed_in_pickup_zone, driver_not_allowed_in_delivery_zone) are returned alongside successes; eligible deliveries still proceed. - reassign_driver also supports deliveries that were self-unassigned after pickup or in transit. A fresh assignment row is created for the new driver and the delivery keeps its current progress status. - Inserted assignments share a single bulk_assignment_id so the per-row realtime trigger is suppressed; the API emits one consolidated realtime row and one bulk_delivery_assigned notification.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request POST "$ONDI_BASE_URL/delivery/bulk/execute" \2  --header "Authorization: Bearer {{access_token}}" \3  --header "Content-Type: application/json" \4  --header "Content-Type: application/json" \5  --data '{6  "order_codes": [7    "1865",8    "1853"9  ],10  "action_id": "assign_driver",11  "params": {12    "driver_id": "uuid-of-driver"13  }14}'
Request body
json
1{2  "order_codes": [3    "1865",4    "1853"5  ],6  "action_id": "assign_driver",7  "params": {8    "driver_id": "uuid-of-driver"9  }10}

Request body fields

order_codesExample
array<string>

Example field from the request body.

action_idExample
string

Example field from the request body.

paramsExample
object

Example field from the request body.

params.driver_idExample
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": "Bulk operation completed",4  "data": {5    "results": [6      {7        "order_code": "1865",8        "success": true9      },10      {11        "order_code": "1853",12        "success": false,13        "error_message": "Order status does not allow this action"14      }15    ],16    "total_success": 1,17    "total_failed": 118  }19}
Partial — driver outside zone200OK
Response body
json
1{2  "success": true,3  "message": "Bulk operation completed",4  "data": {5    "results": [6      {7        "order_code": "1865",8        "success": true9      },10      {11        "order_code": "1853",12        "success": false,13        "error_message": "Driver is not allowed to operate in the pickup zone"14      }15    ],16    "total_success": 1,17    "total_failed": 118  }19}

Search Orders

Delivery & Last-Mile / Bulk Operations
GET/delivery/orders/search?q=1865

Autocomplete search for the bulk operations order picker. Searches by delivery_code or customer name. Returns up to 20 results scoped to the authenticated tenant.

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

Query parameters

qOptional
query string

1865

Search query — matches delivery_code (prefix) or customer name (partial). Min 1 character.

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Orders retrieved successfully",4  "data": [5    {6      "id": "uuid",7      "delivery_code": 1865,8      "customer_name": "John Doe",9      "status": "pending",10      "address": "123 Main St",11      "unit_size": 112    }13  ]14}

Bulk Print — Shipping Labels

Delivery & Last-Mile / Bulk Operations
GET/delivery/bulk/print?order_codes[]=1865&order_codes[]=1853&type=shipping_label

Returns shipment_label_url from each delivery record. If not generated yet, url is null with a message. Frontend handles opening/printing.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/bulk/print?order_codes[]=1865&order_codes[]=1853&type=shipping_label" \2  --header "Authorization: Bearer {{access_token}}"

Query parameters

order_codes[]Optional
query string

1865

Order code

order_codes[]Optional
query string

1853

Order code

typeOptional
query string

shipping_label

shipping_label | receipt

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Print data retrieved successfully",4  "data": {5    "type": "shipping_label",6    "results": [7      {8        "order_code": "1865",9        "url": "https://label-url...",10        "status": "generated"11      },12      {13        "order_code": "1853",14        "url": null,15        "status": "pending",16        "message": "label_not_generated"17      }18    ]19  }20}

Bulk Print — Receipts

Delivery & Last-Mile / Bulk Operations
GET/delivery/bulk/print?order_codes[]=1865&order_codes[]=1853&type=receipt

Returns signed receipt URLs from the payments table (receipt_storage_path). Receipt must have been generated by the payment receipt job (receipt_status = success). If not ready, url is null with message receipt_not_ready. Signed URLs expire after 1 hour.

Send a bearer token in the Authorization header for an authenticated OnDi user session.
Request
curl
1curl --request GET "$ONDI_BASE_URL/delivery/bulk/print?order_codes[]=1865&order_codes[]=1853&type=receipt" \2  --header "Authorization: Bearer {{access_token}}"

Query parameters

order_codes[]Optional
query string

1865

Order code

order_codes[]Optional
query string

1853

Order code

typeOptional
query string

receipt

shipping_label | receipt

Headers

AuthorizationOptional
header string

Bearer {{access_token}}

Responses

Success200OK
Response body
json
1{2  "success": true,3  "message": "Print data retrieved successfully",4  "data": {5    "type": "receipt",6    "results": [7      {8        "order_code": "1865",9        "url": "https://signed-url...",10        "receipt_generated_at": "2026-04-06T18:14:20Z"11      },12      {13        "order_code": "1853",14        "url": null,15        "message": "receipt_not_ready"16      }17    ]18  }19}