Search, Filter & Sort Logistic Orders
What this covers
How a storefront lists Logistic Orders — the "My orders" screens — with server-side filtering and sorting through ORDER-550 (POST /v1/shop/logistic-orders).
At a glance
This is a buyer (shop) surface. Criteria are sent in the request body; pagination and sorting are sent as query parameters.
The administration counterpart, ADM-ORDER-551 (
POST /v1/logistic-orders), shares the same body criteria and sort keys described here, with the caller's perimeter applied (whole tenant for an operator, own orders for a supplier user). Sorting on a custom field value is the only storefront-only capability.Sorting rule (global): invalid sort entries are silently ignored. The valid entries of the same request are still applied and the call returns
200.Default sort: without any
sortcriteria, the most recently created orders come first. This default is stable, so pagination is deterministic.
Warning: Two fields deprecated since 3.29 —orderLogisticLinePriceDtoandofferCustomFieldSnapshotDtos— are no longer returned by default to tenants created from 3.136 onwards. Existing tenants keep receiving them until they ask for their removal. See Order line previews for the replacements.
Key concepts
| Concept | Description |
|---|---|
| Search criteria | A JSON body (locale is the only required field) describing what to filter on: statuses, dates, suppliers, identifiers, origins, custom fields. |
| Sort key | A field:direction pair passed as a sort query parameter. Multiple keys are applied in the order they are sent. |
| Order origin | Where the order comes from: CART, SUPPLIER_QUOTE, ORDER or EXTERNAL_ORDER. |
| Custom field criteria | Filters on custom field values, at order, account or offer level. |
| Preview line | An order line returned inline with its logistic order, so a list screen can show a few products without an extra call. The number returned per order is driven by the nbPreviewLines query parameter. |
Order line previews
Both ORDER-550 and ADM-ORDER-551 accept an nbPreviewLines query parameter that controls how many order lines are returned inline with each logistic order. nbPreviewLines=0 returns none — the lightest response for a screen that only displays order headers.
Each preview line carries a snapshot of the offer as it was when the order was placed, split across two objects:
| Object | What it carries |
|---|---|
offerPriceSnapshotDto | Every price of the line — unit, total, shipping, tax amounts, offer price type and the offer price external identifier |
offerInventorySnapshotDto | The inventory-side data of the offer — currency, packing type, quantity per item, tax rates and codes, order quantity bounds, lead time to ship, external source, and the offer custom field values |
Deprecated fields no longer returned by default
Two fields of the order lines, deprecated since 3.29 and already duplicated elsewhere in the same response, are no longer returned by default. No data is lost: the replacements carry the same values.
| Deprecated field | Read it from instead |
|---|---|
orderLogisticLinePriceDto | offerPriceSnapshotDto for the prices, and offerInventorySnapshotDto for the tax rate, quantity per item, external source, currency and packing type |
offerCustomFieldSnapshotDtos | offerInventorySnapshotDto.customFieldValueSnapshots |
Who receives them
Whether these two fields are returned is driven by a tenant-level setting:
| Tenant | Are the two fields returned |
|---|---|
| Created before 3.136 | Yes — nothing changes for integrations in place. They can ask for the fields to be dropped once they have migrated |
| Created from 3.136 onwards | No — responses only carry offerPriceSnapshotDto and offerInventorySnapshotDto |
The setting applies to every route exposing logistic order lines, lists as well as order detail — not to ORDER-550 and ADM-ORDER-551 alone.
Fields available in offerPriceSnapshotDto
offerPriceExternalId, offerPriceType, offerPriceTypeValue, itemPerPack, productPriceWithoutTaxes, productPriceWithTaxes, productTaxAmount, originalProductPriceWithoutTaxes, originalProductPriceWithTaxes, confirmedProductPriceWithoutTaxes, shippingPriceWithoutTaxes, shippingPriceWithTaxes, shippingTaxAmount, totalProductPriceWithoutTaxes, totalProductPriceWithTaxes, totalProductTaxAmount, totalPriceWithoutTaxes, totalPriceWithTaxes, totalTaxAmount, taxLegalNotice
Fields available in offerInventorySnapshotDto
offerInventoryExternalId, externalSource, currency, packingType, quantityPerItem, productTaxCode, productTaxRate, shippingTaxCode, shippingTaxRate, minOrderQuantity, maxOrderQuantity, leadTimeToShip, customFieldValueSnapshots
Warning: An integration built on a new tenant must read the prices and the offer data fromofferPriceSnapshotDtoandofferInventorySnapshotDto— the two deprecated fields are simply absent from its responses. On an existing tenant, migrating to the two replacements is the prerequisite to asking for their removal.
Tip: Migrate now even if your tenant still receives the two fields. Once your integration reads only the replacements, ask your DJUST contact to drop them and the order lists get lighter with no further change on your side.
Dropping them lightens the preview lines of the order lists by 15 % to 38 %, depending on how many offer custom fields the tenant carries — and preview lines are what a list screen loads on every page change.
flowchart LR
%% Styles (Readme)
classDef create fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
classDef read fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
classDef update fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
classDef add fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
classDef remove fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
classDef place fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
A[🧾 Field read today<br>on a preview line]:::sys --> B{Which field}
B -->|orderLogisticLinePriceDto<br>a price| C[➕ offerPriceSnapshotDto]:::add
B -->|orderLogisticLinePriceDto<br>tax rate, quantity per item,<br>external source, currency,<br>packing type| D[➕ offerInventorySnapshotDto]:::add
B -->|offerCustomFieldSnapshotDtos| E[➕ offerInventorySnapshotDto<br>customFieldValueSnapshots]:::add
C --> F[✅ Same values<br>lighter response]:::place
D --> F
E --> F
class B decision
style A rx:8,ry:8
style B rx:8,ry:8
style C rx:8,ry:8
style D rx:8,ry:8
style E rx:8,ry:8
style F rx:8,ry:8
Shape of a preview line
{
"id": "0000033820",
"quantity": 1,
"status": "ACCEPTED_BY_SUPPLIER",
"offerPriceSnapshotDto": {
"offerPriceExternalId": "RC-EX3A",
"offerPriceType": "ACCOUNT",
"offerPriceTypeValue": "ACME RETAIL",
"itemPerPack": 1,
"productPriceWithoutTaxes": 117.45,
"productPriceWithTaxes": 140.94,
"productTaxAmount": 23.49,
"totalProductPriceWithoutTaxes": 117.45,
"totalProductPriceWithTaxes": 140.94,
"totalProductTaxAmount": 23.49,
"shippingPriceWithoutTaxes": 0.0,
"shippingPriceWithTaxes": 0.0,
"shippingTaxAmount": 0.0,
"totalPriceWithoutTaxes": 117.45,
"totalPriceWithTaxes": 140.94,
"totalTaxAmount": 23.49
},
"offerInventorySnapshotDto": {
"offerInventoryExternalId": "INV-RC-EX3A",
"externalSource": "EXTERN",
"currency": "EUR",
"packingType": "UNIT",
"quantityPerItem": 1.0,
"productTaxRate": 20.0,
"customFieldValueSnapshots": [
{
"customFieldSnapshotDto": {
"externalId": "warranty",
"type": "TEXT",
"mandatory": false
},
"typedValue": "24 months"
}
]
}
}Sorting
Both field:direction (recommended) and field,direction are accepted, and asc / desc are available on every sortable field. Sort keys are accepted in camelCase; the snake_case form remains functional.
Sortable fields
id, reference, externalId, status, paymentStatus, paymentOption, createdAt, updatedAt, orderOrigin, incidentDeclared, channel, shippingType, supplierName
Sortable price fields
totalPriceWithTax, totalPriceWithoutTax, totalTaxAmount, totalProductWithTax, totalProductWithoutTax, totalProductTaxAmount, totalShippingFeesWithTax, totalShippingFeesWithoutTax, totalShippingTaxAmount
Tip: An unknown sort key no longer fails the whole request.sort=reference:asc&sort=notAField:descsorts by reference and ignores the second key.
Sorting on the supplier name
supplierName (alias supplier_name) sorts the orders on the name of their supplier, so a paginated list can be grouped by supplier without loading every order client-side.
- The comparison ignores case and accents.
- Orders with no supplier come last, in both directions.
- The key combines with the other sort keys in the order they are sent, including a
cf.<identifier>key. - Available on both the storefront (ORDER-550) and administration (ADM-ORDER-551) lists.
# Orders grouped by supplier, most recent first within each supplier
POST /v1/shop/logistic-orders?sort=supplierName:asc&sort=createdAt:desc&page=0&size=20Sorting on a custom field value
Orders can also be sorted on the value of one of their custom fields, using the key cf.<identifier> where the identifier is either the DJUST identifier of the custom field or its external one.
- One custom field key per request. If several are sent, the first is honoured and the following ones are ignored.
- Orders with no value for that custom field come last, in both directions.
- Comparison depends on the type:
NUMBERandMETRICvalues are ordered as numbers,DATEvalues written in ISO form chronologically, and everything else as text — ignoring case and accents. - The key is ignored when no custom field carries the identifier, or when that custom field holds media.
Note: Sorting on a custom field value is available on the storefront surface only.
# Orders sorted by the PRIORITY custom field, then by creation date
POST /v1/shop/logistic-orders?sort=cf.PRIORITY:asc&sort=createdAt:desc&page=0&size=20Filters
Order identifier
orderIdentifier matches the order reference, its external identifier or its DJUST identifier — a single field to back an "order number" search box, with no need to know which identifier the buyer typed.
The comparison is a partial match that ignores case: test-224 finds the order TEST-224. Accents are not ignored.
{ "locale": "fr", "orderIdentifier": "ORD-000123" }Incident status
incidentStatus keeps the orders carrying at least one incident in one of the given statuses: OPEN, ON_GOING, CLOSED. It is the criterion to use to find the orders whose incident is still being processed.
- Several values are combined with a logical OR. An order is kept as soon as one of its incidents matches: an order with one
CLOSEDand oneOPENincident is returned for["CLOSED"]as well as for["OPEN"]. - Only the status of the incident is evaluated, never the statuses of its lines.
- Incidents declared on the whole order and incidents declared on order lines are treated alike.
- The criterion combines with every other filter. A supplier user only gets its own orders back.
{ "locale": "fr", "incidentStatus": ["OPEN", "ON_GOING"] }
Warning: The olderincidentboolean relies on the order's incident flag, which is also raised by a simple customer discussion and is never cleared. It therefore returns more orders than the incident statuses combined. PreferincidentStatusto follow the processing of incidents; see Order Incident Management for how statuses are updated.
Order origin
orderOrigin restricts the list to one or more origins: CART, SUPPLIER_QUOTE, ORDER, EXTERNAL_ORDER. The filter is applied before pagination, which is how external orders are kept out of a storefront screen without paging through them client-side.
{ "locale": "fr", "orderOrigin": ["CART", "SUPPLIER_QUOTE"] }Orders awaiting my approval
pendingMyApproval (boolean) keeps only the orders whose approval is assigned to the connected customer user and still pending. It is the criterion behind an "To approve" screen.
- Orders the connected user has already approved are excluded.
- Orders waiting for the approval of another user are excluded.
- At
falseor absent, the behaviour is strictly unchanged. - The criterion combines with every other filter and sort key, and the usual security perimeter (authorised customer accounts and store view) still applies.
Note:pendingMyApprovalis available on the storefront surface only (ORDER-550). A Back-Office user is never an approver, so the criterion has no administration counterpart.
{ "locale": "fr", "pendingMyApproval": true }
Tip:pendingMyApprovalis a server-side filter, so the approval queue stays paginated. Do not confuse it withapprovalIds, which filters on specific approval workflows regardless of who has to act on them.
Custom field criteria
Three criteria lists are available, one per level:
| Field | Level |
|---|---|
orderLogisticCustomFieldValueCriteria | Logistic order |
accountCustomFieldValueCriteria | Customer account |
offerCustomFieldValueCriteria | Offer |
Each entry is a { customFieldId, value } pair. The combination rules are:
- Several values on the same custom field → combined with a logical OR.
- Different custom fields → combined with a logical AND.
- Custom fields of type
MEDIAare not searchable and are excluded from filtering.
{
"locale": "fr",
"orderLogisticCustomFieldValueCriteria": [
{ "customFieldId": "PRIORITY", "value": "HIGH" },
{ "customFieldId": "CHANNEL", "value": "B2B" },
{ "customFieldId": "CHANNEL", "value": "B2C" }
]
}Reads as: PRIORITY = HIGH AND (CHANNEL = B2B OR CHANNEL = B2C).
Other criteria
| Field | Description |
|---|---|
logisticStatus | One or more logistic order statuses (e.g. SHIPPED) |
supplierIds | Restrict to one or more suppliers |
customerAccountIds | Restrict to one or more customer accounts |
connectedUserOnly | Restrict to the orders placed by the connected user |
approvalIds | Filter on approval workflows |
pendingMyApproval | Keep only the orders still awaiting the approval of the connected user — see Orders awaiting my approval |
paymentOptions | Filter on available payment methods (e.g. BANK_WIRE) |
incident | Keep only the orders flagged as carrying an incident (flag also raised by a customer discussion — prefer incidentStatus) |
incidentStatus | Keep only the orders with at least one incident in the given statuses — see Incident status |
creationDateFrom / creationDateTo | Creation date range |
updateDateFrom / updateDateTo | Update date range |
Processing pipeline
flowchart LR
IN[📘 Request<br>body criteria + query sort]:::sys --> SC[Scope resolution<br>account • store]:::sys
SC --> IDF[Apply orderIdentifier<br>reference • externalId • id]:::read
IDF --> ORG[Apply orderOrigin]:::read
ORG --> CF[Apply custom field criteria<br>OR inside • AND across]:::read
CF --> ST[Apply status, incidentStatus<br>and date filters]:::read
ST --> SO{Sort keys provided}:::decision
SO -->|No| DEF[Default sort<br>newest orders first]:::sys
SO -->|Yes| VAL[Keep valid keys<br>ignore the others]:::sys
DEF --> PG[Paginate]:::sys
VAL --> PG
PG --> OUT[✅ Paginated logistic orders]:::place
%% Styles (Readme)
classDef create fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
classDef read fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
classDef update fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
classDef add fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
classDef remove fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
classDef place fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
style IN rx:8,ry:8
style SC rx:8,ry:8
style IDF rx:8,ry:8
style ORG rx:8,ry:8
style CF rx:8,ry:8
style ST rx:8,ry:8
style SO rx:8,ry:8
style DEF rx:8,ry:8
style VAL rx:8,ry:8
style PG rx:8,ry:8
style OUT rx:8,ry:8
Example scenarios
Shipped orders of two suppliers
A "My orders" screen showing shipped orders of two suppliers, searched by order number and sorted by total amount excluding tax.
POST /v1/shop/logistic-orders?sort=totalProductWithoutTax:desc&page=0&size=20&nbPreviewLines=3
dj-client: ACCOUNT
dj-api-key: <your-api-key>
Content-Type: application/json{
"locale": "fr",
"orderIdentifier": "2026-08",
"logisticStatus": ["SHIPPED"],
"supplierIds": ["SUP-01", "SUP-02"],
"orderOrigin": ["CART"],
"creationDateFrom": "2026-08-01T00:00:00.000Z"
}Orders with an incident still being processed, grouped by supplier
An "Incidents to follow" screen listing the orders that carry at least one open or ongoing incident, grouped by supplier name.
POST /v1/shop/logistic-orders?sort=supplierName:asc&sort=createdAt:desc&page=0&size=20&nbPreviewLines=0
dj-client: ACCOUNT
dj-api-key: <your-api-key>
Content-Type: application/json{
"locale": "fr",
"incidentStatus": ["OPEN", "ON_GOING"]
}My approval queue
An "Orders to approve" screen listing only the orders the connected customer user still has to approve, oldest first.
POST /v1/shop/logistic-orders?sort=createdAt:asc&page=0&size=20&nbPreviewLines=0
dj-client: ACCOUNT
dj-api-key: <your-api-key>
Content-Type: application/json{
"locale": "fr",
"pendingMyApproval": true
}Best practices
- Filter server-side, always. Every criterion on this page is applied before pagination. Loading all orders and filtering in the browser defeats the pagination and degrades on large accounts.
- Use
orderIdentifierfor a single search box. One field covers the reference, the external identifier and the DJUST identifier, whatever the case typed by the buyer. - Follow incidents with
incidentStatus, notincident. The boolean flag is also raised by a plain discussion and never goes back down. - Group by supplier with
sort=supplierNamerather than sorting a page of results in the browser: the sort applies across all pages. - Exclude external orders with
orderOrigin, not by post-filtering a page of results — otherwise your page sizes become inconsistent. - Send one custom field sort key at most. Additional ones are silently dropped, so a screen relying on two of them will not behave as expected.
- Build the approval queue with
pendingMyApproval, not by loading every order awaiting approval and sorting in the browser — that is incompatible with server-side pagination. - Rely on the default sort for stable pagination. Do not add a random tie-breaker of your own.
- Read prices from
offerPriceSnapshotDtoand offer data fromofferInventorySnapshotDto. The two deprecated fields are absent from the responses of any tenant created from 3.136 onwards; the replacements carry the same values on every tenant. - Set
nbPreviewLinesto what the screen actually displays. A list showing three products per order should sendnbPreviewLines=3, and a header-only listnbPreviewLines=0— every extra preview line is payload the browser downloads and discards.
Common mistakes
| Mistake | Symptom | Fix |
|---|---|---|
Expecting a 400 on an unknown sort key | Sorting silently differs from what the UI shows | Invalid keys are ignored by design — validate the key list in your integration |
Filtering on a MEDIA custom field | The criterion has no effect | MEDIA custom fields are excluded from filtering |
Sending several cf.<identifier> sort keys | Only one column is actually sorted | Restrict the UI to a single custom field sort at a time |
Omitting locale | Request rejected | locale is the only required field of the criteria body |
| Post-filtering external orders after pagination | Uneven page sizes, missing rows | Use the orderOrigin criterion |
Using incident: true to find unresolved incidents | Orders with only a discussion, or with closed incidents, are returned too | Use incidentStatus: ["OPEN", "ON_GOING"] |
Using approvalIds to build an approval queue | Orders assigned to other approvers are returned | Use pendingMyApproval: true — it targets the connected user's pending approvals |
Expecting pendingMyApproval to work on the administration list | The criterion is ignored | It is a storefront-only criterion — a Back-Office user is not an approver |
Expecting incidentStatus to look at line statuses | An order whose incident is OPEN but whose lines are all CLOSED is still returned for OPEN | Only the incident status is evaluated — update the incident status itself when the incident is resolved |
Still reading orderLogisticLinePriceDto on a preview line | Prices display as empty or undefined on the order list of a tenant created from 3.136 onwards | Read them from offerPriceSnapshotDto, and the tax rate, quantity per item, external source, currency and packing type from offerInventorySnapshotDto |
Still reading offerCustomFieldSnapshotDtos | Offer custom fields disappear from the order list | Read offerInventorySnapshotDto.customFieldValueSnapshots |
| Testing an integration on an old tenant and shipping it on a new one | The two fields are present in development and absent in production | The setting is per tenant — validate on a tenant created from 3.136, or read only the two replacement objects |
| Requesting preview lines a list screen never displays | Slow list loading on large accounts | Align nbPreviewLines with the screen, 0 when only headers are shown |
Error codes
For the full reference of functional codes, see Error / Warning codes.
API quicklinks
- Search Logistic Orders (storefront) — ORDER-550
- Search Logistic Orders (administration) — ADM-ORDER-551
- Get a Logistic Order by id — ORDER-501
- List Commercial Orders — ORDER-560 — see Search, Filter & Sort Orders
Updated 18 days ago

