Pack

Updated May 29, 20264 min read

After items are picked, your operators check in 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 status machine, separate from the pick that fed into it.

Packing is optional if your workflow skips the pick stage. Line items in allocated or picked status can both enter a pack.

The model

A pack carries:

  • pack_id. Unique identifier, prefixed PAK_ (e.g. PAK_87).
  • 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 assigned before a pack can start. The operator picks a station when checking in at the Fulfillment App, or you can set them at creation or via the reassign endpoint.

Pack items

Each pack item carries product metadata copied from the line item, plus packing progress:

  • quantity and quantity_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 a pick_id revert to picked; items without one revert to allocated.
  • selection_method. How the packer confirmed the item: SCANNER, CAMERA, or MANUAL.
  • 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, prefixed PKG_ (e.g. PKG_456).
  • order_id and fulfillment_order_id. Which order and FO this parcel belongs to. All items in a package must come from the same FO.
  • package_type. The carton type from the merchant's packaging catalog.
  • dimension, empty_weight, max_weight, weight. Physical measurements.
  • items. The line items placed in this parcel, each with a line_item_id and quantity.
  • 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. Each package typically becomes its own shipment.

Pack lifecycle

open ──start──▶ processing ──complete──▶ completed  (terminal)
  │                  │
  └── cancel ────────┴───────────────▶ cancelled  (terminal)
StatusMeaning
openCreated, waiting for packer to start.
processingThe packer is actively building parcels.
completedAll items packed, shipments booked, handed off. Terminal.
cancelledVoided. Line items reverted, shipments cancelled. Terminal.

Status transitions

FromToTrigger
openprocessingPOST /orders/packs/{packId}/start. Requires packing_station and packer to be set.
opencancelledPOST /orders/packs/{packId}/cancel.
processingcompletedPOST /orders/packs/{packId}/complete. All items must be fully packed, all shipments booked.
processingcancelledPOST /orders/packs/{packId}/cancel.

The packing workflow

A typical pack workflow follows these steps:

  1. Create the pack with the line items to pack.
  2. Assign packer and station (at creation, or via reassign).
  3. Start the pack.
  4. Add packages for each parcel you want to build.
  5. Pack items into packages, one scan at a time.
  6. Create shipments from the packages (for delivery FOs).
  7. Complete the pack with the ship zone.

At any point before completion, you can unpack items (reverse a pack action), remove packages, or reset all packages to start over.

Effect on fulfillment-order line items

Pack operations drive the fulfillment-order line-item status. These side effects happen automatically.

Pack eventLine-item status change
Pack createdallocated or pickedpack_in_progress. Partial quantities split the line item.
Pack completedpack_in_progressfulfilled.
Pack cancelled (item had pick_id)pack_in_progresspicked
Pack cancelled (item had no pick_id)pack_in_progressallocated

On pack completion, Carriyo also:

  • Marks each shipment as ready_to_ship (fires the shipment-status webhook).
  • Applies the ship_zone to each shipment.
  • For fulfillment orders with delivery_method = COLLECTION and a customer_collection_address, creates a customer collection record in open status. No shipment is created for store-pickup collection FOs.

Completing a pack

To complete a pack, the operator needs:

  • Every line item fully packed (quantity_packed >= quantity).
  • A shipment for each non-collection, non-digital package (created via the create-shipment endpoint).
  • A ship zone in the request body (required when any package has a shipment_id).

The ready_to_ship transition is the only signal your systems receive across the fulfillment/shipping boundary.

Shipment creation from a pack

Before completing, you book shipments from the packed packages:

POST /orders/packs/{packId}/create-shipment takes an array of package_ids and an optional carrier_account. All selected packages must belong to the same order and fulfillment order. Each package becomes a parcel in the shipment.

Store-pickup collection FOs are blocked from shipment creation. Collections are auto-created when the pack completes instead.

Lookup endpoints vs full record

The list endpoints (/orders/packs/order/{orderId}, /orders/packs/fulfillment-order/{foId}, /orders/packs/pick/{pickId}) return lookup records with only summary fields: pack_id, tenant, location_id, status, and creation_date.

Use GET /orders/packs/{packId} to retrieve the full record with items, packages, documents, and timestamps.

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 click-and-collect FOs.
  • Shipping. Pack completion is what produces a ready_to_ship shipment.
  • Locations. Packing stations are configured per location.
  • Fulfillment App. The app warehouse operators use to run the Pack flow.