Order Adjustments
Overview
When the kitchen cannot fulfill an order exactly as placed, your POS can ask Stream to adjust it: remove a line item, reduce its quantity, or substitute another item (a size downgrade counts as a substitution). Stream validates the request immediately, pushes the change to the DSP, and reports the outcome back to your Handle Order endpoint.
POS-initiated adjustments are opt-in and enabled per merchant. Contact Stream to enable them. Until then, requests are rejected with 403 feature_disabled.
Not supported: adding items, refund amounts, and modifier-level changes.
DSP support
| DSP | Removal | Quantity reduction | Substitution |
|---|---|---|---|
| DoorDash | Yes | Yes | No |
| Uber Eats | Yes | Yes | No |
| Glovo | Yes | Yes | Yes |
| Other DSPs | No | No | No |
A DSP can still decline an adjustment it normally supports. Uber Eats, for example, may ask the customer to confirm. Stream then reports the result asynchronously (see Results).
Requesting an Adjustment
Send an order.adjustment.requested event to the Handle Webhook Event endpoint, signed like every other webhook event.
{
"type": "order.adjustment.requested",
"object": {
"order_id": "8c1f0f3e2d0b4c6a",
"location_id": "location-456",
"adjustments": [
{ "_id": "fries_line_id", "adjustment_type": "removal" },
{
"_id": "burger_line_id",
"adjustment_type": "quantity_update",
"new_quantity": 1
},
{
"_id": "soda_line_id",
"adjustment_type": "substitution",
"substitution": {
"provider_id": "water-sku",
"name": "Water",
"quantity": 1
}
}
]
}
}
- order_id: the Stream order id, sent as
idempotency_keyonorder.created. - location_id: your provider location id for the order.
- adjustments[]._id: the line item's
_idfromorder.created(line_items[]._id). Each line item may appear at most once. - new_quantity: required for
quantity_update. It must be at least 1 and lower than the current quantity. To go to zero, useremoval. - substitution: required for
substitution. Give the replacement'sprovider_idandquantity;nameis optional. The line keeps its original price.
An order can be adjusted once. Combine every change into a single request.
Validation Responses
Stream answers synchronously. A 2xx means the request was accepted and is being sent to the DSP. Rejections return a JSON body with a machine-readable code:
{
"statusCode": 409,
"error": "Conflict",
"code": "order_not_modifiable",
"message": "Order is not modifiable in status ready_for_pickup"
}
| HTTP | code | When |
|---|---|---|
| 400 | — | Malformed payload (missing fields, unknown adjustment_type, duplicate _id) |
| 403 | feature_disabled | The merchant is not enabled for POS-initiated adjustments |
| 404 | order_not_found | No order with this order_id at this location_id |
| 409 | order_not_modifiable | The order is not pending/in_progress, or it was canceled |
| 409 | order_already_adjusted | The order was already adjusted |
| 400 | unsupported_by_dsp | The DSP does not accept POS adjustments, or does not support substitutions |
| 400 | invalid_adjustment | _id not on the order or matching more than one line, new_quantity too high, or every item removed |
Results
Once the DSP responds, Stream sends one of these events to your Handle Order endpoint:
order.adjusted: the full, updated order, withadjusted: trueandapplied_adjustmentslisting what the DSP accepted. Each applied adjustment carries the line item_idand, for substitutions, thesubstitution.order.adjustment.failed: nothing was changed on the order.
{
"type": "order.adjustment.failed",
"object": {
"order_id": "8c1f0f3e2d0b4c6a",
"location_id": "location-456",
"code": "dsp_rejected",
"reason": "Order already picked up",
"adjustments": [{ "_id": "fries_line_id", "adjustment_type": "removal" }]
}
}
code | Meaning |
|---|---|
unsupported_by_dsp | The DSP does not support this adjustment for this order |
dsp_rejected | The DSP refused the adjustment |
dsp_error | The DSP could not be reached or returned an unexpected error |
order_not_modifiable | The order changed after the request was accepted (e.g. canceled) |
A failed adjustment does not use up the order's one adjustment. You may send a corrected request.