[Explainer] Substitutions & Other Shopping Use Cases
Substitutions instructions can be specified in a few different ways for when the dasher is unable to find the requested item and marks it out of stock.
An example flow: During ecommerce shopping, allow customers to select if they want an item to be substituted or not.
-
If yes
- Allow customers to pre-select items → pass these items through the delivery creation payload
- If customers have not pre-selected items
- Recommend most popular / probable substitutions to guide the dashers → pass these items through the delivery creation payload (merchant recommended subs)
- [or] Choose the “contact” option as the substitution preference in the delivery creation payload so the dasher can contact the customer during shopping to align on a substitution preference
- Allow dashers to add net new items to the cart upon customer request
- Surface the white label subs link so customers can update their substitution instructions for any item even after the DoorDash order has been created.
-
If not
- Choose the Refund option as the substitution preference in the delivery creation payload so the dasher marks the item as out of stock and does not pick a substitute
- Surface the white label subs link so customers can update their substitution instructions for any item even after the DoorDash order has been created.
Send through substitution instructions for an item in a few different ways:
Item-specific option
You can send item-specific substitution options for the Dasher to choose from as part of the Delivery Creation payload as well as the PATCH Update API endpoint (until dasher assignment).
Customer-selected if you allow your customers to pre-select items. This is highly recommended as the dasher has some options to choose from instead of having to call the customer.

| Field Name (Drive API) | Field Value |
|---|---|
| items.item_options.substitution_preference | "substitute" |
| items.item_options.substitute_item_ids | merchant item id(s) |
| items.item_options.substitute_item_ids_additional_metadata.id | merchant item id(s) of substitute item |
| items.item_options.substitute_item_ids_additional_metadata.quantity | quantity of substitution item |
| items.item_options.substitute_item_ids_additional_metadata.weight | weight of substitution item |
| items.item_options.substitute_item_ids_additional_metadata.weight_unit | weight unit of substitution item (i.e. "lbs") |
Merchant recommended subs if you want to send through your own recommendations. This is especially helpful if your customers have not pre-selected their substitutions and you are able to provide some options for the dasher to choose from at the store. In this scenario, the dasher will still text the customer informing them of the item they are substituting with so the customer is able to confirm.

| Field Name (Drive API) | Field Value |
|---|---|
| items.item_options.substitution_preference | "substitute" |
| items.item_options.merchant_recommended_substitute_item_ids | merchant item id(s) |
| items.item_options.substitute_item_ids_additional_metadata.id | merchant item id(s) of substitute item |
| items.item_options.substitute_item_ids_additional_metadata.quantity | quantity of substitution item |
| items.item_options.substitute_item_ids_additional_metadata.weight | weight of substitution item |
| items.item_options.substitute_item_ids_additional_metadata.weight_unit | weight unit of substitution item (i.e. "lbs") |
The dasher_completed_shopping webhook will reflect this shopping via the following fields: Substitution_source = “dasher”
Note: please reach out to the DoorDash Integrations team to enable this option via a configuration.
“Contact Me” option
You can request that the Dasher contact the customer during the pick process to agree on a suitable substitution

| Field Name (Drive API) | Field Value |
|---|---|
| items.item_options.substitution_preference | "contact" |
Note: if you want to disable customer communications during dasher shop time, please reach out to DoorDash.
“Refund me” option
You can ask the Dasher not to pick another option and mark the item out of stock, in the event that the requested item is unavailable.
| Field Name (Drive API) | Field Value |
|---|---|
| items.item_options.substitution_preference | "refund" |
White-label post checkout option

Customers, via a link, can update their substitution preferences to “contact me” or “refund me” options, or choose a substitution from DoorDash’s list of item recommendations.
- The link to this white-label UI will come through via customer text messages or through the tracking link (found in webhooks or delivery creation response payload).
- Customer preferences from past selections will be saved.
- Steps to enable functionality:
- Step 1: Reach out to the DoorDash Integrations team to turn on the white label UI configuration.
- Step 2
[if DoorDash owns customer communications]
- Navigate to the “SMS” Settings in your Developer Portal, select the appropriate business from the dropdown and configure the variable
{subs_link}to your desired text message.- We recommend you add the
{subs_link}variable to the “Delivery created” SMS. Example: “Please make substitution selections via{subs_link}” - Ensure the Drive API field “should_send_notifications” is set to true to allow customer text messages to go through.
- Skip this step if you do not want text messages enabled. [if Merchant owns customer communications]
- We recommend you add the
- We recommend you send the subs link right after the ecommerce checkout so the customers have the ability to fill in substitution instructions well in advance.
- Navigate to the “SMS” Settings in your Developer Portal, select the appropriate business from the dropdown and configure the variable
Force Overrides
Allow the dasher pick up an item by asserting the item they have picked up is correct, regardless of a failed barcode scan. This feature is useful when the barcode is damaged or there is a UPC mismatch with the catalog data previously sent. To override, the dasher will click the button “I have the correct item”, take a photo and proceed.
Configuration options: Reach out to DoorDash if you want to allow dasher to pick an override
- That is in the catalog data sent to DoorDash

- That is not in the catalog data sent to DoorDash

- The dasher_completed_shopping webhook will reflect this shopping via the following fields:
- Substitution_source = “dasher”
- Scanned_barcode = overridden item’s barcode
Dasher-addition of new items to cart
This is the ability for a dasher to add net new items to the cart upon customer request during shop time. Activating the dasher-addition flow requires a call or text between the customer and dasher during the shopping process. This feature can help customers add items they may have forgotten when they first created the order. The dasher can add up to 5 new items (configurable). Maximum weight for an item can also be configured. A consideration for the merchant would be to plan for the incremental charges.

The dasher_completed_shopping webhook will reflect this shopping via the following fields: addition_source = “dasher”
Note: Reach out to the DoorDash Integrations team to enable this feature.
Multiple instance of same item
You can add multiple instances of the same item (same item id) to an order if there are item-level differences for each instance. For example: allowing your customers to add two types of bananas (yellow bananas, green bananas) or two cuts of meat with different weights.

Use the following fields to indicate the differences:
| Field Name (Drive API) | Field Value |
|---|---|
| items.special_instructions | item-level notes (i.e. "green bananas") |
| items.external_instance_id | id to differentiate same external id |
Multi-Scan Variable Weight Items
For variable weight items where a Dasher scans multiple individual packs; for example, two packs of steak each with a different weight, DoorDash can return per-scan barcode data in the DASHER_COMPLETED_SHOPPING webhook.
When this feature is enabled, a new field called item_entries_info is included as a nested field within each item in the shopped_items array. Each element in item_entries_info corresponds to one scanned pack and contains two fields:
| Field Name (Drive API) | Always Present or May be Null | Description |
|---|---|---|
| entry_fulfilled_substitution_type | Always Present | How the item was fulfilled. Enum: no_substitution, pre_selected, override, contact, generic_substitution, unspecified |
| scanned_data_list | Always Present | List of decoded barcode objects for this pack. See scanned_data_list schema below. |
entry_fulfilled_substitution_type values
| Field Value | Meaning |
|---|---|
| no_substitution | Original item was picked |
| pre_selected | A substitution pre-approved by the customer or merchant was picked |
| override | Dasher picked an item that does not match the expected original or substitution, but asserts they have the right item |
| contact | Dasher contacted customer to get substitution approval |
| generic_substitution | Dasher picked a generic substitute requested by customer |
| unspecified | Other scenarios |
scanned_data_list schema (per pack) Each entry in item_entries_info contains a scanned_data_list. The same structure is used from the top-level item, but scoped to a single pack. Fields are identical to the top-level scanned_data_list, with the addition of GS1-specific decoded fields:
| Field Name (Drive API) | Always Present or May be Null | Description |
|---|---|---|
| format | Always Present | Barcode format. One of: upc_a, upc_e, ean_13, ean_8, plu, gtin-14, gs1-data-matrix |
| is_variable_measure | May be Null | Whether the item is variable weight/measure. true / false / null |
| indicator_digit | May be Null | Used in GTIN-14 barcodes to classify the item type |
| product_code | May be Null | Identifies the item within a given system |
| check_digit | May be Null | Verifies integrity of the barcode data |
| country_code | May be Null | Country where manufacturer is registered. Used in EAN-13 and EAN-8 |
| manufacturer_code | May be Null | Company that produced the product. Used in UPC-A, EAN-13, UPC-E |
| number_system | May be Null | Type/categorization of barcode. Used in UPC-A and UPC-E |
| plu_check_digit | May be Null | Price check digit for variable measure barcodes |
| company_prefix | May be Null | Brand owner identifier. Used in GTIN-14 |
| item_reference | May be Null | Identifies product within a company. Used in GTIN-14 |
| scanned_code_sans_check_digit | May be Null | Scanned barcode value excluding the check digit |
| barcode_weight | May be Null | Weight decoded directly from the barcode |
| barcode_price | May be Null | Price decoded directly from the barcode |
| barcode_weight_unit | May be Null | Unit of measurement for barcode_weight (e.g. kg) |
| scanned_code | May be Null | Complete scanned barcode string. May contain FNC1 separator characters for GS1 Data Matrix barcodes |
| variable_measure | May be Null | Variable field that cannot be definitively interpreted as weight or price. Only populated when the distinction is ambiguous — the merchant's POS determines meaning |
| barcode_expiration_date | May be Null | Expiration date encoded in the barcode, in YYYY-MM-DD format. Null if not deducible from the barcode |
Note: Reach out to the DoorDash Integrations team to enable this feature.