Skip to content

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

  1. Click Create Shipment from the /shipments page
  2. Choose a creation mode:
  3. From orders — pick one or more READY_TO_SHIP orders
  4. From staging — consolidate LPNs already sitting in a staging area
  5. Empty — create a shell shipment and add orders/LPNs later
  6. Enter the basic shipment details:
  7. Customer (auto-filled when created from orders)
  8. Origin — warehouse location or party address
  9. Destination — customer address (polymorphic: party or warehouse)
  10. Carrier (optional at creation — can be assigned later)
  11. 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 PLANNED shipment 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

  1. Open the target shipment and click Start Loading
  2. The system creates a loading session, locks the shipment against concurrent edits, and transitions it to LOADING status
  3. The loading dashboard shows:
  4. Expected LPNs (from attached orders and/or pre-added LPNs)
  5. Loaded count vs. total
  6. Weight and cube progress
  7. 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

  1. Focus the barcode scanner on the LPN label
  2. The scanned barcode is sent to POST /shipments/:id/loading/scan-lpn
  3. The system performs multi-level validation:
  4. LPN exists and is in the current warehouse
  5. LPN status is AT_STAGING or otherwise loadable
  6. Customer match — LPN contents belong to the shipment's customer
  7. Not already loaded on another active shipment
  8. The response returns one of three levels:
  9. Success — LPN loaded; progress counter advances
  10. Warning — loaded with caveats (e.g. different pick list, expiring lot)
  11. 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_STAGING status and decremented from the session counters
  • API: DELETE /shipments/:shipmentId/loading/lpn/:lpnId with { reason }

Completing the Loading Session

  1. Once the counter reads complete (all expected LPNs scanned), click Complete Loading
  2. The session closes; the shipment moves from LOADING to 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:

  1. Click Complete with Override
  2. Enter a reason (required) — free text, captured in the audit log
  3. 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:

  1. Open the shipment and click Assign Carrier
  2. Select the carrier from the dropdown (carriers are configured in Administration → Carriers)
  3. Select a service level (Ground, Express, LTL, etc. — pulled from the carrier's configured services)
  4. 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:

  1. Click Preview Manifest to review the aggregated LPN contents — GET /shipments/:id/manifest-preview
  2. Verify totals (weight, cube, piece count, declared value)
  3. Click Manifest ShipmentPOST /shipments/:id/manifest
  4. Optionally provide:
  5. Manifest number — if omitted, the system generates one
  6. Carrier reference — carrier's internal booking ID
  7. 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:

  1. Click Dispatch on the shipment detail page
  2. Enter or confirm:
  3. Tracking number (uses existing tracking number if one is already set)
  4. Actual pickup date/time (defaults to now)
  5. 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.

  1. From the shipment detail page, click Generate Label
  2. Select a template (or design one in Administration → Templates)
  3. Template fields bind to shipment data via the data-binding panel — tracking number, addresses, barcode, LPN counts, weight, customer PO, etc.
  4. Preview the rendered label
  5. 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

  1. Any active loading session is auto-aborted
  2. All attached orders are returned to READY_TO_SHIP status
  3. All attached LPNs are returned to AT_STAGING status
  4. The shipment status is set to CANCELLED with the cancellation reason, user, and timestamp recorded
  5. A shipment.cancelled event is emitted for downstream consumers (notifications, billing)

How to Cancel

  1. Open the shipment and click Cancel Shipment
  2. Enter a cancellation reason (required)
  3. 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

  1. Create a shipment for the customer
  2. Add all ready orders via Add Orders
  3. Pick each order; LPNs end up in the customer's staging lane
  4. Start a loading session and scan all LPNs
  5. Complete loading, manifest, dispatch

Scenario 2: Walk-Up Order Added After Loading Started

  1. Attach the new order via PUT /shipments/:id/orders — the shipment is already in LOADING
  2. Pick the new order; the LPN lands in staging
  3. Continue the active loading session — scan the new LPN; the loader auto-expands the expected set
  4. Complete loading once the new LPN is verified

Scenario 3: Customer Mismatch at the Order Stage

  1. User tries to add Customer B's order to Customer A's shipment
  2. API returns 409 with the mismatch list
  3. UI shows the customer-mismatch dialog
  4. User cancels and instead creates or locates Customer B's own shipment

Scenario 4: Short Ship (Missing LPN at Dock)

  1. Start loading; scan every available LPN
  2. One LPN cannot be located — supervisor is called
  3. Supervisor clicks Complete with Override, enters reason "LPN LPN-4421 not located — investigating"
  4. Shipment manifests short; the audit log records the override
  5. Operations creates a follow-up shipment for the missing LPN once located

Scenario 5: Cancel and Reship

  1. Customer changes address after manifest but before dispatch
  2. Cancel the shipment with reason "customer address change — reshipping"
  3. Orders return to READY_TO_SHIP, LPNs return to staging
  4. Update the destination on the order (or create a new shipment with the corrected address)
  5. 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


Need Help?


User Guide | Last Updated: April 2026