Skip to main content

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 Orders
GET/warehousing/receiving-orders

Retrieves receiving orders with pagination and filters.

Status counts

  • stats and status_matrix are identical.

  • They are scoped by tenant_id and by warehouse_id when warehouse_id is provided either as a legacy query parameter or in column_filters.

  • They are not narrowed by the selected status, so the frontend can render status tabs for the selected tenant or warehouse while total remains the current filtered result count.

Frontend integration contract

  • Use total for the current list result count after all filters, including status.

  • Use status_matrix or stats for status-tab counts. When calling with warehouse_id, those counts are for that warehouse only.

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth)

Example: {{tenant_id}}

languagestring

Example: en

sort_byOptionalstring

Sort field: reference_number | expected_arrival_date | actual_arrival_date | created_at (default: created_at)

sort_orderOptionalstring

asc | desc (default: desc)

column_filtersOptionalstring

JSON-stringified filter object. Keys: warehouse_id, supplier_id, status, reference_number, expected_arrival_date {from,to}, actual_arrival_date {from,to}, total_items {min,max}, total_quantity {min,max}. When warehouse_id is present, stats/status_matrix are scoped to that warehouse.

warehouse_idOptionalstring

Legacy: filter by warehouse (optional). When present, stats/status_matrix are scoped to this warehouse.

supplier_idOptionalstring

Legacy: filter by supplier (optional)

statusOptionalstring

Legacy: filter by status (optional). stats/status_matrix remain across all statuses for the selected tenant/warehouse.

expected_arrival_dateOptionalstring

Legacy: filter by exact date YYYY-MM-DD (optional)

searchOptionalstring

Search in reference_number

pagestring

Example: 1

limitstring

Example: 20

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Staging
Request
curl
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

200OK
Response body
json
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 Orders
POST/warehousing/receiving-orders

Creates 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_id and positive quantity

  • If supplier_id is provided, it must exist in the system

  • Status must be one of: pending, received, partially_received, received_with_exceptions, cancelled

  • Item attributes must be a valid object if provided

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
warehouse_idstring—
expected_arrival_datestring—
item_detailsarray<object>—
item_details.item_idstring—
item_details.quantitynumber—
item_details.lot_numberstring—
item_details.serial_numberstring—
item_details.attributesobject—
item_details.attributes.colorstring—
item_details.attributes.sizestring—
reference_numberstring—
external_referencestring—
Show 8 more body fields

Additional body parameters

ParameterTypeDescription
supplier_idstring—
statusstring—
receiving_detailsobject—
receiving_details.tracking_numberstring—
receiving_details.carrierstring—
receiving_details.shipping_methodstring—
receiving_details.notesstring—
notesstring—
Staging
Request
curl
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)
Request example 1
text
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

201Success Response
Response body
json
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
GET/warehousing/receiving-orders/:id

Retrieves detailed information about a specific receiving order, including warehouse, supplier, receiver, and enriched receipt-item details.

  • User must have view:tenant or manage:operations:tenant permission.

Response contract

  • Normal inventory receiving orders expose items[] with item_id, item metadata, quantity, received quantity, bin_id, bin as { id, name, code, location_type } (or null when no valid bin is assigned), and exception context.

  • Bin enrichment is tenant- and receiving-warehouse-scoped.

  • When receiving_details.exception_id references an original delivery exception, receiving_details also includes exception_type, exception_label, exception_reason, and exception_notes. Missing optional reason or notes are returned as null.

  • return_reason remains 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 with delivery_id, delivery_code, barcode, delivery_status, receipt outcome, notes, quantity: 1, and received_quantity (0 for missing, otherwise 1).

  • total_items counts the returned receipt rows. For Waybill-generated orders, total_quantity is the manifest delivery count.

  • Includes associated warehouse, supplier, and receiver information when available.

Path parameters

ParameterTypeDescription
idRequiredstring

UUID of the receiving order to retrieve (required) UUID of the receiving order to retrieve.

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant.

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

More examples
Normal item bin example
json
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}
Waybill example
json
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}
Staging
Request
curl
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

200Success Response
Response body
json
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
GET/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_staff assignment for the matched receiving order's warehouse.

  • warehouse_id is 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-99 return HTTP 404.

  • scan.type is delivery_package_item, scan.package_item_id identifies the printed box, and scan.inventory_item_id identifies its receiving-order inventory line; parent scans retain delivery_package and 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_location is the active default receiving location, or null.

  • HTTP 403 warehouse_access_denied means the actor is not active staff of the matched receiving order's warehouse.

Frontend integration contract

  • Send the complete scanned barcode without removing the -N suffix.

  • Do not send warehouse_id to this scan endpoint.

  • Preselect receiving_order.default_receiving_location.id when non-null.

  • Keep the location scanner visible. For location scans, use receiving_order.warehouse.id from this response as the warehouse_id in GET /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

ParameterTypeDescription
delivery_barcodeRequiredstring

Variable used inside the request path.

barcodeRequiredstring

Parent delivery barcode such as DEL3501, or exact printed delivery-item barcode such as DEL3501-1.

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth) is required only when it is unavailable from the authenticated request context.

Example: {{tenant_id}}

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Staging
Request
curl
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

200OK
Response body
json
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
POST/warehousing/receiving-orders/bulk-receive/validate

Validates 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 DEL3501 selects every remaining box in its receiving order, preserving the existing receive-all behavior.

  • An exact item barcode such as DEL3501-1 is verified against delivery_package_items, resolves parent DEL3501, 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 return unknown_barcode.

  • Cancelled receiving orders return receiving_order_not_receivable; fully received lines return already_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 -N suffix.

  • Treat both delivery_package and delivery_package_item result types as valid when results[].valid === true.

  • Show invalid_scans[].message or invalid_scans[].reason inline.

  • Use counts.scanned_count, counts.valid_count, and counts.invalid_count for 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

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant.

Example: {{tenant_id}}

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
barcodesarray<string>—
Staging
Request
curl
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

200OK
Response body
json
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
POST/warehousing/receiving-orders/bulk-receive

Completes 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_id is 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 construct item_details.

  • Use each receive_result.status to display partially_received or received.

  • Handle mixed_warehouse_codes, bin_id_required_for_received_items, inbound_delivery_not_ready, already_received, not_part_of_this_receiving_order, and unknown_barcode from results[] / 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

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth) (required if not in auth): UUID of the tenant.

Example: {{tenant_id}}

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
barcodesarray<string>—
bin_idstring—
Staging
Request
curl
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)
Request example 1
json
1{2  "barcodes": [3    "DEL3501-1",4    "DEL3501-2"5  ],6  "bin_id": "warehouse-location-uuid"7}

Response examples

200OK
Response body
json
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
POST/warehousing/receiving-orders/:id/bulk-receive/validate

Validates 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 matching STAGE-<delivery>-<ordinal> inventory line in this order.

  • Existing inventory_items.barcode scans 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 return unknown_barcode.

  • Duplicate and already-received scans are rejected.

  • Lookups are batched and indexed.

Frontend integration contract

  • Send the complete scanned code, including the -N suffix.

  • Treat valid warehouse_item and delivery_package_item results as receivable items.

  • Show invalid_scans[].message inline.

  • Use counts.expected_count, counts.scanned_valid_count, and counts.remaining_count for 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

ParameterTypeDescription
idRequiredstring

UUID of the receiving order being scanned.

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth)

Example: {{tenant_id}}

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
barcodesarray<string>—
warehouse_idstring—
Staging
Request
curl
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)
Request example 1
json
1{2  "barcodes": [3    "DEL3501-1",4    "DEL3501-2"5  ],6  "warehouse_id": "warehouse-uuid"7}

Response examples

200OK
Response body
json
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
POST/warehousing/receiving-orders/:id/bulk-receive

Finalizes 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_id is 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_received until 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, and counts.remaining_count after 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

ParameterTypeDescription
idRequiredstring

UUID of the receiving order to bulk receive UUID of the receiving order to receive.

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth)

Example: {{tenant_id}}

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
barcodesarray<string>—
bin_idstring—
warehouse_idstring—
Staging
Request
curl
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)
Request example 1
json
1{2  "barcodes": [3    "DEL3501-1",4    "DEL3501-2"5  ],6  "bin_id": "warehouse-location-uuid",7  "warehouse_id": "warehouse-uuid"8}

Response examples

200OK
Response body
json
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
POST/warehousing/receiving-orders/:id/execute

Atomic 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

ParameterTypeDescription
idRequiredstring

Received order UUID

Example: {{receiving_order_id}}

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant when it is not supplied by authentication context

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

200Success Response
Response body
json
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
PUT/warehousing/receiving-orders/:id

Updates 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

ParameterTypeDescription
idRequiredstring

UUID of the receiving order to update (required)

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth)

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
statusstring—
actual_arrival_datestring—
notesstring—
receiving_detailsobject—
receiving_details.tracking_numberstring—
receiving_details.carrierstring—
receiving_details.shipping_methodstring—
receiving_details.notesstring—
item_detailsarray<object>—
item_details.item_idstring—
item_details.quantitynumber—
item_details.received_quantitynumber—
Show 7 more body fields

Additional body parameters

ParameterTypeDescription
item_details.bin_idnull—
item_details.lot_numberstring—
item_details.serial_numberstring—
item_details.attributesobject—
item_details.attributes.colorstring—
item_details.attributes.sizestring—
item_details.attributes.conditionstring—
Staging
Request
curl
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

200Success - Received With P&D Auto-execution
Response body
json
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}