Batch Context
Purpose
This feature lets partners declare, at the moment they begin picking, whether the order is being picked alongside other orders in a batch — and if so, which batch and how it was composed.
Batch context is captured once per order at start-picking, persisted at the order level, surfaced on subsequent prep-state reads. It does not affect order acceptance, picking flow, or amendments.
Core Schema and Enums
BatchContext (object)
| Field | Type | Required | Description |
|---|---|---|---|
is_batched | bool | yes | true if this order is being picked as part of a batch |
batch_id | string | when is_batched=true | Partner-supplied identifier shared by all orders in the same batch |
batch_size | uint32 | when is_batched=true | Number of orders in the batch (must be ≥ 2) |
batch_scope | enum | when is_batched=true | See BatchScope below |
BatchScope (enum)
SINGLE_AGGREGATOR— All orders in the batch originate from a single aggregator (e.g. all Deliveroo)CROSS_AGGREGATOR— Orders in the batch span multiple aggregators
Key Architectural Principles
Captured once, at start-picking only:
Batch context is recorded at the moment picking begins and is not updated later in the order's lifecycle.
Order-level, not item-level:
Unlike prep-state and amendments, batch context attaches to the order, not to individual items. It appears alongside (not inside) the prep-state items on read responses.
Independent of amendments and prep-state:
Batch context does not interact with amendments, archival, or item-level updates. Amending an order does not clear, replace, or invalidate the recorded batch context.
API Endpoint
PUT /v1/picking/orders/{order_id}/start_picking
Request body:
{
"batch_context": {
"is_batched": true,
"batch_id": "wave-123",
"batch_size": 3,
"batch_scope": "CROSS_AGGREGATOR"
}
}{
"batch_context": { "is_batched": false }
}Validation rules:
- When
is_batched = true:batch_idis required and must be non-empty.batch_sizeis required and must be ≥ 2. A missing/zerobatch_sizereturnsbatch_size is required; values of 1 returnbatch_size must be >= 2.batch_scopeis required and must be one ofSINGLE_AGGREGATORorCROSS_AGGREGATOR.
- When
is_batched = false:batch_id,batch_size, andbatch_scopemust all be unset. Sending any of them alongsideis_batched: falseis rejected. - Malformed JSON is rejected with
400 BAD_REQUEST.
Successful response:
{ "message": "Preparation stage updated successfully" }Recorded batch context is observable via the prep-state read endpoints (below).
Read-Back via Prep-State
Once batch context has been recorded for an order, it is included on prep-state reads:
GET /picking/v1/orders/{order_id}/prep-state
{
"location_id": "...",
"order_id": "...",
"items": [ ... ],
"batch_context": {
"is_batched": true,
"batch_id": "wave-123",
"batch_size": 3,
"batch_scope": "CROSS_AGGREGATOR"
}
}GET /picking/v1/orders/{order_id}/prep-state/items/{item_id}
The single-item response includes the same batch_context field at the top level.
Rules:
- For non-batched orders, the response contains
{ "is_batched": false }with the optional fields absent. batch_contextis order-level metadata; it is identical across every item-level response for the same order.
Error Handling
Non-Retryable (4xx):
400 BAD_REQUEST— Malformed JSON, orbatch_contextvalidation failure (missingbatch_id, invalidbatch_size, unrecognisedbatch_scope, or fields set whenis_batched: false).401 UNAUTHORIZED— As per the existing start-picking contract.404 NOT_FOUND— Order does not exist.429 TOO_MANY_REQUESTS— The 1-request-per-order-per-30-seconds rate limit on start-picking applies unchanged.
Retryable (5xx):
500 INTERNAL(failed to store batch context) — The order transition itself may not have completed; partners should retry the entire start-picking call. Retries with the same payload are safe.
Integration Best Practices
- Send batch context exactly once per order, in the
start_pickingrequest. - Use a stable
batch_idshared by every order in the same batch. The ID is partner-supplied and opaque to Deliveroo; choose a format that lets you correlate it back to your own dispatch records. - Don't synthesise batches for single orders: if a picker is handling one order, send
is_batched: falserather than a batch of size 1.batch_size = 1is rejected. - Do not depend on echo back in the start-picking response. If you need to confirm the recorded value, fetch the prep-state GET endpoint.
Updated about 12 hours ago
