Pack
After items are picked, your operators work at a packing station and build the parcels. Carriyo records this work as a Pack: a unit of packing work with its own data model and lifecycle, separate from the pick that fed into it.
Picking is optional before packing. Line items in allocated
or picked status can both enter a pack.
The model
A pack carries:
pack_id. Unique identifier, prefixedPAK_(e.g.PAK_87).partner_location_id. The fulfillment location.packing_station. The station where the work happens.packer. The user doing the work.status. The lifecycle state.items. The line items being packed, with packing progress.packages. The physical parcels being built.documents. Attached files, typically the auto-generated packing-list PDF.
Both packing_station and packer must be set before a pack
can start. In the Fulfillment App the operator chooses a station. Via the API, you set them at creation, or while
the pack is open via the reassign endpoint, which takes either
or both.
Pack items
Each pack item carries product metadata copied from the line item, plus packing progress:
quantityandquantity_packed. Total requested versus placed into packages so far.pick_id. The pick this item came from, if any. Affects cancellation: if the pack is cancelled, items with apick_idrevert topicked; items without one revert toallocated.selection_method. How the packer confirmed the item:SCANNER,CAMERA, orMANUAL. It is stored on the pack item, not on the package, and a pack-items call without it clears the earlier value.- Product fields:
sku,description,barcode,image_link,weight,unit_price,origin_country,hs_code,dangerous_goods.
Packages (parcels)
Each package on a pack is a physical parcel:
package_id. Unique identifier, prefixedPKG_(e.g.PKG_456).order_idandfulfillment_order_id. Which order and fulfillment order this parcel belongs to. All items in a package must come from the same fulfillment order.package_type. A free-text label for the kind of package.dimension,empty_weight,max_weight. Physical measurements. A package also has aweightfield, but no pack operation sets it, so shipment parcels useempty_weight.items. The line items placed in this parcel, each with aline_item_idandquantity.shipment_id. Set when a shipment is created from this package.
A pack can have many packages: a single order can split across several parcels. Creating a shipment takes one or more packages of the same fulfillment order and makes one parcel per package.
Pack lifecycle
open ──start──▶ processing ──complete──▶ completed (terminal)
│ │
└── cancel ────────┴───────────────▶ cancelled (terminal)
| Status | Meaning |
|---|---|
open | Created, waiting for the packer to start. |
processing | The packer is actively building parcels. |
completed | All items packed and handed off to Shipping or a collection. Terminal. |
cancelled | Voided. Line items reverted, live shipments cancelled. Terminal. |
Status transitions
| From | To | Trigger |
|---|---|---|
open | processing | POST /orders/packs/{packId}/start. Requires packing_station and packer to be set. |
open | cancelled | POST /orders/packs/{packId}/cancel. |
processing | completed | POST /orders/packs/{packId}/complete. Every item must be fully packed, and every package that needs one must have a shipment (see below). |
processing | cancelled | POST /orders/packs/{packId}/cancel. |
The packing workflow
A typical pack workflow follows these steps:
- Create the pack with the line items to pack.
- Assign packer and station (at creation, or via reassign).
- Start the pack.
- Add packages for each parcel you want to build.
- Pack items into packages, in one or more calls.
- Create shipments from the packages (every fulfillment order except a local collection).
- Complete the pack with the ship zone.
While the pack is processing, you can unpack items (reverse a
pack action). Removing a package is refused once that package
has a live shipment; resetting all packages is refused once any
package has one. A pack or unpack quantity above what remains is
rejected, and nothing in that call is saved.
Effect on fulfillment-order line items
Pack operations change the fulfillment-order line-item status. These side effects happen automatically.
| Pack event | Line-item status change |
|---|---|
| Pack created | allocated or picked → pack_in_progress. Partial quantities split the line item. |
| Pack completed | pack_in_progress → fulfilled. |
Pack cancelled (item had pick_id) | pack_in_progress → picked |
Pack cancelled (item had no pick_id) | pack_in_progress → allocated |
On pack completion, Carriyo also:
- Records one fulfillment per fulfillment order, with a new
fulfillment_id. Fulfilled line items keep theshipment_idsthat shipment creation added. - Applies the
ship_zoneto each shipment and moves it toready_to_ship. Both happen shortly after completion. A shipment with no carrier waits until one is assigned, and the shipment-status webhook fires when it reachesready_to_ship. - For each fulfillment order with
delivery_method = COLLECTIONand acustomer_collection_address, creates a customer collection inopenstatus. A local collection has no shipment. A remote collection's packages already have their shipment to the collection point.
Completing a pack
To complete a pack, the operator needs:
- Every line item fully packed (
quantity_packed = quantity). - A shipment (created via the create-shipment endpoint) for each
package holding non-digital items, unless the fulfillment order
is a local collection. An item is digital when its order line
item has the
digitalflag. - A ship zone in the request body, required when any package
has a
shipment_id. It names a ship zone configured at the location the shipments pick up from; an unknown one is dropped without an error.
Every shipment on the pack must be booked before the pack can
complete. Completion sends one order webhook per
fulfillment order it fulfills, and the shipment webhook reports
ready_to_ship later. The completion webhook doesn't include
the new customer collections yet; read the order to find them.
Shipment creation from a pack
Before completing, you create shipments from the packed packages:
POST /orders/packs/{packId}/create-shipment takes an array
of package_ids and an optional carrier_account. Without a
carrier account, your shipping automation rules choose the
carrier when the shipment is booked. All selected packages must
belong to the same order and fulfillment order. Each package
becomes a parcel in the shipment, and the call sends an order
webhook for the shipped line items.
A local collection can't have a shipment, because its parcel doesn't move; its collection is created when the pack completes. A remote collection needs a shipment to the collection point, like a delivery.
Lookup endpoints vs full record
The list endpoints (/orders/packs/order/{orderId},
/orders/packs/fulfillment-order/{foId} and
/orders/packs/pick/{pickId}) return only pack_id, tenant,
partner_location_id, status and creation_date per pack; use
GET /orders/packs/{packId} for the full record.
How it fits with other modules
- Fulfillment. The parent module.
- Pick. The upstream stage; picked items move into Pack.
- Customer collection. Pack completion creates a customer collection for local and remote collection fulfillment orders.
- Shipping. Pack completion is what
produces a
ready_to_shipshipment. - Locations. Packing stations are configured per location.
- Fulfillment App. The app warehouse operators use to run the Pack flow.