Package Transfers
5 API calls in this section.
Endpoints for transferring packages/deliveries between warehouses. Supports two modes:
system_only: Updates warehouse association in the system without creating delivery operations.delivery_operation: Creates delivery orders and optionally a waybill for physical movement managed by the delivery module.
List Package Transfers
/warehousing/package-transfersRetrieves a paginated list of warehouse-to-warehouse Package Transfer audit records.
Waybill visibility
Every eligible warehouse-to-warehouse Waybill with at least one package has one waybill Package Transfer projection and is returned for its source or destination warehouse whatever its Waybill status, including in_transit, received, and closed. Empty Waybills, same-warehouse routes, and routes without a valid warehouse destination do not create a projection. The projection is created in the same transaction as the first delivery attachment; existing missing projections are backfilled idempotently.
Search
search is case-insensitive, limited to 100 characters, and matches Waybill number plus source or destination warehouse name or code.
Mode filtering
Package Transfers have two stored modes: system_only and delivery_operation. Delivery-operation transfers have an operation_type of single_delivery or waybill. Use mode and operation_type directly; neither value is a status.
Exact pill requests
All: omit both filters.
System only:
mode=system_only.Single delivery:
mode=delivery_operation&operation_type=single_delivery.Waybill:
mode=delivery_operation&operation_type=waybill.
operation_type implies mode=delivery_operation when mode is omitted. Sending mode=system_only together with an operation type returns HTTP 400. column_filters supports the same mode and operation_type fields and takes precedence over standalone parameters. status and transfer_type are not supported Package Transfer filters and return HTTP 400. Search, mode, and operation type are applied in the database before pagination, so response total is the filtered result count.
Related lifecycle object
A single_delivery transfer is created only when selection resolves to exactly one delivery and no inventory items. Its list row includes that entity as the singular delivery object with id, delivery_code, barcode, and delivery status. The delivery property is not added to Waybill or system-only rows. A Waybill transfer instead exposes its linked waybill object and Waybill status. The existing delivery_ids audit field remains available for backward compatibility.
Statistics
stats.total, stats.system_only, stats.single_delivery, and stats.waybill describe the same Package Transfer population after tenant, warehouse, and search filters. The selected mode/operation type does not narrow stats, allowing the frontend to render all mechanism pills. stats.total always equals the sum of the three counters. A linked Waybill's lifecycle status remains available only as package_transfers[].waybill.status for related-detail display.
Requires valid token with view or manage permissions.
Frontend integration contract
Send the exact mode/operation_type combinations above. Use each row's existing mode and operation_type fields. For single_delivery, render the singular delivery object and use delivery.status; do not expect a delivery property on Waybill or system-only rows. For waybill, use the nested waybill object and waybill.status. Use the four stats fields for pills. Do not send status and do not use either related lifecycle status as the Package Transfer list status. Treat HTTP 400 as an invalid filter request and display the localized response message.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idRequired | string | UUID of the tenant (required) Example: |
modeOptional | string | Optional Package Transfer mode filter: |
operation_typeOptional | string | Optional delivery-operation subtype filter: |
source_warehouse_idOptional | string | Filter by source warehouse (optional) |
destination_warehouse_idOptional | string | Filter by destination warehouse (optional) |
searchOptional | string | Optional case-insensitive search, maximum 100 characters. Matches Waybill number and source or destination warehouse name/code. |
column_filtersOptional | string | Optional JSON object supporting mode and |
pageOptional | string | Page number (optional, default: 1) Example: |
limitOptional | string | Items per page (optional, backend default: 25) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/warehousing/package-transfers?tenant_id=${TENANT_ID}&mode=&operation_type=&source_warehouse_id=&destination_warehouse_id=&search=&column_filters=&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": "Package transfers retrieved successfully",4 "package_transfers": [5 {6 "id": "transfer-uuid-1",7 "mode": "delivery_operation",8 "operation_type": "single_delivery",9 "notes": "Single package movement",10 "delivery_ids": [11 "delivery-uuid-1"12 ],13 "created_at": "2026-05-22T11:00:00Z",14 "source_warehouse": {15 "id": "wh-source-uuid",16 "name": "Main Warehouse",17 "code": "WH-A"18 },19 "destination_warehouse": {20 "id": "wh-dest-uuid",21 "name": "Branch Warehouse",22 "code": "WH-B"23 },24 "waybill": null,25 "performer": {26 "id": "user-uuid-1",27 "full_name": "Warehouse User"28 },29 "delivery": {30 "id": "delivery-uuid-1",31 "delivery_code": "DEL1001",32 "barcode": "PKG-1001",33 "status": "pending"34 }35 },36 {37 "id": "transfer-uuid-2",38 "mode": "delivery_operation",39 "operation_type": "waybill",40 "notes": "Batch transfer to branch warehouse",41 "delivery_ids": [42 "delivery-uuid-2",43 "delivery-uuid-3"44 ],45 "created_at": "2026-05-22T11:05:00Z",46 "source_warehouse": {47 "id": "wh-source-uuid",48 "name": "Main Warehouse",49 "code": "WH-A"50 },51 "destination_warehouse": {52 "id": "wh-dest-uuid",53 "name": "Branch Warehouse",54 "code": "WH-B"55 },56 "waybill": {57 "id": "waybill-uuid-1",58 "waybill_number": "WB00001",59 "status": "drafted"60 },61 "performer": {62 "id": "user-uuid-1",63 "full_name": "Warehouse User"64 }65 }66 ],67 "page": 1,68 "limit": 20,69 "total": 7,70 "stats": {71 "total": 7,72 "system_only": 3,73 "single_delivery": 2,74 "waybill": 275 }76}Create Package Transfer - System Only
/warehousing/package-transfersMarks packages as transferred to another warehouse without creating delivery operations. Use when the movement already happened or doesn't need delivery tracking.
Requires 'manage:operations:tenant' or 'manage:module:warehouse' permission.
Behavior
Resolves barcodes to deliveries (tries barcode first, then
delivery_code)Updates
pickup_warehouse_idanddropoff_warehouse_idon each deliveryDoes NOT create a waybill, delivery order, or driver assignment
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idRequired | string | UUID of the tenant (required) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
modeRequired | string | Must be |
source_warehouse_idRequired | string | UUID of the source warehouse |
destination_warehouse_idRequired | string | UUID of the destination warehouse |
package_barcodesRequired | array<string> | Array of package barcodes or delivery codes |
notesOptional | string | Transfer notes |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/package-transfers?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "mode": "system_only",6 "source_warehouse_id": "{{source_warehouse_id}}",7 "destination_warehouse_id": "{{destination_warehouse_id}}",8 "package_barcodes": [9 "PKG-1001",10 "PKG-1002"11 ],12 "notes": "Moved manually by warehouse team"13}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "message": "Packages transferred successfully",4 "transfer_id": "transfer-uuid-1",5 "transferred_count": 2,6 "delivery_ids": [7 "del-uuid-1",8 "del-uuid-2"9 ],10 "mode": "system_only",11 "rejected": []12}Create Package Transfer - Single Delivery Operation
/warehousing/package-transfersCreates a delivery operation for a single package transfer between warehouses. Sets the delivery's pickup/dropoff warehouses so it can be assigned to a driver via the delivery module.
Behavior
Sets
pickup_warehouse_idanddropoff_warehouse_idon the deliveryDelivery is now ready for driver assignment in the delivery module
No waybill is created for single packages
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idRequired | string | UUID of the tenant (required) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
modeRequired | string | Must be |
operation_typeOptional | string |
|
source_warehouse_idRequired | string | Source warehouse UUID |
destination_warehouse_idRequired | string | Destination warehouse UUID |
package_barcodesRequired | array<string> | Array with 1 barcode |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/package-transfers?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "mode": "delivery_operation",6 "operation_type": "single_delivery",7 "source_warehouse_id": "{{source_warehouse_id}}",8 "destination_warehouse_id": "{{destination_warehouse_id}}",9 "package_barcodes": [10 "PKG-1001"11 ]12}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "message": "Delivery transfer created successfully",4 "transfer_id": "transfer-uuid-2",5 "mode": "delivery_operation",6 "operation_type": "single_delivery",7 "delivery_ids": [8 "del-uuid-1"9 ],10 "rejected": []11}Create Package Transfer - Waybill Operation
/warehousing/package-transfersThin alias over canonical warehouse Waybill validation/create. Idempotency-Key is required. Selection may combine package barcodes, delivery IDs, and individually tracked inventory IDs. The service applies one destination lock, reuses compatible Draft/Pending or staged-parent deliveries, creates Draft deliveries only for raw inventory, and returns enriched Waybill detail with operation_result. Creation stops at drafted; seal, driver warehouse_handover, staff receipt, and explicit close remain separate.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idRequired | string | UUID of the tenant (required) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Idempotency-Key | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
mode | string | — |
operation_type | string | — |
source_warehouse_id | string | — |
destination_warehouse_id | string | — |
package_barcodes | array<string> | — |
delivery_ids | array<string> | — |
inventory_item_ids | array<string> | — |
new_delivery_defaults | object | — |
new_delivery_defaults.customer_id | string | — |
new_delivery_defaults.delivery_service_id | string | — |
new_delivery_defaults.payer_type | string | — |
new_delivery_defaults.payment_method | string | — |
Show 1 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
notes | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/package-transfers?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --header "Idempotency-Key: package-transfer-waybill-${_GUID}" \5 --data-raw '{6 "mode": "delivery_operation",7 "operation_type": "waybill",8 "source_warehouse_id": "{{source_warehouse_id}}",9 "destination_warehouse_id": "{{destination_warehouse_id}}",10 "package_barcodes": [11 "PKG-1001"12 ],13 "delivery_ids": [14 "{{delivery_id}}"15 ],16 "inventory_item_ids": [17 "{{inventory_item_id}}"18 ],19 "new_delivery_defaults": {20 "customer_id": "{{customer_id}}",21 "delivery_service_id": "{{delivery_service_id}}",22 "payer_type": "sender",23 "payment_method": "cash"24 },25 "notes": "Batch transfer to branch"26}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "message": "Waybill transfer created successfully",4 "transfer_id": "transfer-uuid-3",5 "mode": "delivery_operation",6 "operation_type": "waybill",7 "delivery_ids": [8 "del-uuid-1",9 "del-uuid-2",10 "del-uuid-3"11 ],12 "waybill_id": "waybill-uuid-1",13 "waybill_number": "WB00001",14 "status": "drafted",15 "rejected": []16}Validate Package Barcodes
/warehousing/package-transfers/validateRead-only alias over canonical mixed Waybill preflight. Source warehouse is required. Destination may be inferred from a compatible delivery; raw-only inventory requires it explicitly. Response contains accepted deliveries/items, localized rejected rows, destination lock, defaults requirement, and can_create.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idRequired | string | UUID of the tenant (required) Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
mode | string | — |
operation_type | string | — |
source_warehouse_id | string | — |
destination_warehouse_id | string | — |
package_barcodes | array<string> | — |
delivery_ids | array<string> | — |
inventory_item_ids | array<string> | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/warehousing/package-transfers/validate?tenant_id=${TENANT_ID}" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "mode": "delivery_operation",6 "operation_type": "waybill",7 "source_warehouse_id": "{{source_warehouse_id}}",8 "destination_warehouse_id": "{{destination_warehouse_id}}",9 "package_barcodes": [10 "PKG-1001",11 "PKG-9999"12 ],13 "delivery_ids": [14 "{{delivery_id}}"15 ],16 "inventory_item_ids": [17 "{{inventory_item_id}}"18 ]19}'Replace {{placeholders}} with your own values before sending.
Response examples
1{2 "success": true,3 "valid": [4 {5 "barcode": "PKG-1001",6 "delivery_id": "del-uuid-1",7 "delivery_code": "DEL-001",8 "status": "staged_at_warehouse",9 "current_warehouse_id": "wh-uuid-1"10 },11 {12 "barcode": "PKG-1002",13 "delivery_id": "del-uuid-2",14 "delivery_code": "DEL-002",15 "status": "staged_at_warehouse",16 "current_warehouse_id": "wh-uuid-1"17 }18 ],19 "invalid": [20 {21 "barcode": "PKG-9999",22 "reason": "not_found"23 }24 ],25 "total_scanned": 3,26 "valid_count": 2,27 "invalid_count": 128}