Receiving Orders
10 API calls in this section.
Endpoints for managing receiving orders (incoming shipments) in warehouses, including creating orders and listing them with various filtering options. The receiving-order database write is the atomic stock boundary: it projects only the newly received cumulative delta into stock and one receive movement, so normal, quick, package, and item-bulk paths cannot add the same units twice. Inventory item rows preserve has_open_exception and the latest open_exception, and also expose every current open_exceptions entry plus open_exception_count. For an open damaged exception with an exact package mapping and current available stock in the same warehouse, that compact exception returns package_item_id and available_actions[].key=return_to_origin; this also applies when receiving created stock after the exception and inventory_stock_id remains null. An explicit stock ID must still match exactly. Execute the action through POST /warehousing/exceptions/:id/return-to-origin. Its receiving_order_id is optional provenance. A staged P&D receiving order remains blocked by an unrelated open parent exception. When an Arrived-at-Warehouse parent exception is explicitly linked to that existing receiving order, warehouse staff may receive that exact order while the exception remains open; Retry and Return stay blocked until receipt confirms custody. Executing an outbound P&D delivery remains blocked until the parent exception is resolved.
List Receiving Orders
/warehousing/receiving-ordersRetrieves receiving orders with pagination and filters.
Status counts
statsandstatus_matrixare identical.They are scoped by
tenant_idand bywarehouse_idwhenwarehouse_idis provided either as a legacy query parameter or incolumn_filters.They are not narrowed by the selected
status, so the frontend can render status tabs for the selected tenant or warehouse whiletotalremains the current filtered result count.
Frontend integration contract
Use
totalfor the current list result count after all filters, includingstatus.Use
status_matrixorstatsfor status-tab counts. When calling withwarehouse_id, those counts are for that warehouse only.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) Example: |
language | string | Example: |
sort_byOptional | string | Sort field: |
sort_orderOptional | string | asc | desc (default: desc) |
column_filtersOptional | string | JSON-stringified filter object. Keys: |
warehouse_idOptional | string | Legacy: filter by warehouse (optional). When present, stats/ |
supplier_idOptional | string | Legacy: filter by supplier (optional) |
statusOptional | string | Legacy: filter by status (optional). stats/ |
expected_arrival_dateOptional | string | Legacy: filter by exact date YYYY-MM-DD (optional) |
searchOptional | string | Search in |
page | string | Example: |
limit | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders?tenant_id=${TENANT_ID}&language=en&page=1&limit=20" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json"Response examples
1{2 "success": true,3 "message": "Receiving orders retrieved successfully",4 "receiving_orders": [5 {6 "id": "ro-uuid-1",7 "tenant_id": "tenant-uuid",8 "warehouse_id": "warehouse-uuid",9 "reference_number": "RO-1Z2X3C4V",10 "external_reference": "PO-9876",11 "supplier_id": "supplier-uuid",12 "supplier_name": "Acme Suppliers Inc.",13 "expected_arrival_date": "2026-06-15T00:00:00Z",14 "actual_arrival_date": null,15 "status": "pending",16 "total_items": 2,17 "total_quantity": 75,18 "items": [19 {20 "item_id": "item-uuid-1",21 "item_name": "Premium T-Shirt",22 "quantity": 50,23 "received_quantity": 0,24 "lot_number": "LOT123",25 "serial_number": "SN456",26 "bin_id": null,27 "attributes": {28 "color": "black",29 "size": "medium"30 }31 },32 {33 "item_id": "item-uuid-2",34 "item_name": "Cotton Polo Shirt",35 "quantity": 25,36 "received_quantity": 0,37 "lot_number": "LOT456",38 "serial_number": "SN789",39 "bin_id": null,40 "attributes": {41 "color": "white",42 "size": "large"43 }44 }45 ],46 "notes": "Monthly restock order",47 "created_at": "2026-05-01T10:00:00Z",48 "updated_at": "2026-05-01T10:00:00Z",49 "warehouse": {50 "id": "warehouse-uuid",51 "name": "Main Warehouse",52 "code": "WH001"53 },54 "received_by_user": null,55 "supplier": {56 "id": "supplier-uuid",57 "name": "Acme Suppliers Inc."58 }59 }60 ],61 "stats": {62 "total": 21,63 "pending": 5,64 "in_progress": 1,65 "received": 11,66 "partially_received": 3,67 "received_with_exceptions": 0,68 "cancelled": 169 },70 "status_matrix": {71 "total": 21,72 "pending": 5,73 "in_progress": 1,74 "received": 11,75 "partially_received": 3,76 "received_with_exceptions": 0,77 "cancelled": 178 },79 "page": 1,80 "limit": 20,81 "total": 2182}Create Receiving Order
/warehousing/receiving-ordersCreates a new receiving order (incoming shipment) for a warehouse. Validates warehouse existence, item details, and optional supplier references.
User must have 'manage:operations:tenant' permission
Business Rules
Warehouse must exist and belong to the specified tenant
All items must exist in the inventory system
Each item must have a valid
item_idand positive quantityIf
supplier_idis provided, it must exist in the systemStatus must be one of: pending, received,
partially_received,received_with_exceptions, cancelledItem attributes must be a valid object if provided
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
warehouse_id | string | — |
expected_arrival_date | string | — |
item_details | array<object> | — |
item_details.item_id | string | — |
item_details.quantity | number | — |
item_details.lot_number | string | — |
item_details.serial_number | string | — |
item_details.attributes | object | — |
item_details.attributes.color | string | — |
item_details.attributes.size | string | — |
reference_number | string | — |
external_reference | string | — |
Show 8 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
supplier_id | string | — |
status | string | — |
receiving_details | object | — |
receiving_details.tracking_number | string | — |
receiving_details.carrier | string | — |
receiving_details.shipping_method | string | — |
receiving_details.notes | string | — |
notes | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "warehouse_id": "{{warehouse_id}}",6 "expected_arrival_date": "2023-06-15",7 "item_details": [8 {9 "item_id": "{{item_id_1}}",10 "quantity": 50,11 "lot_number": "LOT123",12 "serial_number": "SN456",13 "attributes": {14 "color": "black",15 "size": "medium"16 }17 },18 {19 "item_id": "{{item_id_2}}",20 "quantity": 25,21 "lot_number": "LOT456",22 "serial_number": "SN789",23 "attributes": {24 "color": "white",25 "size": "large"26 }27 }28 ],29 "reference_number": "RO-1Z2X3C4V",30 "external_reference": "PO-9876",31 "supplier_id": "{{supplier_id}}",32 "status": "pending",33 "receiving_details": {34 "tracking_number": "TRK12345",35 "carrier": "Express Shipping Co.",36 "shipping_method": "2-day",37 "notes": "Deliver at loading dock B"38 },39 "notes": "Monthly restock order"40}'Replace {{placeholders}} with your own values before sending.
Other request examples (1)
1{2 "warehouse_id": "uuid", // required3 "expected_arrival_date": "date", // required4 "item_details": [ // required array of items5 {6 "item_id": "uuid", // required7 "quantity": number, // required, must be positive8 "lot_number": "string", // optional9 "serial_number": "string", // optional10 "attributes": {} // optional custom attributes11 }12 ],13 "reference_number": "string", // optional14 "external_reference": "string", // optional (e.g., purchase order number)15 "supplier_id": "uuid", // optional16 "status": "string", // required (pending, received, partially_received, received_with_exceptions, cancelled)17 "receiving_details": { // optional18 "tracking_number": "string", 19 "carrier": "string",20 "shipping_method": "string",21 "notes": "string"22 },23 "notes": "string" // optional24}Response examples
1{2 "success": true,3 "message": "Receiving order created successfully",4 "receiving_order": {5 "id": "order-uuid",6 "tenant_id": "tenant-uuid",7 "warehouse_id": "warehouse-uuid",8 "reference_number": "RO-1Z2X3C4V",9 "external_reference": "PO-9876",10 "supplier_id": "supplier-uuid",11 "expected_arrival_date": "2023-06-15T00:00:00Z",12 "status": "pending",13 "item_details": [14 {15 "item_id": "item-uuid-1",16 "quantity": 50,17 "lot_number": "LOT123",18 "serial_number": "SN456",19 "attributes": {20 "color": "black",21 "size": "medium"22 }23 },24 {25 "item_id": "item-uuid-2",26 "quantity": 25,27 "lot_number": "LOT456",28 "serial_number": "SN789",29 "attributes": {30 "color": "white",31 "size": "large"32 }33 }34 ],35 "receiving_details": {36 "tracking_number": "TRK12345",37 "carrier": "Express Shipping Co.",38 "shipping_method": "2-day",39 "notes": "Deliver at loading dock B"40 },41 "actual_arrival_date": null,42 "received_by": null,43 "notes": "Monthly restock order",44 "created_at": "2023-06-01T10:00:00Z",45 "updated_at": "2023-06-01T10:00:00Z"46 }47}Get Receiving Order
/warehousing/receiving-orders/:idRetrieves detailed information about a specific receiving order, including warehouse, supplier, receiver, and enriched receipt-item details.
User must have
view:tenantormanage:operations:tenantpermission.
Response contract
Normal inventory receiving orders expose
items[]withitem_id, item metadata, quantity, received quantity,bin_id,binas{ id, name, code, location_type }(ornullwhen no valid bin is assigned), and exception context.Bin enrichment is tenant- and receiving-warehouse-scoped.
When
receiving_details.exception_idreferences an original delivery exception,receiving_detailsalso includesexception_type,exception_label,exception_reason, andexception_notes. Missing optional reason or notes are returned asnull.return_reasonremains the physical return-handoff reason and is not used as the original delivery exception reason.Waybill-generated receiving orders expose one delivery manifest entry per
items[]row withdelivery_id,delivery_code,barcode,delivery_status, receiptoutcome,notes,quantity: 1, andreceived_quantity(0for missing, otherwise1).total_itemscounts the returned receipt rows. For Waybill-generated orders,total_quantityis the manifest delivery count.Includes associated warehouse, supplier, and receiver information when available.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | UUID of the receiving order to retrieve (required) UUID of the receiving order to retrieve. |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant. Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
More examples
1{2 "item_id": "item-uuid",3 "bin_id": "bin-uuid",4 "bin": {5 "id": "bin-uuid",6 "name": "Receiving Bin",7 "code": "B001",8 "location_type": "bin"9 }10}1{2 "success": true,3 "receiving_order": {4 "waybill_id": "waybill-uuid",5 "status": "partially_received",6 "total_items": 2,7 "total_quantity": 2,8 "items": [9 {10 "delivery_id": "delivery-uuid",11 "delivery_code": "DEL1001",12 "barcode": "1001",13 "delivery_status": "delivered",14 "outcome": "present",15 "notes": null,16 "quantity": 1,17 "received_quantity": 118 }19 ]20 }21}1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/${ID}?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json"Response examples
1{2 "success": true,3 "message": "Receiving order retrieved successfully",4 "receiving_order": {5 "id": "order-uuid",6 "waybill_id": "waybill-uuid",7 "warehouse_id": "warehouse-uuid",8 "reference_number": "RO-WB-WB00039",9 "status": "partially_received",10 "receiving_details": {11 "source": "failed_delivery_return",12 "exception_id": "exception-uuid",13 "return_reason": "Returned as instructed",14 "exception_type": "damaged",15 "exception_label": "Package Damage",16 "exception_reason": "Outer box was crushed",17 "exception_notes": "Driver uploaded a photo"18 },19 "total_items": 2,20 "total_quantity": 2,21 "items": [22 {23 "delivery_id": "delivery-uuid-1",24 "delivery_code": "DEL1001",25 "barcode": "1001",26 "delivery_status": "delivered",27 "outcome": "present",28 "notes": null,29 "quantity": 1,30 "received_quantity": 131 },32 {33 "delivery_id": "delivery-uuid-2",34 "delivery_code": "DEL1002",35 "barcode": "1002",36 "delivery_status": "in_transit",37 "outcome": "missing",38 "notes": null,39 "quantity": 1,40 "received_quantity": 041 }42 ]43 }44}Scan Receiving Order Barcode
/warehousing/receiving-orders/scan/{{delivery_barcode}}Scans a staged receiving barcode and resolves its receiving warehouse from the matched receiving order.
The actor must have an active
warehouse_staffassignment for the matched receiving order's warehouse.warehouse_idis not required or read; the backend derives it from the receiving order.
Response contract
Exact delivery-item codes are verified against the tenant package-item record and mapped to an inventory line in the same receiving order before their parent code is used. Arbitrary suffixes such as
DEL3501-99return HTTP 404.scan.typeisdelivery_package_item,scan.package_item_ididentifies the printed box, andscan.inventory_item_ididentifies its receiving-order inventory line; parent scans retaindelivery_packageand return null item IDs.When the barcode exists in both an origin and a Waybill destination receiving order, the destination receipt order is selected.
receiving_order.default_receiving_locationis the active default receiving location, or null.HTTP 403
warehouse_access_deniedmeans the actor is not active staff of the matched receiving order's warehouse.
Frontend integration contract
Send the complete scanned barcode without removing the
-Nsuffix.Do not send
warehouse_idto this scan endpoint.Preselect
receiving_order.default_receiving_location.idwhen non-null.Keep the location scanner visible. For location scans, use
receiving_order.warehouse.idfrom this response as thewarehouse_idinGET /warehousing/locations/:barcode?search_type=barcode&warehouse_id=:warehouse_id.
Resolve a receiving barcode to receiving-order details. Accepts a parent delivery barcode such as DEL3501 and an exact printed delivery-item barcode such as DEL3501-1. For an item barcode, the backend verifies the complete code, uses DEL3501 to locate the parent receiving order, and keeps DEL3501-1 as the exact box identity. Failed staged P&D child legs use the physical parent parcel barcode; operational returns use the separate return delivery's own barcode. Eligible unassigned G2G receiving work remains supported through the shared atomic warehouse-staging owner. The backend derives the warehouse from the matched receiving order and verifies that the actor is active staff of that warehouse.
Path parameters
| Parameter | Type | Description |
|---|---|---|
delivery_barcodeRequired | string | Variable used inside the request path. |
barcodeRequired | string | Parent delivery barcode such as |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) is required only when it is unavailable from the authenticated request context. Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/scan/${DELIVERY_BARCODE}?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json"Response examples
1{2 "success": true,3 "message": "Receiving order retrieved successfully",4 "scan": {5 "barcode": "DEL1001",6 "type": "delivery_package"7 },8 "receiving_order": {9 "id": "receiving-order-uuid",10 "reference_number": "RO-1001",11 "external_reference": "DEL1001",12 "status": "pending",13 "warehouse": {14 "id": "warehouse-uuid",15 "name": "Main Warehouse",16 "code": "WH001"17 },18 "default_receiving_location": {19 "id": "location-uuid",20 "code": "B001",21 "name": "Receiving Bin",22 "barcode": "WLCWH001B001",23 "location_type": "bin"24 },25 "item_details": [26 {27 "item_id": "item-uuid-1",28 "quantity": 1,29 "received_quantity": 0,30 "bin_id": null31 }32 ]33 },34 "items": []35}Validate Bulk Package Receiving Barcodes
/warehousing/receiving-orders/bulk-receive/validateValidates parent delivery and exact delivery-item barcodes for receiving. This endpoint does not mutate receiving orders or inventory stock.
User must have warehouse/tenant access through the normal warehousing middleware.
Business Rules
A parent barcode such as
DEL3501selects every remaining box in its receiving order, preserving the existing receive-all behavior.An exact item barcode such as
DEL3501-1is verified againstdelivery_package_items, resolves parentDEL3501, and selects only its matching receiving-order inventory line.Multiple item barcodes for one order are combined without selecting unscanned boxes.
Duplicate scans in the same request return
duplicate_scan; unknown or invented item suffixes returnunknown_barcode.Cancelled receiving orders return
receiving_order_not_receivable; fully received lines returnalready_received.Staged inbound delivery readiness is enforced before package scans are marked valid.
Validation uses set-based indexed barcode lookups and no per-barcode database queries.
Frontend integration contract
Send every complete scanned code, including its
-Nsuffix.Treat both
delivery_packageanddelivery_package_itemresult types as valid whenresults[].valid === true.Show
invalid_scans[].messageorinvalid_scans[].reasoninline.Use
counts.scanned_count,counts.valid_count, andcounts.invalid_countfor the live scan summary.
If a scanned staged P&D receiving order has an unrelated open parent exception, that scan is invalid with reason=parent_exception_open. The exact order linked to an Arrived-at-Warehouse exception remains receivable so warehouse custody can be confirmed.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant. Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
barcodes | array<string> | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/bulk-receive/validate?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "barcodes": [6 "DEL3501-1",7 "DEL3501-2"8 ]9}'Response examples
1{2 "success": true,3 "message": "Bulk package receiving barcodes validated successfully",4 "results": [5 {6 "barcode": "DEL1001",7 "valid": true,8 "type": "delivery_package",9 "reason": "valid_scan",10 "message": "Valid scan",11 "receiving_order_id": "receiving-order-uuid-1",12 "reference_number": "RO-STAGE-1001",13 "warehouse_id": "warehouse-uuid",14 "remaining_items": 115 },16 {17 "barcode": "DEL9999",18 "valid": false,19 "type": "unknown",20 "reason": "unknown_barcode",21 "message": "Unknown barcode"22 }23 ],24 "invalid_scans": [25 {26 "barcode": "DEL9999",27 "valid": false,28 "type": "unknown",29 "reason": "unknown_barcode",30 "message": "Unknown barcode"31 }32 ],33 "counts": {34 "scanned_count": 2,35 "valid_count": 1,36 "invalid_count": 137 }38}Bulk Receive Package Receiving Orders
/warehousing/receiving-orders/bulk-receiveCompletes receiving from parent delivery or exact delivery-item barcodes across staged receiving orders.
User must have warehouse/tenant access through the normal warehousing middleware.
bin_idis optional. If omitted, backend uses the active default receiving location.
Business Rules
Backend re-runs the same exact barcode validation before mutating data.
A parent code receives all remaining lines. Exact item codes receive only their matching lines; unscanned lines remain outstanding and the order becomes
partially_received.Receiving the remaining exact item codes later changes the order to
received.All valid scans in one completion request must resolve to one warehouse.
Stock and receive movements are projected only for newly selected quantities into the selected/default location.
Invalid scans are returned in
invalid_scans; valid scans can still complete.
Frontend integration contract
Send complete physical item barcodes without stripping the suffix.
Keep the scanned barcode list and selected
bin_id; do not constructitem_details.Use each
receive_result.statusto displaypartially_receivedorreceived.Handle
mixed_warehouse_codes,bin_id_required_for_received_items,inbound_delivery_not_ready,already_received,not_part_of_this_receiving_order, andunknown_barcodefromresults[]/invalid_scans[].
Normal staged P&D receiving remains blocked by an unrelated open parent exception. The exact staged order linked to an Arrived-at-Warehouse parent exception and a failed outbound re-receiving order are explicitly receivable while their exceptions remain open. The receiving-order update atomically adds only each line's remaining received delta to stock and one receive movement; a replay adds zero.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant. Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
barcodes | array<string> | — |
bin_id | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/bulk-receive?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "barcodes": [6 "DEL3501-1",7 "DEL3501-2"8 ],9 "bin_id": "{{location_id}}"10}'Replace {{placeholders}} with your own values before sending.
Other request examples (1)
1{2 "barcodes": [3 "DEL3501-1",4 "DEL3501-2"5 ],6 "bin_id": "warehouse-location-uuid"7}Response examples
1{2 "success": true,3 "message": "Bulk package receiving completed",4 "received_count": 2,5 "failed_count": 0,6 "bin_id": "location-uuid",7 "results": [8 {9 "barcode": "DEL1001",10 "valid": true,11 "type": "delivery_package",12 "reason": "valid_scan",13 "message": "Valid scan",14 "receiving_order_id": "receiving-order-uuid-1",15 "reference_number": "RO-STAGE-1001",16 "warehouse_id": "warehouse-uuid",17 "remaining_items": 1,18 "success": true,19 "receive_result": {20 "success": true,21 "receiving_order_id": "receiving-order-uuid-1",22 "reference_number": "RO-STAGE-1001",23 "external_reference": "DEL1001",24 "warehouse_id": "warehouse-uuid",25 "status": "received",26 "received_items": 1,27 "auto_execute_delivery": {28 "enabled": false,29 "attempted": 0,30 "executed": 0,31 "skipped": 0,32 "failed": 0,33 "details": []34 }35 }36 }37 ],38 "invalid_scans": [],39 "counts": {40 "scanned_count": 2,41 "valid_count": 2,42 "invalid_count": 0,43 "received_count": 2,44 "failed_count": 045 }46}Validate Bulk Receiving Barcodes
/warehousing/receiving-orders/:id/bulk-receive/validateValidates scans for one receiving order without mutating receiving status or stock.
User must have warehouse/tenant access through the normal warehousing middleware.
Business Rules
Exact delivery-item codes are verified against
delivery_package_items, resolved through their parent delivery code, and mapped to the matchingSTAGE-<delivery>-<ordinal>inventory line in this order.Existing
inventory_items.barcodescans remain supported.A parent delivery barcode confirms context but does not select an item in this order-specific flow.
Item codes for another order return
wrong_receiving_order_context; invented codes returnunknown_barcode.Duplicate and already-received scans are rejected.
Lookups are batched and indexed.
Frontend integration contract
Send the complete scanned code, including the
-Nsuffix.Treat valid
warehouse_itemanddelivery_package_itemresults as receivable items.Show
invalid_scans[].messageinline.Use
counts.expected_count,counts.scanned_valid_count, andcounts.remaining_countfor the live display.
Returns HTTP 409 with code=parent_exception_open when the staged P&D parent has an open exception that is not awaiting this exact receiving order. A linked Arrived-at-Warehouse exception must be received before dispatcher resolution.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | UUID of the receiving order being scanned. |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
barcodes | array<string> | — |
warehouse_id | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/${ID}/bulk-receive/validate?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "barcodes": [6 "DEL3501-1",7 "DEL3501-2"8 ],9 "warehouse_id": "{{warehouse_id}}"10}'Replace {{placeholders}} with your own values before sending.
Other request examples (1)
1{2 "barcodes": [3 "DEL3501-1",4 "DEL3501-2"5 ],6 "warehouse_id": "warehouse-uuid"7}Response examples
1{2 "success": true,3 "message": "Bulk receiving barcodes validated successfully",4 "receiving_order": {5 "id": "receiving-order-uuid",6 "reference_number": "RO-1001",7 "external_reference": "DEL1001",8 "status": "pending",9 "warehouse": {10 "id": "warehouse-uuid",11 "name": "Main Warehouse",12 "code": "WH001"13 }14 },15 "results": [16 {17 "barcode": "DEL1001",18 "valid": true,19 "type": "receiving_order",20 "reason": "valid_scan",21 "message": "Valid scan",22 "receiving_order_id": "receiving-order-uuid",23 "reference_number": "RO-1001"24 },25 {26 "barcode": "INV1001",27 "valid": true,28 "type": "warehouse_item",29 "reason": "valid_scan",30 "message": "Valid scan",31 "item_id": "item-uuid-1",32 "sku": "SKU-001",33 "item_name": "Package Item",34 "quantity": 1,35 "received_quantity": 036 },37 {38 "barcode": "INV9999",39 "valid": false,40 "type": "unknown",41 "reason": "unknown_barcode",42 "message": "Unknown barcode"43 }44 ],45 "valid_items": [46 {47 "item_id": "item-uuid-1",48 "quantity": 1,49 "received_quantity": 0,50 "bin_id": null51 }52 ],53 "invalid_scans": [54 {55 "barcode": "INV9999",56 "valid": false,57 "type": "unknown",58 "reason": "unknown_barcode",59 "message": "Unknown barcode"60 }61 ],62 "counts": {63 "expected_count": 2,64 "already_received_count": 0,65 "scanned_valid_count": 1,66 "remaining_count": 167 }68}Bulk Receive Receiving Order
/warehousing/receiving-orders/:id/bulk-receiveFinalizes receiving for valid inventory or exact delivery-item barcodes. The backend revalidates the complete codes and constructs the received item payload.
User must have warehouse/tenant access through the normal warehousing middleware.
Business Rules
bin_idis required and must belong to the receiving order warehouse.Only the valid scanned item lines are received and stocked in that bin.
Unscanned lines remain outstanding; status is
partially_receiveduntil every line is received.Existing inventory barcodes remain supported.
Invalid scans are returned in
invalid_scans; if no valid item scans remain, the endpoint returns HTTP 400.Stock increases only by the newly received quantity.
Frontend integration contract
Submit the complete scanned barcode list and selected
bin_id; do not strip delivery-item suffixes.Do not construct or submit
item_details.Use
receiving_order.status,counts.received_count, andcounts.remaining_countafter success.
Returns HTTP 409 with code=parent_exception_open when the staged P&D parent has an open exception that is not awaiting this exact receiving order. Receiving status and inventory stock remain unchanged for blocked orders. For accepted scans, the receiving-order update atomically projects only the newly received cumulative delta into stock and one receive movement; a replay adds zero.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | UUID of the receiving order to bulk receive UUID of the receiving order to receive. |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
barcodes | array<string> | — |
bin_id | string | — |
warehouse_id | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/${ID}/bulk-receive?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "barcodes": [6 "DEL3501-1",7 "DEL3501-2"8 ],9 "bin_id": "{{location_id}}",10 "warehouse_id": "{{warehouse_id}}"11}'Replace {{placeholders}} with your own values before sending.
Other request examples (1)
1{2 "barcodes": [3 "DEL3501-1",4 "DEL3501-2"5 ],6 "bin_id": "warehouse-location-uuid",7 "warehouse_id": "warehouse-uuid"8}Response examples
1{2 "success": true,3 "message": "Bulk receiving completed successfully",4 "receiving_order": {5 "id": "receiving-order-uuid",6 "warehouse_id": "warehouse-uuid",7 "reference_number": "RO-1001",8 "external_reference": "DEL1001",9 "status": "partially_received",10 "supplier_name": null,11 "total_items": 2,12 "total_quantity": 2,13 "items": [14 {15 "item_id": "item-uuid-1",16 "item_name": "Package Item",17 "quantity": 1,18 "received_quantity": 1,19 "bin_id": "location-uuid"20 }21 ]22 },23 "received_items": [24 {25 "item_id": "item-uuid-1",26 "bin_id": "location-uuid",27 "received_quantity": 1,28 "lot_number": null,29 "serial_number": null30 }31 ],32 "invalid_scans": [],33 "counts": {34 "expected_count": 2,35 "received_count": 1,36 "newly_received_count": 1,37 "remaining_count": 138 },39 "auto_execute_delivery": {40 "enabled": false,41 "attempted": 0,42 "executed": 0,43 "skipped": 0,44 "failed": 0,45 "details": []46 }47}Execute Receiving Order
/warehousing/receiving-orders/:id/executeAtomic outbound execution for a received order. The action is allowed only when the receiving order still owns current custody and the actor is active staff of that order's warehouse. A warehouse-staged P&D Execute requires exact equality between received, stocked, picked, and reserved quantities, then returns a completed pick, reserved stock, and handoff: null; the later assignment owns handoff creation. A confirmed Waybill transfer removes execution from the origin and creates the actionable destination order without changing the existing Waybill execution contract. Frontend must branch on HTTP 403 warehouse_access_denied, HTTP 409 receiving_order_not_current_warehouse, and HTTP 409 warehouse_preparation_inconsistent.
Executes the exact outbound delivery_id owned by a received order. The receiving order determines the warehouse; no request body is required. The actor must have an active warehouse_staff assignment for that warehouse or the API returns HTTP 403 warehouse_access_denied. A Waybill receipt creates one destination receiving order per logical delivery. Only a present order returns can_execute: true; missing, damaged, no-location, and origin-history rows return a stable execution_block_reason. For a staged-delivery receiving order, can_execute is true only when the linked parent is staged_at_warehouse; otherwise it is false with execution_block_reason=parent_not_staged_for_outbound_execution, matching the execution guard. For a warehouse-staged P&D or operational-return order, execution atomically moves the outbound delivery to pending, creates one completed picking order, reserves destination stock without reducing its quantity, and returns handoff: null; received, stocked, picked, and reserved quantities must match exactly or the request returns HTTP 409 warehouse_preparation_inconsistent. Assignment creates the handoff later with driver context. Repeating P&D execution returns the existing preparation with idempotent_replay: true. Waybill and other non-staged receiving-order execution keep their existing behavior.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | Received order UUID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant when it is not supplied by authentication context Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/${ID}/execute?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "Receiving order executed successfully",4 "idempotent_replay": false,5 "receiving_order": {6 "id": "{{receiving_order_id}}",7 "warehouse_id": "{{destination_warehouse_id}}",8 "status": "received"9 },10 "delivery": {11 "id": "{{delivery_id}}",12 "status": "pending"13 },14 "picking_order": {15 "id": "{{picking_order_id}}",16 "status": "completed"17 },18 "handoff": null19}Update Receiving Order
/warehousing/receiving-orders/:idUpdates a receiving order through the normal warehouse receiving flow; no separate failed-delivery receiving endpoint exists. Send { "status": "received" }. A failed-delivery receipt may send one selected location through item_details[0].bin_id; if omitted, backend uses the warehouse's active default receiving location. If neither exists, the API returns HTTP 400 bin_id_required_for_received_items. Do not send a return-specific location field.
Inventory receiving may also send exceptions, where each entry contains inventory_item_id (or item_id), exception_type, optional affected_quantity, inventory_stock_id, location_id, exception_details, and notes. For an item with positive received_quantity, exceptions are recorded after receipt stock exists. If the tenant-defined exception type has write_off_stock=true, the response is reloaded after the atomic write-off and returns that item with reduced received_quantity. A fully received order changes to received_with_exceptions; the order remains partially_received while other lines are outstanding. Both received and received_with_exceptions are completed receipt states: for a staged P&D order either state advances its parent from arrived_at_warehouse to staged_at_warehouse, so unaffected packages can continue to outbound preparation. During dispatcher warehouse staging, a package already recorded as returned on the inbound child remains in item_details for audit with received_quantity=0 and receipt_outcome=returned_before_warehouse_receipt; it creates no warehouse stock, while forward packages are fully received and the order completes as received_with_exceptions. Auto-execution uses the same corrected quantities. A linked item with received_quantity=0, or no received_quantity before receiving starts, is a valid no-stock exception: the exception is saved with stock_written_off=false, null write-off audit fields, and no unrelated stock is consumed. HTTP 409 code warehouse_write_off_stock_not_available remains reserved for positive received stock that cannot be written off.
For any Picked up/In transit delivery whose physical origin is a warehouse, exception creation has already created one exception-specific pending receiving order. While its custody is awaiting_warehouse_receipt, Retry, Return, and Cancel are unavailable. Receipt atomically restores item-level stock at the resolved receiving location, records one receive inventory movement per parcel item against this receiving order, confirms warehouse custody, removes the old route/trip, marks the old assignment Unassigned, and releases driver capacity exactly once. The delivery remains Exception and the exception remains Open until the dispatcher makes a separate decision after receipt.
For P&D outbound, the parent becomes Staged at warehouse; a later Retry makes Leg B Pending and a later Return stops the failed outbound before creating the existing operational return. For an operational return, there is no parent update and a later Retry makes the same operational return Pending. No nested return order or extra driver action is created.
Frontend
package scan continues opening this normal receiving order. Submit literal status received, optionally one existing location ID. A successful re-stage returns failed_delivery_return.delivery_status=exception, custody_state=staged_at_warehouse, exception_status=open, stock_restored=true, receiving_location_id, and return_action=null; parent_status is Staged for P&D and null for operational returns. Refetch staged P&D receiving details and do not present lines with receipt_outcome=returned_before_warehouse_receipt as warehouse stock or customer-dispatch candidates. Handle failed_delivery_return_items_not_found, failed_delivery_return_pick_quantity_not_found, and failed_delivery_return_stock_projection_failed as conflicts without advancing the screen. Refetch the exception after receipt and render only the actions returned by the backend. Do not show Assign until the dispatcher resolves Retry.
The receiving-order update is the atomic stock boundary. For received, partially received, and received-with-exceptions item lines, the backend projects only the positive cumulative delta into stock and one receiving-order movement; retrying the same cumulative quantities adds zero. Failed-delivery receipt also appends the operational child's warehouse-restage event while keeping the exception open.
When status is received, partially_received, or received_with_exceptions and inventory item_details are supplied, ordinary receipt returns auto_execute_delivery with enabled, attempted, executed, skipped, failed, and details[]. A disabled package setting returns enabled: false and zero counters. Paths that do not check auto-execution, including Waybill and failed-delivery receipt, return null. Each detail identifies item_id, optional delivery_id, and status (executed, skipped, or failed); skipped/failed entries may include reason, code, and message. Executed entries may include picking_order_id; handoff_id exists only when the existing non-P&D execution creates a handoff. P&D and operational-return preparation waits for later assignment to create the handoff.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | UUID of the receiving order to update (required) |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | UUID of the tenant (required if not in auth) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
status | string | — |
actual_arrival_date | string | — |
notes | string | — |
receiving_details | object | — |
receiving_details.tracking_number | string | — |
receiving_details.carrier | string | — |
receiving_details.shipping_method | string | — |
receiving_details.notes | string | — |
item_details | array<object> | — |
item_details.item_id | string | — |
item_details.quantity | number | — |
item_details.received_quantity | number | — |
Show 7 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
item_details.bin_id | null | — |
item_details.lot_number | string | — |
item_details.serial_number | string | — |
item_details.attributes | object | — |
item_details.attributes.color | string | — |
item_details.attributes.size | string | — |
item_details.attributes.condition | string | — |
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/warehousing/receiving-orders/${ID}?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "status": "received",6 "actual_arrival_date": "2023-06-15",7 "notes": "Received complete shipment on time",8 "receiving_details": {9 "tracking_number": "TRK12345-UPDATED",10 "carrier": "Express Shipping Co.",11 "shipping_method": "2-day",12 "notes": "Delivered at loading dock B"13 },14 "item_details": [15 {16 "item_id": "item-uuid-1",17 "quantity": 50,18 "received_quantity": 50,19 "bin_id": null,20 "lot_number": "LOT123",21 "serial_number": "SN456",22 "attributes": {23 "color": "black",24 "size": "medium",25 "condition": "perfect"26 }27 },28 {29 "item_id": "item-uuid-2",30 "quantity": 25,31 "received_quantity": 25,32 "bin_id": "{{location_id}}",33 "lot_number": "LOT456",34 "serial_number": "SN789",35 "attributes": {36 "color": "white",37 "size": "large",38 "condition": "good"39 }40 }41 ]42}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "message": "Receiving order updated successfully",4 "receiving_order": {5 "id": "order-uuid",6 "warehouse_id": "warehouse-uuid",7 "status": "received",8 "supplier_name": null,9 "total_items": 1,10 "total_quantity": 1,11 "items": [12 {13 "item_id": "item-uuid-1",14 "delivery_id": null,15 "waybill_delivery_id": null,16 "outcome": null,17 "item_name": "Product Name",18 "quantity": 1,19 "received_quantity": 1,20 "bin_id": "location-uuid",21 "has_open_exception": false,22 "open_exception": null,23 "open_exceptions": [],24 "open_exception_count": 025 }26 ]27 },28 "auto_execute_delivery": {29 "enabled": true,30 "attempted": 1,31 "executed": 1,32 "skipped": 0,33 "failed": 0,34 "details": [35 {36 "item_id": "item-uuid-1",37 "delivery_id": "delivery-uuid-1",38 "status": "executed",39 "picking_order_id": "picking-order-uuid"40 }41 ]42 }43}