Skip to main content

Orders

5 API calls in this section.

Create Order​

Customer Portal / Delivery Management / Orders
POST/customer/delivery/orders

Creates a delivery order from the authenticated customer portal. When tenant setting delivery_external_reference.unique_per_customer=true (default), a non-empty external_reference_id must be unique among this customer root orders; duplicates return HTTP 400 external_reference_id_already_exists. When false, duplicates are allowed. The backend enforces customer_id from the access token and calculates unit size from package dimensions.

Package contract

  • Single package: send package.weight, package.length, package.width, and package.height. These values are stored at the top level of deliveries.package_details and used to calculate unit_size.

  • Multipart shipment: send package.items[]. Each item is persisted in delivery_package_items; deliveries.package_details is rebuilt as the item/totals/status-summary object.

  • Package details are optional; when no usable measurements exist, general.unit_size.settings.missing_unit_size_fallback selects service minimum, half of service maximum, service maximum, or rejects the request.

  • Optional is_draft=true creates the order as Draft; it may be sent in the JSON body or as ?is_draft=true. Missing or false preserves the current Pending behavior. For a wallet-paid draft, the fee moves from usable balance to reserved without creating a wallet transaction or payment. Execute captures the reservation and creates the delivery-fee transaction; cancelling the draft releases it back to usable balance. Draft orders do not queue driver assignment until Execute.

Warehouse staging

  • The frontend does not send requires_warehouse_staging or staging_warehouse_id.

  • The backend resolves the selected delivery service's effective warehouse policy.

  • When warehouse_policies.pickup_delivery_required=true, the backend selects the configured default staging warehouse or applies staging_selection_strategy.

  • A staged order creates a parent delivery and two child legs: pickup to warehouse, then warehouse to delivery.

  • When package.items is absent or empty, the backend creates one fallback warehouse inventory item named from the delivery code and customer name; it uses package.weight when supplied.

  • Staged P&D database persistence is atomic: the parent, A/B legs, package items, inventory items, receiving order, and sequence plan either all commit or all roll back. Automatically allocated inventory item codes skip codes already claimed manually.

Payment

Use payment.method_id (UUID from GET /customer/delivery/payment-methods).

  • Wallet: method_id = wallet UUID. Pending orders charge immediately. Draft orders reserve first and charge only when executed.

  • COD/cash: method_id = cod UUID. payment.cod_amount is optional goods COD money; omit it or send 0 for fee-only orders. Positive values remain independent from the delivery fee and must fit tenant COD min/max settings.

  • Gateway (e.g. Nass): method_id = gateway UUID, back_ref REQUIRED (return URL).

Frontend integration contract

  • For a single package, submit package dimensions directly and do not create an item row.

  • For multipart, submit package.items; its item summary replaces the direct package-details shape.

  • Do not require COD amount for fee-only orders. Omit payment.cod_amount or send numeric 0; do not submit an empty string.

  • Do not prompt for or submit a staging warehouse.

  • Use data.order.id as the parent order ID and data.children for staged leg details.

  • Handle HTTP 400 for non-delivery service types, unresolved warehouse, ambiguous warehouse selection, unavailable route segments, invalid payment method, or invalid positive COD amount.

  • Default the create-as-draft checkbox to false. The backend accepts either body is_draft: true or query ?is_draft=true. Dispatcher Execute should call POST /delivery/deliveries/:deliveryId/status with { "target_delivery_status": "pending" }.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
pickupobject—
pickup.locationobject—
pickup.location.full_addressstring—
pickup.location.latitudenumber—
pickup.location.longitudenumber—
pickup.location.countrystring—
pickup.location.citystring—
pickup.location.statestring—
pickup.location.postal_codestring—
pickup.location.contact_infoobject—
pickup.location.contact_info.namestring—
pickup.location.contact_info.phonestring—
Show 31 more body fields

Additional body parameters

ParameterTypeDescription
pickup.scheduled_pickup_timestring—
dropoffobject—
dropoff.locationobject—
dropoff.location.full_addressstring—
dropoff.location.latitudenumber—
dropoff.location.longitudenumber—
dropoff.location.countrystring—
dropoff.location.citystring—
dropoff.location.statestring—
dropoff.location.postal_codestring—
dropoff.location.contact_infoobject—
dropoff.location.contact_info.namestring—
dropoff.location.contact_info.phonestring—
dropoff.scheduled_delivery_timestring—
delivery_service_idstring—
payer_typestring—
paymentobject—
payment.method_idstring—
external_reference_idstring—
is_draftboolean—
notesstring—
special_instructionsstring—
packageobject—
package.itemsarray<object>—
package.items.namestring—
package.items.quantitynumber—
package.items.descriptionstring—
package.items.weightnumber—
package.items.lengthnumber—
package.items.widthnumber—
package.items.heightnumber—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/customer/delivery/orders" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "pickup": {6    "location": {7      "full_address": "123 Main St, New York, NY 10001, US",8      "latitude": 40.7128,9      "longitude": -74.006,10      "country": "US",11      "city": "New York",12      "state": "NY",13      "postal_code": "10001",14      "contact_info": {15        "name": "John Doe",16        "phone": "+1234567890"17      }18    },19    "scheduled_pickup_time": "2026-02-05T10:00:00Z"20  },21  "dropoff": {22    "location": {23      "full_address": "456 Oak Ave, Brooklyn, NY 11201, US",24      "latitude": 40.7589,25      "longitude": -73.9851,26      "country": "US",27      "city": "Brooklyn",28      "state": "NY",29      "postal_code": "11201",30      "contact_info": {31        "name": "Jane Smith",32        "phone": "+1987654321"33      }34    },35    "scheduled_delivery_time": "2026-02-05T14:00:00Z"36  },37  "delivery_service_id": "uuid",38  "payer_type": "sender",39  "payment": {40    "method_id": "0760f75f-4aee-4776-afc0-4057d7ad458f"41  },42  "external_reference_id": "ORD-12345",43  "is_draft": false,44  "notes": "Handle with care",45  "special_instructions": "Fragile items",46  "package": {47    "items": [48      {49        "name": "Product A",50        "quantity": 2,51        "description": "Electronics",52        "weight": 1.5,53        "length": 30,54        "width": 20,55        "height": 1556      },57      {58        "name": "Product B",59        "quantity": 1,60        "description": "Clothing",61        "weight": 0.5,62        "length": 25,63        "width": 15,64        "height": 1065      }66    ]67  }68}'

Response examples

400Bad Request
Response body
json
1{2  "success": false,3  "code": "invalid_payer_type",4  "message": "Invalid payer type",5  "field": "payer_type"6}

List Orders​

Customer Portal / Delivery Management / Orders
GET/customer/delivery/orders

Lists the authenticated customer's delivery orders with filters and pagination. Every row includes compact pickup.location and dropoff.location objects containing the nullable localized title map and full_address; existing from and to strings remain unchanged. Every row also includes the nullable relationship fields return_delivery_id, return_delivery_code, original_delivery_id, and original_delivery_code. An original delivery populates the return_delivery_* pair; a return delivery populates the original_delivery_* pair. The values come from the maintained delivery projection, so this list performs no per-row return lookup or join. return_eligible is true only for a delivered order without an existing return relationship. For a linked operational return, the original/P&D parent has literal status=returning only after physical pickup or in-transit starts; assignment alone keeps it staged_at_warehouse.

Query parameters

ParameterTypeDescription
pagestring

Page number (>=1)

Example: 1

limitstring

Items per page (1-50)

Example: 10

statusstring

Filter by status

Example: pending

payment_methodOptionalstring

Filter by payment method (wallet/cod)

payment_statusOptionalstring

Filter by payment status: pending, paid, failed, or refunded

payer_typeOptionalstring

Filter by payer type: sender | receiver

start_dateOptionalstring

Start date filter (ISO format)

end_dateOptionalstring

End date filter (ISO format)

searchOptionalstring

Search by delivery code or reference

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/customer/delivery/orders?page=1&limit=10&status=pending" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "data": {4    "orders": [5      {6        "id": "delivery-uuid",7        "source_transfer_manifest_id": "manifest-uuid"8      }9    ],10    "pagination": {11      "page": 1,12      "limit": 10,13      "total": 114    }15  }16}

Export Orders (CSV)​

Customer Portal / Delivery Management / Orders
GET/customer/delivery/orders/export

Streams a CSV export of the customer's orders using the same filters as List Orders. Supports realtime progress (stream) and abort by canceling the HTTP request.

Response headers

  • Content-Disposition (filename)

  • X-Total-Rows (for progress)

  • X-Export-Tenant-Id

  • X-Export-Customer-Id

text/csv

Query parameters

ParameterTypeDescription
statusOptionalstring

Filter by status

Example: pending

debugOptionalstring

Debug mode (local/dev only; returns JSON with counts instead of CSV)

Example: 1

payment_methodOptionalstring

Filter by payment method

payment_statusOptionalstring

Filter by payment status: pending, paid, failed, or refunded

payer_typeOptionalstring

Filter by payer type: sender | receiver

start_dateOptionalstring

Start date (YYYY-MM-DD or ISO)

Example: 2026-03-01

end_dateOptionalstring

End date (YYYY-MM-DD or ISO)

Example: 2026-03-03

searchOptionalstring

Search by delivery code/reference

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/customer/delivery/orders/export?status=pending&start_date=2026-03-01&end_date=2026-03-03" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

No saved response example. Use Try it to inspect a staging response.

Get Order​

Customer Portal / Delivery Management / Orders
GET/customer/delivery/orders/:id

Gets full order details for a delivery owned by the authenticated customer. data.order.notes and data.order.special_instructions are separate nullable fields; when a package snapshot is present, data.order.package.special_instructions contains the same handling instructions saved from the create request. data.order.pickup.location.title and data.order.dropoff.location.title contain the nullable localized title map captured in each historical delivery-location snapshot; clients should read the requested language key and fall back to full_address when it is missing or empty. data.order also includes the nullable relationship fields return_delivery_id, return_delivery_code, original_delivery_id, and original_delivery_code. For an original order, data.return_delivery contains the linked return's basic id, delivery_code, status, and customer-visible driver. For a return order, data.original_delivery has the same shape. A linked operational return changes the canonical original/P&D parent to literal data.order.status=returning at physical pickup/in-transit and to returned at completion; data.order.return_status remains the separate return lifecycle. Driver is null when customer portal driver visibility is disabled or no driver is assigned. Existing return_request metadata remains on the order. Returns 404 when the order is absent or not owned by the customer, and 500 when delivery or return-context lookup fails.

Path parameters

ParameterTypeDescription
idRequiredstring

Delivery order ID

Example: uuid

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/customer/delivery/orders/${ID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "data": {4    "order": {5      "id": "delivery-uuid",6      "source_transfer_manifest_id": "manifest-uuid",7      "pickup": {8        "location": {9          "title": {10            "en": "Processing point"11          },12          "full_address": "100 Meter Road, Erbil"13        }14      }15    }16  }17}

Cancel Order​

Customer Portal / Delivery Management / Orders
POST/customer/delivery/orders/:id/cancel

Cancels an order owned by the authenticated customer. Cancellation is blocked transactionally with HTTP 409 cannot_cancel_delivery_after_driver_assignment once any assignment in the logical order is active, and with HTTP 409 cannot_cancel_delivery_in_terminal_status after final delivery or another terminal logical state. For staged/P&D, the parent or any operational child ID resolves to the canonical parent; a completed inbound warehouse leg does not block cancellation while final delivery remains incomplete. Paid family delivery fees and collected COD are refunded once to the sender wallet, and the success response returns the canonical root order ID.

Path parameters

ParameterTypeDescription
idRequiredstring

Delivery order ID

Example: uuid

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
reasonstring—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/customer/delivery/orders/${ID}/cancel" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "reason": "Customer requested cancellation"6}'

Response examples

200OK
Response body
json
1{2  "success": true,3  "data": {4    "order": {5      "id": "uuid",6      "status": "cancelled",7      "updated_at": "2026-02-04T12:00:00Z"8    }9  }10}