Skip to main content

Support Weighted Items via Merchant Pick

Overview

The Mx Pick Weighted Items feature adds support for weighted line items — products sold by weight rather than by a fixed unit price (for example, loose produce, deli items, and bulk goods). Adopting this feature requires changes at two points in the order lifecycle:

  • Order transmit — DoorDash will include weighted item data (estimated quantity and purchase type) in the inbound order payload so your integration knows which items require weight reporting.
  • Order adjustment — After picking, your integration reports the actual measured weight back to DoorDash via the existing Order Adjustment API so the final price can be calculated correctly.

New fields are added to both the order transmit body and the PATCH /marketplace/api/v1/orders/{order_id}/adjustment endpoint. All new fields are optional for non-weighted items — existing integrations are unaffected until weighted items appear in an order.

Prerequisites

Reach out to your technical account manager to confirm your integration is enabled for Mx Pick Weighted Items before testing.


Order flow

Adopting this feature requires changes at both ends of the order lifecycle:

  1. Order transmit — DoorDash includes purchase_type on every line item and, for MEASUREMENT items, an estimated requested_quantity when dispatching the order to the merchant. The merchant must read these fields to know which items are weighted and what the customer's requested estimate is.
  2. Order adjustment — After picking, the merchant reports the actual measured weight back to DoorDash via the adjustment endpoint. DoorDash uses this to calculate the final charge.

Both steps are required. An integration that only handles the adjustment without reading the inbound weighted item fields will not have the data needed to pick correctly.

Inbound order payload changes

Weighted line items in the order transmit body now include purchase_type. MEASUREMENT items additionally include requested_quantity — the customer's initial estimated weight at order time. It is a single { quantity, unit } weight object. This is not the final picked weight; the merchant reports the picked weight back via fulfill_quantity on the adjustment request.

UNIT_TO_MEASUREMENT and UNIT items carry only purchase_type — no estimated quantity is sent on transmit.

The standard line-item fields you already receive (id, line_item_id, merchant_supplied_id, name, price, quantity, extras, …) are unchanged — the two weighted fields simply appear alongside them. Note that the integer quantity is the number of units ordered (for example, 3 bananas) and is independent of requested_quantity, which is the estimated weight of a MEASUREMENT item. The example below shows three line items — one of each purchase_type — within the order's categories array (some standard fields are trimmed for brevity):

{
"categories": [
{
"merchant_supplied_id": "DELI",
"name": "Deli",
"items": [
{
"id": "7117374961",
"line_item_id": "83632867-9cf6-4657-a48f-9504cc70864a",
"merchant_supplied_id": "DELI-1001",
"name": "Sliced Deli Turkey (per lb)",
"price": 1699,
"quantity": 1,
"purchase_type": "MEASUREMENT",
"requested_quantity": { "quantity": 0.75, "unit": "lb" }
}
]
},
{
"merchant_supplied_id": "PRODUCE",
"name": "Produce",
"items": [
{
"id": "7117374962",
"line_item_id": "94b653e4-e394-4330-a714-43e764abe843",
"merchant_supplied_id": "PRODUCE-2002",
"name": "Banana (each)",
"price": 45,
"quantity": 3,
"purchase_type": "UNIT_TO_MEASUREMENT"
}
]
},
{
"merchant_supplied_id": "GROCERY",
"name": "Grocery",
"items": [
{
"id": "7117374963",
"line_item_id": "c45b3754-03b2-4da6-ae7f-164d5f8f587b",
"merchant_supplied_id": "GROCERY-3003",
"name": "Sparkling Water 12-pack",
"price": 599,
"quantity": 2,
"purchase_type": "UNIT"
}
]
}
]
}
FieldAppears onMeaning
purchase_typeEvery line itemHow the item is priced and fulfilled — UNIT, MEASUREMENT, or UNIT_TO_MEASUREMENT (see purchase_type values)
requested_quantityMEASUREMENT items onlyThe customer's estimated weight at order time — a single { quantity, unit } object using the same weight units as continuous_quantity

fulfill_quantity is an adjustment-request field only and is never present in the order transmit body.


Endpoint

PATCH https://openapi.doordash.com/marketplace/api/v1/orders/{order_id}/adjustment

PropertyValue
MethodPATCH
AuthProvider API key (unchanged)
Content-Typeapplication/json
IdempotencyNo duplicate-submission deduplication. A no-op or invalid-state adjustment (e.g. order not confirmed or already cancelled) is rejected with 400

New Request Fields

The following fields are added to the existing AdjustedItem object. All are optional for non-weighted items.

FieldTypeRequiredDescription
purchase_typeenumRequired when sending weighted dataHow the line item is priced — see purchase_type values
fulfill_quantityFulfillQuantity[]Required for MEASUREMENT and UNIT_TO_MEASUREMENTPicker-reported actual weight — see fulfill_quantity

purchase_type Values

purchase_type indicates how a line item is priced and determines what weight data DoorDash expects.

ValueMeaningfulfill_quantity shape
UNITSold by discrete count only — not weightedMust NOT be sent
MEASUREMENTSold purely by weight (for example, loose produce per lb)Each entry: continuous_quantity only
UNIT_TO_MEASUREMENTSold in discrete units each weighed individually (for example, whole fish, deli packs)Each entry: both continuous_quantity AND discrete_quantity
warning

purchase_type must match what DoorDash has on record for that line item. Sending weight data (fulfill_quantity) on a UNIT item is rejected with a 409. Omitting fulfill_quantity on a MEASUREMENT or UNIT_TO_MEASUREMENT item is rejected with a 422.

fulfill_quantity

An array of fulfillment weight readings. For UNIT_TO_MEASUREMENT, send one entry per picked unit. For MEASUREMENT, one or more entries are valid (multiple entries are summed for the tolerance check).

FulfillQuantity object

{
"continuous_quantity": {
"quantity": 1.35,
"unit": "lb"
},
"discrete_quantity": {
"quantity": 1,
"unit": "ea"
}
}

continuous_quantity

Reports the measured weight of this reading.

FieldTypeRequiredDescription
quantitynumberYesPositive weight value
unitenumYesWeight unit — see accepted values below

Accepted weight units:

ValueName
lbPound (canonical)
lbsPound (alias, accepted for compatibility)
ozOunce
kgKilogram
gGram

discrete_quantity

Reports the count of physical units in this reading.

FieldTypeRequiredDescription
quantityintegerYesMust be >= 1
unitenumYesDiscrete unit — see accepted values below

Accepted discrete units:

ValueName
eaEach
qtyQuantity
packagePackage
bagBag
bunchBunch
boxBox
trayTray
bouquetBouquet
potPot

UNIT_TO_MEASUREMENT constraint

For UNIT_TO_MEASUREMENT items, send one fulfill_quantity entry per picked unit. The sum of all discrete_quantity.quantity values across entries must equal the top-level quantity field on the item. Mismatches are rejected with 422.


Weighted Substitutions

When substituting a weighted item, include purchase_type and fulfill_quantity on the substituted_item object.

FieldTypeRequiredDescription
merchant_supplied_idstringYesMerchant's identifier for the substitute item
namestringNoDisplay name of the substitute
priceinteger (cents)NoUnit price of the substitute
quantityintegerNoNumber of substitute units
purchase_typeenumRequired for weighted substitutesMust match the substitute item's pricing type
fulfill_quantityFulfillQuantity[]Required for MEASUREMENT / UNIT_TO_MEASUREMENT substitutesActual picked weight of the substitute
note

The customer-side weight tolerance check does not apply to substitutions, because the customer did not specify a target weight for the substitute item.


Example Requests

UNIT_TO_MEASUREMENT: Two packs of salmon, each weighed individually

{
"items": [
{
"line_item_id": "94b653e4-e394-4330-a714-43e764aergjn",
"adjustment_type": "ITEM_UPDATE",
"quantity": 2,
"purchase_type": "UNIT_TO_MEASUREMENT",
"fulfill_quantity": [
{
"continuous_quantity": { "quantity": 1.32, "unit": "lb" },
"discrete_quantity": { "quantity": 1, "unit": "ea" }
},
{
"continuous_quantity": { "quantity": 1.47, "unit": "lb" },
"discrete_quantity": { "quantity": 1, "unit": "ea" }
}
]
}
]
}

The sum of discrete_quantity (1 + 1 = 2) matches the top-level quantity of 2.

MEASUREMENT: Loose deli turkey, reported as a single weight

{
"items": [
{
"line_item_id": "b3c12a88-0011-42de-b901-aabbcc001122",
"adjustment_type": "ITEM_UPDATE",
"quantity": 1,
"purchase_type": "MEASUREMENT",
"fulfill_quantity": [
{
"continuous_quantity": { "quantity": 0.73, "unit": "lb" }
}
]
}
]
}

ITEM_SUBSTITUTE with a weighted substitute

{
"items": [
{
"line_item_id": "94b653e4-e394-4330-a714-43e764ab113",
"adjustment_type": "ITEM_SUBSTITUTE",
"substituted_item": {
"merchant_supplied_id": "item-179",
"name": "Organic Gala Apple",
"price": 350,
"quantity": 1,
"purchase_type": "MEASUREMENT",
"fulfill_quantity": [
{
"continuous_quantity": { "quantity": 0.82, "unit": "lb" }
}
]
}
}
]
}

Mixed: one weighted item and one non-weighted removal

{
"items": [
{
"line_item_id": "aabbcc00-1234-5678-9abc-def000000001",
"adjustment_type": "ITEM_UPDATE",
"quantity": 1,
"purchase_type": "MEASUREMENT",
"fulfill_quantity": [
{
"continuous_quantity": { "quantity": 0.55, "unit": "kg" }
}
]
},
{
"line_item_id": "aabbcc00-1234-5678-9abc-def000000002",
"adjustment_type": "ITEM_REMOVE"
}
]
}

Response Codes

HTTP CodeMeaningWhen it occurs
202 AcceptedSuccessAdjustment accepted and queued for processing
400 Bad RequestOrder state errorOrder is not yet confirmed, has been cancelled, the adjustment is a no-op, or the store is not enabled for order adjustments
401 UnauthorizedAuth failureMissing or invalid API key
403 ForbiddenPermission deniedCaller does not have access to this order
404 Not FoundUnknown identifierOrder, line item, or option ID does not exist
409 ConflictWeighted-item type conflictfulfill_quantity sent for a line item DoorDash priced as non-weighted (UNIT)
422 Unprocessable EntityWeighted-item validation failureStructural issue — including weighted data omitted for a MEASUREMENT or UNIT_TO_MEASUREMENT item. See Validation Rules
429 Too Many RequestsRate limitedRequest rate exceeded
500 Internal Server ErrorUnexpected errorContact DoorDash support
note

409 and 422 are new codes introduced for weighted items. They are only returned when purchase_type or fulfill_quantity is present in the request. Existing integrations that do not send these fields will never receive these codes.

All non-202 responses include a JSON error body:

{ "message": "Invalid weighted-item adjustment payload" }

Validation Rules

RuleCode
purchase_type = UNIT and non-empty fulfill_quantity sent409
purchase_type = MEASUREMENT or UNIT_TO_MEASUREMENT and fulfill_quantity absent or empty422
purchase_type does not match DoorDash's record for the line item422
MEASUREMENT entry contains discrete_quantity422
UNIT_TO_MEASUREMENT entry missing continuous_quantity or discrete_quantity422
Sum of discrete_quantity across entries does not equal item quantity (UNIT_TO_MEASUREMENT)422
continuous_quantity.unit not in the accepted weight unit list422
discrete_quantity.unit not in the accepted discrete unit list422
continuous_quantity.quantity is less than or equal to 0422
discrete_quantity.quantity is less than 1422
Picked weight outside the allowed tolerance (applies to MEASUREMENT and UNIT_TO_MEASUREMENT ITEM_UPDATEs with a recorded estimated weight; not applied to substitutions)422