Skip to main content

Batch & Best-Before-Date Management on Order Lines

Audience: developers integrating a merchant's order/ERP system with Logitrail's Order API, who need to control exactly which physical stock (which incoming batch, or stock with a specific best-before date) is used to fulfill an order line.

This guide explains how to restrict an order line to a specific batch number and/or best-before date, why you'd want to, and what to expect once you do. It assumes you already have Logitrail API credentials — see Authentication if you don't.


1. Base URL and versioning​

EnvironmentBase URL
Test / sandboxhttps://api-1.test.logitrail.com
Productionhttps://api-1.logitrail.com

All endpoints in this guide are under the /v1/orders path.


2. Authentication​

Every request needs the standard two headers (OAuth 2.0 client-credentials bearer token + merchant id):

HeaderValue
AuthorizationBearer <access_token>
X-Logitrail-Merchant-IdYour Logitrail merchant id

Reading an order requires the orders:read scope; setting or clearing a batch/best-before restriction requires orders:manage. See Authentication for how to obtain a token.


3. What this feature is for​

By default, Logitrail's warehouse fulfills an order line by picking whichever eligible stock is oldest by expiry (FEFO — first-expiry-first-out). Most merchants never need to override this.

Sometimes you do need control over exactly which physical stock ships, for example:

  • Traceability / recall compliance — pinning an order to a specific vendor batch/LOT for food, pharma, or other recall-traceable goods.
  • Known-good stock — you've identified a specific incoming batch (e.g. from a particular inbound shipment) that must be the one shipped, overriding the default oldest-first pick.

You do this per order line, by setting best_before_date, batch_numbers, or both. Setting either turns off default FEFO picking for that line and constrains the warehouse to stock matching your restriction.

This only affects lines fulfilled by Logitrail's own warehouse (fulfillment_by: "logitrail"). It has no effect on lines the merchant fulfills themselves.


4. Key concepts​

TermMeaning
Batch / LOT numberThe vendor's manufacturing/production batch identifier, captured when goods are shelved. A product can have stock from several different incoming batches on the shelf at once, each with its own batch number and best-before date.
Best-before dateThe expiry date recorded against a specific incoming batch when it was shelved.

Two fields on an order line carry the restriction:

FieldTypeNotes
best_before_datestring, ISO 8601 date (YYYY-MM-DD)The warehouse must pick stock whose best-before date exactly equals this date — not "on or before".
batch_numbersarray of strings, minimum one entryThe warehouse may pick stock from any batch in this list.

The best-before match is exact, not a range. Despite the name, best_before_date does not mean "anything expiring on or before this date" — it means "only stock whose recorded best-before date is exactly this date." If you don't know the exact date of the batch you want, use batch_numbers instead (or in addition).

If you set both fields on the same line, both must match on the same physical stock — the warehouse picks stock that has one of the listed batch numbers and the exact best-before date. This is normally what you want when a batch number alone isn't unique enough to identify the stock you mean.


5. Setting a restriction​

5.1 At order creation​

Include best_before_date and/or batch_numbers on the line item when creating the order:

POST /v1/orders
Scope: orders:manage
{
"order": {
"...": "other order fields",
"items": [
{
"product": { "id": "64b8f0c2e1b2c3d4e5f67891" },
"quantity": 10,
"batch_numbers": ["LOT-2026-0142"],
"best_before_date": "2026-11-30"
}
]
}
}

Both fields are optional — omit them for normal FEFO picking.

5.2 On an existing order line​

PATCH /v1/orders/{orderId}/items/{itemId}
Scope: orders:manage

This is a dedicated per-line patch endpoint — it only ever touches best_before_date and batch_numbers, leaving the rest of the order line untouched. Each field independently supports three states:

You sendEffect
Field omitted from the bodyLeft unchanged
Field set to a valueRestriction set to that value
Field set to nullRestriction cleared

Set both fields:

{
"best_before_date": "2026-11-30",
"batch_numbers": ["LOT-2026-0142"]
}

Set only the batch restriction, leaving any existing best-before restriction untouched:

{
"batch_numbers": ["LOT-2026-0142", "LOT-2026-0143"]
}

Clear both restrictions (back to normal FEFO picking):

{
"best_before_date": null,
"batch_numbers": null
}

Response — 200 OK, body { "order": { "...": "the full updated order" } }.

5.3 Reading the current restriction​

best_before_date and batch_numbers are returned on every order line by GET /v1/orders/{orderId} and GET /v1/orders (scope orders:read) — null/omitted when no restriction is set.


6. Validation and errors​

PATCH /v1/orders/{orderId}/items/{itemId} returns:

StatusCause
400 Bad RequestMalformed orderId/itemId, malformed best_before_date (must be YYYY-MM-DD), or an empty batch_numbers array. To clear batch_numbers, send null — not [].
404 Not FoundThe order doesn't exist for your merchant account, or the item id isn't on the order.

7. What happens after you set a restriction​

Applying a restriction doesn't validate it against current stock at write time — you can set a batch number or date for which no stock currently exists on the shelf. What happens next:

  • If matching stock exists, the warehouse reserves it for the line (replacing any previously reserved stock that no longer matches, as long as that stock hasn't already been physically staged for picking on this order).
  • If no matching stock exists yet, the line is held the same way any out-of-stock line is — it will fulfil once stock matching your restriction arrives and is shelved.
  • Re-evaluation happens asynchronously after your call — expect a short delay (typically seconds) before the order's reservation reflects a change you just made.

Because there's no write-time check against real stock, a batch number with a typo or a best-before date that doesn't match anything on the shelf won't be rejected — it will simply never find matching stock. Double-check the value against what you know was shelved before setting it, particularly for best_before_date given the exact-match behaviour in §4.


8. Merchant portal​

The Logitrail merchant portal exposes these fields when creating an order (a best-before date picker and a comma-separated batch-numbers field per line) and displays them read-only once the order exists. To change a restriction on an order that's already been created, use the PATCH endpoint described in §5.2 — the portal does not currently offer an edit-in-place control for this.


Questions​

For API credentials or anything not covered here, contact your Logitrail integration contact.