data-model / data-model-f1f5c163d194Markdown ↓

Explore these examples

Edit the published examples in place. Running an example sends a real request to the instance you choose. Nothing runs when you open the page.

Checking sign-in…

Choose existing records

Read records from the selected instance. Nothing is created. Select a record to use it in the walkthrough.

Sign in and choose an instance to browse records.

Selected records survive page navigation in this tab for this sign-in and instance. Switching instances or signing out clears them. Responses and editor drafts stay on this page.

Working with the Data Model — Warehousing and Logistics

Use Warehousing and Logistics to follow materials into the business, through production and out to the customer. It brings stock, reservations, planned deliveries, shipments and delivery confirmations into one working guide, even when they appear in different areas of the application.

For a printing business, the flow might begin with paper arriving from a supplier and end with pallets of finished brochures reaching several destinations. The records answer different questions along that journey: what is available, what a job needs, what the customer expects, what was packed and what was actually received.

Use IaC for infrastructure and provisioning. Use the API for runtime data. Provision warehouse locations and carriers through IaC, together with the suppliers, substrate catalogue and integrations used by your business. Use the API to receive stock, reserve materials, record production issues, plan deliveries, prepare shipments and record delivery outcomes.

This guide covers every operation in the logistics topic, including shared tools and the handover to production and ERP. Warehousing and logistics form one workflow here; their individual records retain their own identities and purposes. The Warehousing and Logistics API reference lists every operation's arguments and results, followed by input, record and enum tables.

Choose where to start

What you need to do Start here
Find a storage location or carrier Locations and carriers
Receive paper, establish stock or count a location Warehouse stock
Reserve paper and supply a printing job Materials for production
Record where and when the customer needs the work Delivery planning
Specify packing, handling or delivery requirements Delivery requirements
Create a shipment, pallet or parcel Packing and dispatch
Record quantities dispatched, received or returned Delivery confirmation
Check outstanding quantities and complete an order Fulfilment review
Investigate related records and possible effects Traceability

Read and change records safely

Start with create… for a new record and update… for changes to an existing record. These are the recommended operations for everyday work. Check the required fields and the treatment of omitted values in each input: an update is not always a partial patch. In particular, planned delivery updates use the same required input shape as creation.

Treat upsert… as an advanced option. Use it only when you understand how it identifies a record, which values it requires and what it replaces. Warehouse stock and transfer upserts can replace the whole record. They are not general shortcuts for editing one field or finding a record by an external reference.

Send the operation and its variables separately to your environment's GraphQL API using an authenticated account. Check top-level GraphQL errors and the errors { path message } inside mutation results. Continue only when errors are empty and the expected record is present. Keep the returned IDs for later requests.

Where an operation requires expectedVersion, read the record's current version first. If another change has intervened, read it again and reconcile your changes. Do not repeatedly submit the old version. Where an input accepts a requestKey, keep the key stable for a retry of the same request and use a new key for a different observation; this does not give other operations retry protection.

The examples follow the same 5,000-copy brochure job as the Production guide. The paper examples use an illustrative cover requirement of 2,500 sheets; the first outbound shipment contains 2,000 finished brochures. Sheets and finished copies are different units and different records. Replace every illustrative ID, date, destination and quantity with the values for your job. These are separate recipes, not a script to execute unchanged from top to bottom.

Read locations and carriers

A warehouse location identifies where stock is held: a warehouse, area, rack or other configured storage position. Locations can have parent locations. Read their names, codes, types and active status before selecting one for a receipt or material reservation.

A carrier identifies the organisation carrying the shipment. Read the configured carrier when preparing dispatch. Selecting it on a shipment does not itself book a collection or purchase a shipping label.

Use getWarehouseLocation or listWarehouseLocations to find storage locations, and getCarrier or listCarriers to find carriers. Their create, update, upsert and delete operations are included in the reference for completeness; manage those definitions through IaC.

Operation Use it to
Query.getWarehouseLocation Read a warehouse location.
Query.listWarehouseLocations Browse warehouse locations.
Query.getCarrier Read a carrier.
Query.listCarriers Browse carriers.
Mutation.createWarehouseLocation Create a warehouse location. Manage through IaC.
Mutation.updateWarehouseLocation Change a warehouse location. Manage through IaC.
Mutation.upsertWarehouseLocation Advanced: Create or replace a warehouse location. Prefer create/update for routine changes. Manage through IaC.
Mutation.deleteWarehouseLocation Delete a warehouse location. Manage through IaC.
Mutation.upsertCarrier Advanced: Create or replace a carrier. Prefer create/update for routine changes. Manage through IaC.
Mutation.createCarrier Create a carrier. Manage through IaC.
Mutation.updateCarrier Change a carrier. Manage through IaC.
Mutation.deleteCarrier Delete a carrier. Manage through IaC.

Receive and count warehouse stock

A warehouse stock record holds a quantity of a particular material or item at a location, together with its unit, reserved quantity and available quantity. A material lot adds batch identity and provenance. It does not hold a second, separate stock balance.

Receive paper against a purchase order

Use receivePurchaseOrder when paper arrives against an existing purchase order:

mutation ReceiveLogisticsPaper($input: ReceivePurchaseOrderInput!) {
  receivePurchaseOrder(input: $input) {
    purchaseOrder { id status }
    updatedLines { id receivedQuantity }
    stockEntries { id quantity unit availableQuantity }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "purchaseOrderId": "pur_000000a48h848r248h248h248h",
    "warehouseLocationId": "wlc_000000448h848r248h248h248h",
    "receivedLines": [
      {
        "purchaseOrderLineId": "pul_000000c48h848r248h248h248h",
        "receivedQuantity": 3000
      }
    ]
  }
}

receivedQuantity is the quantity arriving in this receipt, not the new lifetime total for the line. The operation adds it to the line's received quantity. Supplying a warehouse location creates stock entries for received lines that identify a substrate. A service line or another line without a substrate does not become paper stock merely because a location was supplied.

Inspect updatedLines and stockEntries in the result. Read the purchase order before retrying after a lost response, since repeating a receipt can add the quantity again. Use each purchase order line once in a receipt request. The purchase order moves to partially received or received according to the accumulated line quantities.

The topic also includes createPurchaseOrder, which creates a purchase order with lines and calculates totals. Use it when you need that combined purchasing action. Supplier agreements, prices and broader purchasing workflows are covered in the ERP guide.

Establish a stock record directly

For an opening balance or another supported stock-entry process, use createWarehouseStock:

mutation RecordLogisticsOpeningStock($input: CreateWarehouseStockInput!) {
  createWarehouseStock(input: $input) {
    warehouseStock { id quantity reservedQuantity availableQuantity unit }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "locationId": "wlc_000000448h848r248h248h248h",
    "stockableType": "SUBSTRATE",
    "stockableId": "job_000000648h848r248h248h248h",
    "quantity": 3000,
    "unit": "SHEET",
    "batchNumber": "PAPER-2026-042",
    "notes": "Opening balance from verified physical stock; not a second receipt."
  }
}

This is an alternative to recording the same stock through a purchase-order receipt. Do not do both for the same delivery. stockableType identifies the kind of item, and stockableId identifies the actual configured material or item. For paper, select an existing substrate and use the unit in which the stock is held.

Available stockable types are:

SUBSTRATE, COMPONENT, FINISHED_GOODS, TOOL, INK, CONSUMABLE

The measurement units are:

CLICK, CM, FT, G, IMPRESSION, IN, KG, LB, M, MM, OZ, PC, PT, SHEET

Use getWarehouseStock or listWarehouseStocks to inspect balances, including quantity, reservedQuantity and availableQuantity. Keep units consistent between stock and material requirements; a numeric quantity alone does not establish a conversion between kilograms, sheets and pieces.

Where your environment exposes material-lot fields, a stock entry can reference an existing lot or create its lot metadata alongside the stock. Keep the lot's material and unit consistent with the stock. Read quantities from the stock record, not from the lot.

Count what is physically there

Use performStockCount to record the actual count at a location:

mutation CountLogisticsStock($input: PerformStockCountInput!) {
  performStockCount(input: $input) {
    updatedStocks { id quantity lastCountedAt }
    adjustments { id quantity reason notes }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "locationId": "wlc_000000448h848r248h248h248h",
    "counts": [
      {
        "warehouseStockId": "wst_000000848h848r248h248h248h",
        "countedQuantity": 2980
      }
    ]
  }
}

countedQuantity is the physical total you counted for that stock record. It is not an adjustment amount. The operation updates the stock quantity, records the count time and records differences as adjustments. Include each stock record once, and reconcile existing reservations if the physical count reveals a shortage.

For ordinary record details, use updateWarehouseStock with the record ID and the fields you intend to change. Prefer the receipt, issue and count operations for their corresponding business events, so the associated records are created too.

Record movements carefully

A warehouse transfer records a movement's source, destination, material, quantity, reason and status. Use createWarehouseTransfer for a new movement record and updateWarehouseTransfer to revise it. Those operations maintain the transfer record; they do not by themselves rebalance stock at both locations. Do not assume that setting a transfer to completed has moved quantities in the stock records.

Use the appropriate stock-changing process for the physical event, and reconcile both locations when arranging an internal move. The production-issue and stock-count operations create their associated transfer or adjustment records as part of those actions. Deleting a transfer is not an automatic reversal of a physical movement.

Operation Use it to
Query.getWarehouseStock Read a warehouse stock.
Query.listWarehouseStocks Browse warehouse stocks.
Query.getWarehouseTransfer Read a warehouse transfer.
Query.listWarehouseTransfers Browse warehouse transfers.
Mutation.upsertWarehouseStock Advanced: Create or replace a warehouse stock. Prefer create/update for routine changes.
Mutation.createWarehouseStock Create a warehouse stock.
Mutation.updateWarehouseStock Change a warehouse stock.
Mutation.deleteWarehouseStock Delete a warehouse stock.
Mutation.upsertWarehouseTransfer Advanced: Create or replace a warehouse transfer. Prefer create/update for routine changes.
Mutation.createWarehouseTransfer Create a warehouse transfer.
Mutation.updateWarehouseTransfer Change a warehouse transfer.
Mutation.deleteWarehouseTransfer Delete a warehouse transfer.
Mutation.createPurchaseOrder Create a purchase order and its lines, calculating the totals.
Mutation.receivePurchaseOrder Record quantities received against purchase order lines and optionally create stock entries.
Mutation.performStockCount Set counted stock quantities and record the differences.

Supply materials to a printing job

A job material reservation describes what a printing job needs. The reservation record and the act of reserving available warehouse stock are separate steps.

Record the requirement

mutation RequestLogisticsMaterial($input: CreateJobMaterialReservationInput!) {
  createJobMaterialReservation(input: $input) {
    jobMaterialReservation { id jobId requiredQuantity reservedQuantity unit status }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "jobId": "job_000000248h848r248h248h248h",
    "stockableType": "SUBSTRATE",
    "stockableId": "job_000000648h848r248h248h248h",
    "requiredQuantity": 2500,
    "unit": "SHEET",
    "preferredLocationId": "wlc_000000448h848r248h248h248h",
    "notes": "Cover press sheets; quantity agreed from the production plan."
  }
}

The 2,500-sheet requirement must come from the agreed production plan, including the intended count basis and allowances. It is not derived simply from the order for 5,000 brochures. The preferred location guides selection; it does not create a stock balance there.

Reserve available stock

mutation ReserveLogisticsMaterial($input: ReserveJobMaterialsInput!) {
  reserveJobMaterials(input: $input) {
    reservations { id requiredQuantity reservedQuantity status }
    fullyReservedCount partiallyReservedCount unmetCount
    errors { path message }
  }
}

Variables:

{
  "input": {
    "jobId": "job_000000248h848r248h248h248h"
  }
}

Read every returned reservation and the fully reserved, partially reserved and unmet counts. The operation attempts to satisfy pending or partially reserved requirements from available matching stock, favouring the preferred location. A successful request does not mean every requirement was fully met.

Reservation statuses are:

PENDING, RESERVED, PARTIALLY_RESERVED, CONSUMED, CANCELLED

Use create/update for the requirement records. Do not assume that editing or deleting a reservation record also releases or recalculates every stock reservation; reconcile the stock balances as part of your material-control process.

Issue stock to production

issueStockToProduction records a production issue, creates transfer records and reduces warehouse stock. Each item identifies the stock record, quantity and optional job reference. Include each stock record once in the request.

This operation checks available quantity, which excludes reserved stock. It does not consume a job reservation automatically. A reservation followed by an issue is therefore not a complete automatic reservation-consumption workflow: reconcile or release the relevant reservation through your stock-control process before issuing that stock. Do not subtract it twice or change a reservation status and assume the stock balance has followed.

Production reports record what was used or produced on the shop floor. They serve a different purpose from the warehouse issue; keep the two consistent when reviewing material use.

Operation Use it to
Query.getJobMaterialReservation Read a job material reservation.
Query.listJobMaterialReservations Browse job material reservations.
Mutation.upsertJobMaterialReservation Advanced: Create or replace a job material reservation. Prefer create/update for routine changes.
Mutation.createJobMaterialReservation Create a job material reservation.
Mutation.updateJobMaterialReservation Change a job material reservation.
Mutation.deleteJobMaterialReservation Delete a job material reservation.
Mutation.reserveJobMaterials Attempt to reserve available stock for pending job material requirements.
Mutation.issueStockToProduction Issue available warehouse stock to production, recording transfers and reducing quantities.

Plan the customer delivery

A planned delivery records the customer's intended destination and arrival requirement. Its items state what is expected there. A shipment records a particular physical dispatch. One planned delivery can be supplied by several shipments; planning a quantity does not mean it has left the building.

Record the destination and arrival requirement

mutation PlanLogisticsDelivery($input: PlannedDeliveryInput!) {
  createPlannedDelivery(input: $input) {
    plannedDelivery { id version destination { recipientOrganization city country } }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "destination": {
      "snapshot": {
        "recipientOrganization": "North Street Books",
        "street1": "18 Example Road",
        "city": "Bristol",
        "postalCode": "BS1 1AA",
        "country": "GB"
      }
    },
    "requestedArrival": {
      "meaning": "REQUIRED_BY",
      "latest": {
        "date": "2026-11-06"
      },
      "timezone": "Europe/London"
    }
  }
}

The destination can be supplied as a snapshot or selected from an existing address using the corresponding input. Supply the intended choice rather than both. The saved destination is the delivery's address record; review it before dispatch if the customer's address changes.

This example requests arrival by a date in the destination's time zone. Use an offset-aware instant when you know a precise time; do not turn an unknown time into midnight. requestedArrival distinguishes a requested date, deadline, window or appointment.

Specify the finished work to deliver

mutation PlanLogisticsDeliveryItem($input: PlannedDeliveryItemInput!) {
  createPlannedDeliveryItem(input: $input) {
    plannedDeliveryItem { id version requestedQuantity allocatedQuantity }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "plannedDeliveryId": "pdl_000000e48h848r248h248h248h",
    "jobId": "job_000000248h848r248h248h248h",
    "orderLineId": "oln_000001848h848r248h248h248h",
    "description": "Autumn brochures — finished copies",
    "requestedQuantity": 5000
  }
}

This item requests 5,000 finished brochures. Keep the job and order-line links where they apply, so production and commercial fulfilment can be reviewed together. Use separate planned items when destinations or delivery obligations differ.

Updates and deletions of planned deliveries and their items require the current version. Creation and update validate the records; they do not prove that packing, dispatch or receipt has happened.

Connect a physical dispatch to the plan

After creating the shipment item in the next section, allocate its quantity to the planned delivery item:

mutation AllocateLogisticsDelivery($input: ShipmentItemAllocationInput!) {
  createShipmentItemAllocation(input: $input) {
    shipmentItemAllocation { id version quantity shipmentItemId plannedDeliveryItemId }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "shipmentItemId": "sit_000001248h848r248h248h248h",
    "plannedDeliveryItemId": "pdi_000000g48h848r248h248h248h",
    "quantity": 2000
  }
}

The first dispatch supplies 2,000 of the requested 5,000 brochures. Keep the allocation ID and version. An allocation is a planned connection, not a receipt confirmation. Later, recorded dispatch or receipt quantities must be attributed to the appropriate planned item before they can be credited to it.

Operation Use it to
Query.getPlannedDelivery Read a planned delivery.
Query.getPlannedDeliveryItem Read a planned delivery item.
Query.listPlannedDeliveryItems Browse planned delivery items.
Query.getShipmentItemAllocation Read a shipment item allocation.
Query.listShipmentItemAllocations Browse shipment item allocations.
Mutation.createPlannedDelivery Create a planned delivery.
Mutation.updatePlannedDelivery Change a planned delivery.
Mutation.deletePlannedDelivery Delete a planned delivery.
Mutation.createPlannedDeliveryItem Create a planned delivery item.
Mutation.updatePlannedDeliveryItem Change a planned delivery item.
Mutation.deletePlannedDeliveryItem Delete a planned delivery item.
Mutation.createShipmentItemAllocation Create a shipment item allocation.
Mutation.updateShipmentItemAllocation Change a shipment item allocation.
Mutation.deleteShipmentItemAllocation Delete a shipment item allocation.

Record delivery requirements

Delivery requirements describe obligations beyond a quantity and address: for example, handling instructions, packaging requirements or an agreed logistics event. Keep these structured requirements with the delivery or planned item so they can be assessed alongside the quantities.

createCustomerFulfillmentDefault records a reusable customer default. Read or revise it through the corresponding get, list and update operations. resolveCustomerFulfillmentDefaults explicitly copies a customer's defaults into a planned delivery; it requires the delivery's current version. Changing a customer default is not a silent rewrite of every existing delivery.

Use createFulfillmentRequirement for a delivery-specific requirement or an explicit replacement, supplying the relevant scope and value. Read the existing requirement before replacing it, and preserve the reason for the change. Retire requirements and defaults when they no longer apply, using their current versions. There is no ordinary update operation for a fulfilment requirement; create the intended replacement or retire the old requirement as appropriate.

effectiveFulfillmentRequirements brings together the copied and local requirements and their explicit exceptions. Review its diagnostics rather than assuming that a list of requirements is already satisfied.

Use recordRequirementEvidence to record an observation about whether a requirement was met. Its input distinguishes the observation, completion indication, occurrence time and attribution. Read the supporting records through getRequirementEvidence and listRequirementEvidence. Recording an observation does not itself send a message, obtain approval or perform the physical handling step.

assessFulfillmentRequirements evaluates the relevant scope for the selected quantity stage and, where appropriate, logistics event and time. Review unresolved results. A requirement assessment and a quantity balance answer different questions; both matter when deciding whether the work is ready to close.

Operation Use it to
Query.getFulfillmentRequirement Read a fulfillment requirement.
Query.listFulfillmentRequirements Browse fulfillment requirements.
Query.getCustomerFulfillmentDefault Read a customer fulfillment default.
Query.listCustomerFulfillmentDefaults Browse customer fulfillment defaults.
Query.effectiveFulfillmentRequirements Read applicable delivery requirements and explicit exceptions.
Query.getRequirementEvidence Read a recorded observation about a delivery requirement.
Query.listRequirementEvidence Browse observations about a delivery requirement.
Query.assessFulfillmentRequirements Assess requirements for the requested quantity stage and logistics event.
Mutation.createFulfillmentRequirement Create a fulfillment requirement.
Mutation.createCustomerFulfillmentDefault Create a customer fulfillment default.
Mutation.updateCustomerFulfillmentDefault Change a customer fulfillment default.
Mutation.retireFulfillmentRequirement Retire a fulfillment requirement.
Mutation.retireCustomerFulfillmentDefault Retire a customer fulfillment default.
Mutation.resolveCustomerFulfillmentDefaults Copy the selected customer’s fulfilment defaults into a planned delivery.
Mutation.recordRequirementEvidence Record whether a delivery requirement was met, with its supporting observation.

Prepare shipments and packages

A shipment groups a physical dispatch. Packages describe its pallets, cartons or parcels. Shipment items describe the work inside those packages. Preserve those distinctions when one job is split between vehicles or destinations.

Create the first shipment

mutation CreateLogisticsShipment($input: CreateShipmentInput!) {
  createShipment(input: $input) {
    shipment { id shipmentNumber status }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "orderId": "ord_000001648h848r248h248h248h",
    "destinationSnapshot": {
      "recipientOrganization": "North Street Books",
      "street1": "18 Example Road",
      "city": "Bristol",
      "postalCode": "BS1 1AA",
      "country": "GB"
    },
    "shipmentNumber": "SHIP-2026-1042",
    "status": "DRAFT",
    "notes": "First 2,000 copies of the 5,000-copy brochure delivery."
  }
}

This draft covers the first 2,000 brochures. Set the actual configured carrier when it is known, and check the shipment destination against the planned delivery. The order link provides context; it does not allocate every item to an order line automatically.

Add the pallet or parcel

mutation AddLogisticsPackage($input: CreateShipmentPackageInput!) {
  createShipmentPackage(input: $input) {
    shipmentPackage { id shipmentId packageNumber }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "shipmentId": "shp_000000j48h848r248h248h248h",
    "packageNumber": 1,
    "packagingType": "PALLET",
    "notes": "Pallet containing 2,000 finished brochures."
  }
}

The example uses one pallet. Add further package records for other pallets or parcels rather than treating a shipment's package-count field as the package contents. Supply dimensions and weights according to the conventions of your shipping process; this example leaves unknown measurements unset.

Record the contents

mutation AddLogisticsShipmentItem($input: CreateShipmentItemInput!) {
  createShipmentItem(input: $input) {
    shipmentItem { id packageId quantity orderLineId }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "packageId": "spk_000001048h848r248h248h248h",
    "jobId": "job_000000248h848r248h248h248h",
    "orderLineId": "oln_000001848h848r248h248h248h",
    "description": "Autumn brochures — first dispatch",
    "quantity": 2000
  }
}

Use the returned item ID in the allocation recipe above. Use updateShipment, updateShipmentPackage and updateShipmentItem for revisions to existing records, and read the allocation records when changing quantities. Deleting a record does not undo a physical dispatch.

Dispatch and track the shipment

For a combined action, dispatchShipment creates a shipment with packages and items already marked as picked up. Use it when that is the event you intend to record; do not call it to update the draft shipment created above, or you will create another shipment. It records the dispatch rather than booking transport on your behalf.

Use updateShipmentTracking for status and tracking changes. Supply occurrence times only when known. A status of DELIVERED is not an item-level receipt confirmation and does not by itself complete the order.

Shipment statuses are:

DRAFT, READY_FOR_PICKUP, PICKED_UP, IN_TRANSIT, OUT_FOR_DELIVERY, DELIVERED, FAILED_DELIVERY, RETURNED, CANCELLED

Use dailyDispatchManifest to review a day's shipments with their packages, items and order context. It is a view of the recorded dispatch work, not a substitute for checking what was physically handed to the carrier.

Operation Use it to
Query.getShipment Read a shipment.
Query.listShipments Browse shipments.
Query.getShipmentPackage Read a shipment package.
Query.listShipmentPackages Browse shipment packages.
Query.getShipmentItem Read a shipment item.
Query.listShipmentItems Browse shipment items.
Query.listPlannedDeliveries Browse planned deliveries.
Query.dailyDispatchManifest Read the day’s shipments with package, item and order details.
Mutation.upsertShipment Advanced: Create or replace a shipment. Prefer create/update for routine changes.
Mutation.createShipment Create a shipment.
Mutation.updateShipment Change a shipment.
Mutation.deleteShipment Delete a shipment.
Mutation.createShipmentPackage Create a shipment package.
Mutation.updateShipmentPackage Change a shipment package.
Mutation.upsertShipmentPackage Advanced: Create or replace a shipment package. Prefer create/update for routine changes.
Mutation.deleteShipmentPackage Delete a shipment package.
Mutation.upsertShipmentItem Advanced: Create or replace a shipment item. Prefer create/update for routine changes.
Mutation.createShipmentItem Create a shipment item.
Mutation.updateShipmentItem Change a shipment item.
Mutation.deleteShipmentItem Delete a shipment item.
Mutation.dispatchShipment Create a shipment with packages and items already marked as picked up.
Mutation.updateShipmentTracking Update shipment status and tracking details without completing the order.

Record dispatch, receipt and returns

Record what was observed for each shipment item: the quantity dispatched, received or returned. These quantity records are exposed through the …Evidence operations. A shipment status describes the shipment overall; these records establish the quantities for the individual items.

The quantity stages are:

DISPATCH, RECEIPT, RETURN

Confirm the first receipt

mutation RecordLogisticsReceipt($input: ShipmentItemEvidenceInput!) {
  recordShipmentItemEvidence(input: $input) {
    shipmentItemEvidence { id version stage quantity }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "shipmentItemId": "sit_000001248h848r248h248h248h",
    "stage": "RECEIPT",
    "quantity": 2000,
    "occurredAt": {
      "instant": "2026-11-05T10:15:00Z"
    },
    "requestKey": "receipt-SHIP-2026-1042-pallet-1-v1",
    "allocations": [
      {
        "source": {
          "allocation": {
            "id": "sia_000001448h848r248h248h248h",
            "version": 1
          }
        },
        "quantity": 2000
      }
    ]
  }
}

Only send this request once the 2,000 brochures have actually been received. It records that observation and attributes the quantity through the allocation created earlier. Replace the example's allocation version with the version you read from your own record. Use a stable requestKey for this observation so an identical retry can be recognised.

An observation can be recorded before its attribution is known. Use attributeShipmentItemEvidence later to credit it to the correct planned item, supplying the observation's current version, a request key and the attribution source. Quantities that have not been attributed must not be treated as satisfying the planned delivery.

Correct a record or record a return

Use the correction fields to record a correction to an earlier observation, preserving its reference and explaining the reason. A return is a separate quantity stage linked to the relevant receipt through receiptEvidenceId; it is not simply a shipment status change. Inspect the returned records and balances after either action.

Read individual observations with getShipmentItemEvidence or their history with listShipmentItemEvidence. shipmentItemExecutionBalance shows observed, credited and unattributed quantities for the physical item. Missing observations remain unknown, including whether returns have been observed; do not turn an unknown value into zero.

Read the planned delivery balance

query ReadLogisticsDeliveryBalance($id: PlannedDeliveryItemID!) {
  plannedItemFulfillmentBalance(plannedDeliveryItemId: $id) {
    plannedDeliveryItemId requestedQuantity allocatedQuantity
    stages { stage knownCreditedQuantity attributionComplete remainingQuantity }
    netRetainedQuantity netAttributionComplete
  }
}

Variables:

{
  "id": "pdi_000000g48h848r248h248h248h"
}

The requested quantity, allocated quantity and credited quantities are deliberately separate. After the first 2,000-copy receipt, the 5,000-copy obligation is not fully met. Inspect attributionComplete before interpreting remainingQuantity: the API can return an unknown remaining quantity when coverage or attribution is incomplete. Likewise, a missing netRetainedQuantity does not establish that there were no returns.

Operation Use it to
Query.getShipmentItemEvidence Read a recorded shipment-item quantity observation.
Query.listShipmentItemEvidence Browse shipment-item quantity observations.
Query.shipmentItemExecutionBalance Review observed and attributed quantities for a shipment item.
Query.plannedItemFulfillmentBalance Review allocated and credited quantities for a planned delivery item.
Mutation.recordShipmentItemEvidence Record an observed dispatch, receipt or return quantity.
Mutation.attributeShipmentItemEvidence Credit an observed quantity to its planned delivery item.

Review fulfilment and complete the order

Use plannedItemReview to review a planned item's quantities, effective requirements, assessment and authorised notes together. Resolve missing attribution and outstanding requirements rather than relying on the shipment's status label.

For the order-level review, use the same query as the ERP guide:

query CheckCommerceFulfilment($orderId: OrderID!) {
  orderFulfillmentCompletion(orderId: $orderId) {
    orderId completionPoint outcome diagnosticSummary diagnostics
  }
}

Variables:

{
  "orderId": "ord_01h455vb4pex5vsknk084sn02q"
}

orderFulfillmentCompletion assesses the current completion policy across the order's lines using explicitly attributed quantities. Read its outcome and diagnostics. Shipment totals or a single delivered pallet are not enough to conclude that the whole order has been fulfilled.

When the order satisfies the selected completion point, completeOrderFulfillment is the explicit action to complete it. Supply the completion point you reviewed and inspect the result. The operation checks the current policy; it does not invent missing receipt quantities or reopen previously completed work.

updateFulfillmentSettings changes shared completion policy. It is administrative configuration, not a step for closing an individual order. Keep that decision separate from recording what happened to a particular shipment.

Operation Use it to
Query.plannedItemReview Review quantities, requirements and authorised notes for a planned delivery item.
Query.orderFulfillmentCompletion Check whether every order line meets the current completion milestone
Mutation.updateFulfillmentSettings Change shared order completion policy. Administrative configuration.
Mutation.completeOrderFulfillment Complete an order after checking its fulfilment milestone

Trace the work and its impact

Use fulfillmentTrace to explore the relationships around a delivery or shipment record, and fulfillmentImpact to find related records upstream or downstream. This helps answer questions such as which planned deliveries are connected to a shipment item.

provenanceTrace and provenanceImpact extend the view across production, fulfilment and material provenance. A material batch can explain where work came from while warehouse stock remains the authority for quantities.

whatIf explores the effect of proposed relationship links and reports whether they introduce a cycle. It does not save those links or carry out the proposed movement. Read the allowed direction, depth and graph arguments in the reference before narrowing a trace.

These queries explain relationships and potential effects. They do not prove that a physical movement occurred or calculate a replacement stock balance.

Operation Use it to
Query.fulfillmentTrace Trace relationships around a delivery or shipment record.
Query.fulfillmentImpact Find delivery records affected upstream or downstream of a record.
Query.provenanceTrace Trace relationships across production, fulfilment and material provenance.
Query.provenanceImpact Find related records that could be affected across those relationships.
Query.whatIf Explore the effect of proposed relationship links without saving them.

Keep handling instructions with the records

Use entity notes for operational instructions, conversations and decisions associated with the appropriate order, job or delivery record. Keep structured quantities, destinations, requirements and confirmations in their dedicated fields; a note explains the work rather than replacing those records.

This shared example records a note on the source order:

mutation AddCommerceOrderNote($input: CreateEntityNoteInput!) {
  createEntityNote(input: $input) {
    entityNote { id targetId body version }
    errors { path message }
  }
}

Variables:

{
  "input": {
    "targetId": "ord_01h455vb4pex5vsknk084sn02q",
    "body": "Customer requested delivery after 10:00. Confirm the delivery appointment before dispatch."
  }
}

Choose the target type and ID for the record you are annotating. Read the existing version before updating or deleting a note. Search and list operations help find relevant instructions; reindexEntityNotes supports search maintenance and is not a required step after writing each note.

Operation Use it to
Query.getEntityNote Read a note attached to a record you can access
Query.getEntityNoteBySource Find a note by its source integration and key
Query.entityNotes Browse notes on a record
Query.searchEntityNotes Search notes you are allowed to read
Mutation.createEntityNote Add a note to a record
Mutation.updateEntityNote Edit a note using its current version
Mutation.deleteEntityNote Delete a note using its current version
Mutation.reindexEntityNotes Request refreshed search indexing for a selected set of notes

Discover the API and get help

The shared discovery operations expose schema information, available tools and help. Use them to find the inputs supported by your environment and the related workflows you need.

Retrieve named examples through topicExamples(names: [...]), using names such as logistics.receive-paper, logistics.plan-delivery and logistics.record-receipt. Each operation belongs with its variables. Replace the illustrative IDs and review the intended business event before sending a mutation.

Operation Use it to
Query.magicQuery Read data with a compact named query
Query.getMagicQuerySchema Inspect the inputs and result of a compact named query
Query.listMagicQueries Discover the available compact named queries
Query.getMagicQueryGraphQL Inspect the GraphQL operation for a compact named query
Query.listDataChangeEventTopics Discover record-change event topics
Query.generateDefaultDataQuery Prepare a query for a record-change event
Query.ping Check whether the API responds
Query.iacSchema Read the infrastructure schema for IaC tooling
Query.iacValidate Validate an IaC source document
Query.iacGuides Read IaC authoring guides
Query.helpChapters Discover help chapters
Query.helpChapter Read a help chapter
Query.searchHelp Find help by search term
Query.schemaAuthoringCatalog Discover supported schema authoring features
Query.compileSchemaXML Convert an authored XML schema to JSON Schema
Query.renderSchemaXML Convert JSON Schema to authored XML
Query.iacSchemaDocument Read a schema document used by IaC tooling
Subscription.dataChangeEvents Subscribe to record-change events
Query.topicExamples Retrieve named examples with their operations and variables.

Published platform manual · revision 80b1cbef57a3