Shipping & Outbound Operations¶
The Zora Tech Logistics Platform ships full outbound shipment management from the /shipments page: create shipments, load LPNs through a guided scanning workflow, manifest with a carrier, generate labels and documents, dispatch, and track delivery. This guide covers the end-to-end outbound flow for dispatchers, warehouse supervisors, and carrier coordinators.
Quick Info
Audience: Dispatchers, Warehouse Supervisors, Carrier Coordinators Route: /shipments Mobile: Loading workflow supported on mobile Related: Packing & Shipping SOP | Load Planning | Order Processing
Overview¶
A shipment is the unit of outbound work that links orders, LPNs, a carrier, and tracking documents. Shipments progress through a defined status lifecycle from planning through delivery, with full audit and document retention along the way.
Key Capabilities¶
- Shipments list with operator-based filtering, URL persistence, and bulk actions
- Manual and order-driven creation — create empty shipments or spin one up directly from one or more orders
- Guided LPN-to-shipment loading with barcode scanning, customer verification, and supervisor overrides
- Carrier assignment and dispatch with tracking, bill-of-lading, MBOL, seal, and equipment numbers
- Label generation via the Fabric.js template editor and manifest generation from LPN contents
- Tracking updates and shipment audit log (new in v1.6)
- Document management — upload BOLs, packing lists, and carrier paperwork
- Cancellation with automatic rollback of orders and LPNs to their prior states
Shipment Lifecycle¶
Shipments follow a structured status workflow tied to carrier operations.
stateDiagram-v2
[*] --> PLANNED: Create
PLANNED --> LOADING: Start loading session
LOADING --> PLANNED: Abort loading
LOADING --> MANIFEST: Complete loading + manifest
PLANNED --> MANIFEST: Manifest directly
MANIFEST --> DISPATCHED: Dispatch
DISPATCHED --> IN_TRANSIT: Carrier tracking
IN_TRANSIT --> DELIVERED: Proof of delivery
PLANNED --> CANCELLED: Cancel
MANIFEST --> CANCELLED: Cancel | Status | Description |
|---|---|
| PLANNED | Shipment created; orders and LPNs may be attached but not yet loaded |
| LOADING | Active loading session — LPNs being scanned onto the shipment |
| MANIFEST | Loading complete; manifest generated and ready for carrier pickup |
| DISPATCHED | Carrier has picked up the shipment |
| IN_TRANSIT | Shipment moving through carrier network |
| DELIVERED | Proof of delivery recorded |
| CANCELLED | Shipment voided; orders returned to READY_TO_SHIP, LPNs returned to AT_STAGING |
Cancellable Statuses
Only shipments in PLANNED or MANIFEST status can be cancelled. Once DISPATCHED, a shipment must be resolved through carrier channels.
The Shipments List Page¶
Navigate to Shipments in the sidebar to open the list view at /shipments.
Filters¶
The list supports operator-based filters with bracket notation. Filter state is persisted to the URL, so any view you create can be shared, bookmarked, or reopened with a browser refresh.
| Filter | Operators | Example |
|---|---|---|
| Status | eq, ne, in, notIn | status[in]=PLANNED,LOADING |
| Carrier | eq, ne | carrierId[eq]=<uuid> |
| Customer | eq, ne | customerId[ne]=<uuid> |
| Warehouse | equals | warehouseId=<uuid> |
| Date range | startDate, endDate | startDate=2026-04-01&endDate=2026-04-18 |
| Search | free text | search=SHP-001 — matches shipment number, tracking, BOL, MBOL |
The legacy ?status=PLANNED format is still honored and treated as eq. By default the list excludes DELIVERED shipments to keep the active workload front-and-center; toggle the Show delivered filter to include them.
URL Filter Persistence
Any combination of filters you apply is reflected in the URL. Bookmark frequent views — for example, all MANIFEST shipments for a specific carrier ready for same-day pickup — and share the link with teammates.
Statuses at a Glance¶
Shipments are color-coded by status in the list: PLANNED (neutral), LOADING (blue), MANIFEST (amber), DISPATCHED / IN_TRANSIT (teal), DELIVERED (green), CANCELLED (grey).
Bulk Actions¶
Select multiple rows using the row checkboxes to perform bulk actions:
- Bulk assign carrier — set a single carrier across all selected shipments
- Bulk manifest — generate manifests for all eligible selected shipments
- Bulk export — download a CSV of the current selection
- Bulk cancel — cancel multiple shipments (still respects the PLANNED/MANIFEST status rule)
Bulk Cancel Caveat
Bulk cancel is atomic per shipment, not across the batch. If one shipment fails the eligibility check, the remainder still process. Review the results panel for any skipped entries.
Creating a Shipment¶
From the Shipments List¶
- Click Create Shipment from the
/shipmentspage - Choose a creation mode:
- From orders — pick one or more
READY_TO_SHIPorders - From staging — consolidate LPNs already sitting in a staging area
- Empty — create a shell shipment and add orders/LPNs later
- Enter the basic shipment details:
- Customer (auto-filled when created from orders)
- Origin — warehouse location or party address
- Destination — customer address (polymorphic: party or warehouse)
- Carrier (optional at creation — can be assigned later)
- Requested pickup date
The system generates a shipment number (SHP-XXXX) automatically. The shipment opens in PLANNED status.
API: POST /shipments — create from orders; POST /shipments/from-staging — create from a staging area consolidation.
From an Order Detail Page¶
On an order in READY_TO_SHIP status, click Add to Shipment to either:
- Create a new shipment with this order, or
- Attach the order to an existing
PLANNEDshipment for the same customer
Adding Orders to an Existing Shipment¶
From a shipment detail page, click Add Orders and select orders to attach.
API: PUT /shipments/:id/orders — body { orderIds: string[], force?: boolean }.
Customer Mismatch Confirmation (v1.6)
If any selected order belongs to a different customer than the shipment, the API responds with 409 Conflict and the UI presents a customer-mismatch confirmation dialog listing every mismatched order and its customer. To proceed, click Confirm and Add Anyway — the request is retried with force: true. To back out, click Cancel and remove the mismatched orders from your selection.
Mis-consolidation into the wrong customer's shipment is the most common cause of mis-shipments. The confirmation dialog exists specifically to stop that error at the warehouse before labels print.
LPN-to-Shipment Loading Workflow¶
Loading is the scan-driven process of moving picked LPNs from staging onto a specific shipment. It runs as a loading session with real-time validation, barcode verification, and optional supervisor overrides.
Starting a Loading Session¶
- Open the target shipment and click Start Loading
- The system creates a loading session, locks the shipment against concurrent edits, and transitions it to
LOADINGstatus - The loading dashboard shows:
- Expected LPNs (from attached orders and/or pre-added LPNs)
- Loaded count vs. total
- Weight and cube progress
- Session event log
API: POST /shipments/:id/loading/start.
One Active Session Per Shipment
A shipment can only have one active loading session at a time. If another user tries to start a session on the same shipment, the API returns 409 Conflict. Use GET /loading-sessions/active to see your in-progress sessions across all shipments.
Scanning LPNs¶
- Focus the barcode scanner on the LPN label
- The scanned barcode is sent to
POST /shipments/:id/loading/scan-lpn - The system performs multi-level validation:
- LPN exists and is in the current warehouse
- LPN status is
AT_STAGINGor otherwise loadable - Customer match — LPN contents belong to the shipment's customer
- Not already loaded on another active shipment
- The response returns one of three levels:
- Success — LPN loaded; progress counter advances
- Warning — loaded with caveats (e.g. different pick list, expiring lot)
- Error — rejected with reason code; LPN is not loaded
Customer Mismatch During Loading (v1.6)¶
If a scanned LPN's contents belong to a different customer than the shipment, the scan is blocked with an error. There is no "force-load" path from the scanner — this is deliberate. LPNs belonging to the wrong customer must be returned to staging and routed to the correct shipment.
No Override for Customer Mismatch
Unlike the order-to-shipment confirmation dialog, the loading workflow does not allow overriding a customer mismatch. The correct remediation is to remove the LPN from the scan list and resolve the allocation upstream (pick list, order linkage).
Pre-validation (Without Loading)¶
For workflows that need to confirm an LPN is loadable before committing, call POST /shipments/:id/loading/validate-lpn. This runs the same validation pipeline but does not persist the load.
Removing an LPN from an Active Session¶
If an LPN was loaded in error:
- In the session UI, click Remove next to the LPN row
- The LPN is returned to
AT_STAGINGstatus and decremented from the session counters - API:
DELETE /shipments/:shipmentId/loading/lpn/:lpnIdwith{ reason }
Completing the Loading Session¶
- Once the counter reads complete (all expected LPNs scanned), click Complete Loading
- The session closes; the shipment moves from
LOADINGto a state ready for manifest
API: POST /shipments/:id/loading/complete.
Supervisor Override for Partial Loads¶
If a shipment must ship short (missing LPN, damaged goods pulled off the truck), a user with the shipment:update permission can complete the session with a supervisor override:
- Click Complete with Override
- Enter a reason (required) — free text, captured in the audit log
- Confirm
API: POST /shipments/:id/loading/supervisor-override with { action: 'complete_partial', reason }.
Override Reasons Are Audited
Every supervisor override is written to the shipment audit log with the supervisor's user ID, the reason, and a timestamp. Use plain language ("missing LPN ABC123 — still at customer staging, next truck") rather than opaque codes — the audit trail is read by the customer service team when follow-up is needed.
Aborting a Session¶
To cancel a loading session without saving progress, click Abort Loading. All scanned LPNs are returned to AT_STAGING and the shipment reverts to PLANNED.
API: DELETE /shipments/:id/loading/abort with { reason }.
Carrier Assignment and Booking¶
Assigning a Carrier¶
Carrier assignment can happen at creation time or any time before manifest:
- Open the shipment and click Assign Carrier
- Select the carrier from the dropdown (carriers are configured in Administration → Carriers)
- Select a service level (Ground, Express, LTL, etc. — pulled from the carrier's configured services)
- Optionally enter a carrier reference number if the booking was made externally
This updates the shipment via PUT /shipments/:id/tracking (which also accepts carrierReference and related identifiers) or the dedicated carrier assignment action on the shipment detail page.
Booking / Manifesting¶
Once loading is complete and a carrier is assigned, generate the manifest to mark the shipment ready for carrier pickup:
- Click Preview Manifest to review the aggregated LPN contents —
GET /shipments/:id/manifest-preview - Verify totals (weight, cube, piece count, declared value)
- Click Manifest Shipment —
POST /shipments/:id/manifest - Optionally provide:
- Manifest number — if omitted, the system generates one
- Carrier reference — carrier's internal booking ID
- Bill of lading number — for LTL/freight shipments
The shipment status moves to MANIFEST, all LPNs are progressed to SHIPPED status and cleared from their staging areas, and the shipment is ready for carrier pickup.
Manifest vs. Dispatch
Manifest = paperwork complete and ready for pickup. Dispatch = carrier has physically picked up the shipment. These are two distinct events. A shipment can sit in MANIFEST for hours or days until the carrier arrives.
Dispatch¶
When the carrier picks up:
- Click Dispatch on the shipment detail page
- Enter or confirm:
- Tracking number (uses existing tracking number if one is already set)
- Actual pickup date/time (defaults to now)
- Notes
API: POST /shipments/:id/dispatch. The shipment moves to DISPATCHED status and all attached LPNs progress to DISPATCHED status.
Labels and Manifests¶
Shipping Labels¶
Labels are generated from the Fabric.js template editor, a drag-and-drop designer for carrier-compliant labels, BOLs, packing slips, and custom forms.
- From the shipment detail page, click Generate Label
- Select a template (or design one in Administration → Templates)
- Template fields bind to shipment data via the data-binding panel — tracking number, addresses, barcode, LPN counts, weight, customer PO, etc.
- Preview the rendered label
- Click Print or Download PDF
Templates are reusable across shipments. Common templates shipped out of the box:
- 4×6 shipping label (ZPL-friendly, barcode-first)
- Letter-size packing slip with itemized contents
- BOL / Straight Bill of Lading for LTL
- Custom carrier-specific labels
Template Editor Lives Elsewhere
The template editor itself is documented in Administration → Templates. This guide only covers generating labels for a specific shipment from an existing template.
Manifests¶
The manifest is the consolidated shipping document aggregating every LPN and line-level item on the shipment. Generate it via the Manifest Shipment action (see Booking / Manifesting above).
Manifest output is available as PDF download from the shipment detail page and is automatically attached to the shipment's document list.
Shipment Documents¶
Upload additional paperwork (signed BOLs, customs docs, inspection reports) via the Documents tab:
- List:
GET /shipments/:id/documents - Upload:
POST /shipments/:id/documents(multipart) - Download:
GET /shipments/:id/documents/:docId/download - Delete:
DELETE /shipments/:id/documents/:docId
Documents are scoped to the shipment's customer for downstream billing and portal visibility.
Tracking¶
Viewing Tracking¶
The shipment detail page displays a Tracking panel with:
- Current carrier tracking number
- Bill of lading / MBOL / seal / equipment numbers
- Event history from the carrier (when carrier integration is enabled)
- Estimated delivery date
Updating Tracking Fields¶
All tracking-related identifiers can be set or updated at any point via the tracking editor:
- Tracking number
- Bill of lading number (BOL)
- Master bill of lading number (MBOL) — for consolidated freight
- Carrier reference
- Seal number
- Equipment number (trailer/container)
- Notes
API: PUT /shipments/:id/tracking.
MBOL for Consolidated Freight
MBOL (Master BOL) is used when multiple shipments roll up under a single freight-forwarder move. The individual shipment's BOL is the "house" BOL; the MBOL ties it to the consolidated move. Set both if your shipment is moving as part of a larger consolidation.
Status Updates¶
Status transitions from MANIFEST through DELIVERED can be driven manually from the detail page (Mark Delivered, Mark In Transit) or automatically from carrier tracking webhooks when the integration is configured. Status changes are recorded in the shipment audit log with the user ID (for manual changes) or the webhook source (for automatic changes).
Shipment Audit Log (v1.6)¶
Every shipment has a complete audit log accessible from the Audit Log tab on the shipment detail page.
What's Recorded¶
- Shipment creation, updates, cancellation
- Order attach/detach events (including any customer-mismatch force-add with the user who confirmed)
- LPN add/remove events
- Loading session start, scan, complete, abort, supervisor override
- Manifest, dispatch, tracking updates
- Document upload/delete
- Status transitions (with prior and new status)
Each entry captures who (user ID and display name), when (ISO-8601 timestamp), what (action type), and details (JSON payload with diff and metadata).
Filtering¶
The audit log view supports filters by:
- Action type (e.g. only show
loading-session.*events) - User
- Date range
Exporting¶
Click Export Audit Log to download a CSV of the currently filtered entries — useful for compliance reporting and customer dispute resolution.
New in v1.6
The per-shipment audit log UI was introduced in v1.6 as part of the mis-shipment investigation work. It surfaces the same data that was previously only accessible via backend queries, now with filtering and export built into the shipment detail page.
Cancellation¶
Cancelling a shipment rolls back every downstream effect atomically. It is only allowed for shipments in PLANNED or MANIFEST status.
What Happens on Cancel¶
- Any active loading session is auto-aborted
- All attached orders are returned to
READY_TO_SHIPstatus - All attached LPNs are returned to
AT_STAGINGstatus - The shipment status is set to
CANCELLEDwith the cancellation reason, user, and timestamp recorded - A
shipment.cancelledevent is emitted for downstream consumers (notifications, billing)
How to Cancel¶
- Open the shipment and click Cancel Shipment
- Enter a cancellation reason (required)
- Confirm
API: POST /shipments/:id/cancel with { reason }.
Cancellation Is Atomic
If any step of the cancellation fails (for example, an LPN can no longer be returned to staging because the staging area was deleted), the entire operation is rolled back and the shipment stays in its prior status. Investigate the failure before retrying.
Cannot Cancel After Dispatch
Once a shipment is DISPATCHED, cancellation is not supported through the platform. You must coordinate directly with the carrier to recall or reroute the shipment, then record the outcome as notes on the shipment.
Returns Processing¶
Not Yet Available
Returns processing (RMA creation, disposition workflows, refund/exchange processing, restock-to-inventory) is not yet implemented in the platform. It is the genuine remaining gap in the outbound/reverse-logistics suite.
Until the returns module ships, inbound receipts of returned goods must be handled through the regular Receiving Operations flow with a blind-receiving note indicating "customer return" in the comments.
Track the returns roadmap with your Zora Tech account team.
Mobile Support¶
The shipment loading workflow is fully supported on mobile. Mobile is recommended for floor users because of camera-based barcode scanning:
- Start Loading, Scan LPN, Complete Loading, Abort, Remove LPN — all available from the mobile shipment detail page
- Tracking update and Mark Delivered — available on mobile for drivers and field staff
See Mobile Workflows for the full mobile picking/packing/loading flow.
Common Scenarios¶
Scenario 1: Same-Customer Multi-Order Consolidation¶
- Create a shipment for the customer
- Add all ready orders via Add Orders
- Pick each order; LPNs end up in the customer's staging lane
- Start a loading session and scan all LPNs
- Complete loading, manifest, dispatch
Scenario 2: Walk-Up Order Added After Loading Started¶
- Attach the new order via
PUT /shipments/:id/orders— the shipment is already inLOADING - Pick the new order; the LPN lands in staging
- Continue the active loading session — scan the new LPN; the loader auto-expands the expected set
- Complete loading once the new LPN is verified
Scenario 3: Customer Mismatch at the Order Stage¶
- User tries to add Customer B's order to Customer A's shipment
- API returns 409 with the mismatch list
- UI shows the customer-mismatch dialog
- User cancels and instead creates or locates Customer B's own shipment
Scenario 4: Short Ship (Missing LPN at Dock)¶
- Start loading; scan every available LPN
- One LPN cannot be located — supervisor is called
- Supervisor clicks Complete with Override, enters reason "LPN LPN-4421 not located — investigating"
- Shipment manifests short; the audit log records the override
- Operations creates a follow-up shipment for the missing LPN once located
Scenario 5: Cancel and Reship¶
- Customer changes address after manifest but before dispatch
- Cancel the shipment with reason "customer address change — reshipping"
- Orders return to
READY_TO_SHIP, LPNs return to staging - Update the destination on the order (or create a new shipment with the corrected address)
- Reload and remanifest
Troubleshooting¶
| Issue | Solution |
|---|---|
| "Customer mismatch" dialog on Add Orders | Review the mismatched orders. If intentional (e.g. 3PL consolidation), click Confirm and Add Anyway — the override is audited. Otherwise remove the mismatched orders from the selection. |
| Cannot start loading session (409) | Another user has an active loading session on this shipment. Check GET /loading-sessions/active or the loading dashboard, and either take over or wait for the existing session to complete. |
| LPN scan rejected — "not in warehouse" | The LPN is in a different warehouse. Transfer it to the shipment's warehouse first, or start a separate shipment at the LPN's current warehouse. |
| LPN scan rejected — "customer mismatch" | LPN contents belong to another customer. Return the LPN to staging and route it to the correct customer's shipment. |
| Cannot cancel shipment | Only PLANNED and MANIFEST shipments can be cancelled. For DISPATCHED and later, coordinate with the carrier. |
| Manifest action is disabled | Check that the shipment has at least one loaded LPN, a carrier assigned, and is in a status that allows manifesting (PLANNED with loading complete, or LOADING). |
| Tracking webhook not updating status | Verify the carrier integration credentials in Administration → Carriers. Tracking webhooks require the carrier's API keys and a reachable webhook URL. |
| Audit log entry shows "system" user | System-generated events (e.g. auto-abort triggered by shipment cancellation) are attributed to the system user. The correlating manual action will be recorded in a separate entry with the human user's ID. |
API Quick Reference¶
| Operation | Method + Path |
|---|---|
| List shipments | GET /shipments |
| Get shipment | GET /shipments/:id |
| Get full details | GET /shipments/:id/details |
| Create from orders | POST /shipments |
| Create from staging | POST /shipments/from-staging |
| Add orders | PUT /shipments/:id/orders |
| Add LPNs | POST /shipments/:id/lpns |
| Remove LPNs | DELETE /shipments/:id/lpns |
| Start loading | POST /shipments/:id/loading/start |
| Scan LPN | POST /shipments/:id/loading/scan-lpn |
| Validate LPN (no load) | POST /shipments/:id/loading/validate-lpn |
| Loading status | GET /shipments/:id/loading/status |
| Complete loading | POST /shipments/:id/loading/complete |
| Abort loading | DELETE /shipments/:id/loading/abort |
| Remove LPN from session | DELETE /shipments/:id/loading/lpn/:lpnId |
| Supervisor override | POST /shipments/:id/loading/supervisor-override |
| Manifest preview | GET /shipments/:id/manifest-preview |
| Manifest shipment | POST /shipments/:id/manifest |
| Update tracking | PUT /shipments/:id/tracking |
| Dispatch | POST /shipments/:id/dispatch |
| Cancel | POST /shipments/:id/cancel |
| List documents | GET /shipments/:id/documents |
| Upload document | POST /shipments/:id/documents |
| Download document | GET /shipments/:id/documents/:docId/download |
| Ready for pickup | GET /shipments/ready-for-pickup/:warehouseId |
Related Guides¶
- Packing & Shipping SOP
- Load Planning
- Order Processing
- Mobile Workflows
- Carrier Administration
- Template Editor (Labels & BOLs)
Need Help?¶
Questions?
User Guide | Last Updated: April 2026