Skip to main content

Create & update menus

Limited access

Marketplace APIs are not yet generally available. Please record interest in early access here.

The image below presents a high level overview of how Menu creation and update work via our API.

Menu

Creating Menus (Pull)

GET /{merchant_pull_menu_endpoint}/{location_id}

As part of the integration workflow, partners must implement an endpoint that allows DoorDash to pull menus. This enables a more streamlined process when onboarding new stores. With this, the DoorDash team can configure the store and pull the corresponding menu all at one time, rather than coordinating with our partners for the menu push. The response for the menu ingestion process will match what is described below for the push method. The response to this GET request will differ from your Push request. Regardless of if multiple menus need to be returned as part of the response, the menus should be included as an array. Example below.

{
"store": {
"merchant_supplied_id": "<client's store id>",
"provider_type": "<client’s DoorDash provider type>"
},
"menus": [
{...},
{...}
]
}

Note: As the sample response above indicates, the response on Menu Pull request must return the menu(s) as an array, even if there is only one menu being returned.

Partners are expected to return appropriate response codes if the Menu Pull request fails for streamlined triage and escalation if needed.

Once our service is finished creating your menu or if the menu creation fails, the service will send out a POST webhook request with the menu creation result. You need to create an endpoint and provide us with its URL in order to receive the webhook notification. This request will contain the same "reference" as the response to your initial request, allowing you to keep track of which requests have been completely processed. You can find more details about this webhook in the section Know when your menu is ready.

Creating Menus (Push)

POST /api/v1/menus

DoorDash’s menu creation pipeline works asynchronously. Upon making a successful request to the POST endpoint, you will receive a response with status code 200 indicating that we’ve successfully received the request to create the menu. The result of this request will be sent back to you later via a menu status webhook. Menu processing time can differ depending on the size of the queue at the time the menu job was created. Average menu processing time is less than 1 minute.

The menu request body contains a reference field, which is optional. This could be any merchant supplied id that references the menu create request and will be returned back in the menu status webhook to identify the original request for which the status is. If not provided, DoorDash will populate this id and the DoorDash generated id will be sent back via the response to the MENU POST. Do not leave it as an empty string or null value.

The menu request body contains a provider_type field which should pass your provider type without any version number. For example, if your header is "User-Agent": DoordashClient/1.0 then the value to pass in the provider_type field in the body of the call would simply be "provider_type": "doordash_client".

Once our service is finished creating your menu or if the menu creation fails, the service will send out a POST webhook request with the menu creation result. You need to create an endpoint and provide us with its URL in order to receive the webhook notification. This request will contain the same reference as the response to your initial request, allowing you to keep track of which requests have been completely processed. You can find more details about this webhook in the section Receiving Menu Status Updates.

Preventing Duplicate Menus

To prevent duplicate menus from being created for stores, DoorDash examines the menu.merchant_supplied_id within the menu payload for POST requests to determine if an active menu already exists with the same value for this field. This works similiarly as if you try to save a file to a folder that already contains a file with the same name, in which case you're prompted to either rename the file or overwrite the existing file.

If a match is found (using menu.merchant_supplied_id), the existing menu will be overwritten using the payload in the request. Additionally a new menu.id will be generated for the menu and sent back once the update is done processing. This new menu.id as well as the original menu.id for the menu can be used to update the menu (backwards compatible).

The below example demonstrates what would happen if a duplicate menu-create request was received without this logic:

prior_logic_example

The next example demonstrates the current logic DoorDash has that prevents the above scenario from happening:

current_logic_example

Updating Menus (Push)

PATCH /api/v1/menus/{id}

Upon creating a menu, you will receive the "id": "menu-id" (UUID) in the POST request sent out by DoorDash’s menu status webhook. When updating a menu, you should include that menu’s ID in the URL parameters. Menu processing time can differ depending on the size of the queue at the time the menu job was created, but average menu processing time is less than 1 minute.

The menu update pipeline works identically to the menu creation pipeline. When updating a menu, you will need to include the full menu in your request, not just the specific fields you wish to update. Hence, the data validation for the PATCH endpoint will be identical to the POST endpoint because it uses the same model. Just as with POST, you can also provide a reference field in the payload to identify your request or rely on the DoorDash generated reference.

Once our service is finished updating your menu or if the menu update fails, our webhook will send a POST request to the endpoint you provide us with. Details can be found in the following section, Receiving Menu Status Updates.

Updating Menus (Pull)

GET /{merchant_pull_menu_endpoint}/{location_id}[?ids=external_menu_ids]

Note: Updating Menus via the Menu Pull method is part of the Menu Pull requirement

Partners can utilize the same pull endpoint to allow DoorDash to request menu updates based on a list of external menu ids. This allows for flexibility on the DoorDash side to ensure menus are in sync. The recommendation is that Push logic is still built out on the provider’s side to automatically trigger menu updates when changes are made within the POS. Upon creating a menu, you will receive the "id": "menu-id" (UUID) in the POST request sent out by DoorDash’s menu status webhook.

Please Note:

The "id": "menu-id" (UUID) field is required for Updating Menus via Menu Pull & it must be included within the menu payload.

The "id": "menu-id"(UUID) field is to be placed within the menus array. Please see the sample below:

{
"store": {
"merchant_supplied_id": "",
"provider_type": ""
},
"menus": [
{
"id": "string",
"reference": "string",
"open_hours": [
{
"day_index": "MON",
"start_time": "00:00",
"end_time": "23:59"
}
],
"special_hours": [],
"menu": {
"name": "string",
"subtitle": "string",
"merchant_supplied_id": "string",
"active": true,
"categories": [
]
}
}
]
}
Status CodeDetails
200Success
400Bad Request
403Forbidden
429Too Many Requests
500Internal Server Error

If you receive a 429, please retry after 1 minute. If you receive a 500, please retry with exponential backoff. If you receive a 400 response, please do not retry. There should be an associated error message with a 400 status code that will help with diagnosing the origin of the issue (example below).

400 Bad Request: Invalid menu payload: [StoreMenu.menu.MenuCategory[IcedBeverages]: find duplicate merchant id:5757, name:Freshly Brewed Iced Coffee - Create Your Own - Custom.]

In the above example, there is already an item with the merchant_supplied_id of 5757. This is stating that there are duplicate IDs for an item within the same level of the Menu. To resolve this error, you must have unique merchant_supplied_ids for items within the same Menu Level.

Status CodeBodyDescription
200INVALID_ARGUMENT::INVALID_ARGUMENT: Already have a job IN_PROGRESSA menu job is already in progress for this location. Please wait a few minutes to trigger another job.
400INVALID_ARGUMENT::INVALID_ARGUMENT: Store does not exist for the menuThe menu.json includes a store "merchant_supplied_id" that does not exist. Please make sure the store "merchant_supplied_id" in the menu.json is correct.
403INVALID_ARGUMENT::INVALID_ARGUMENT: Mismatch menu id and store idThe menu ID within the menu.json to run a menu update is incorrect and does not exist for the store. Please make sure the menu ID within the payload is correct. This ID was returned when the menu was created and should have been stored.
429Developer account endpoint rate limit exceededThe rate limit has been exceeded. Please retry the job after 1 minute.
400INVALID_ARGUMENT::INVALID_ARGUMENT: Store under active onboarding and not ready to receive menu pushPlease use the correct Menu Create/Update Endpoint for SSIO to trigger a Menu Pull.

If a field within the menu payload exceeds the allowed Max Length, the menu will fail with a 400 Bad Request response. Please adhere to the max length fields listed below.

FieldMax Length
Menu
name500
subtitle500
merchant_supplied_id1024
Category
name500
subtitle500
merchant_supplied_id1024
Item, ItemExtra and ItemExtraOption
name500
description1000
merchant_supplied_id1024

Notable Menu Fields

  • reference: Required field in menu pull response. It is a merchant menu identifier which will be linked to the id (external menu id)
  • id (external menu id): Required is event type is MenuUpdate. Returned when the menu is created and must be stored by the merchant after MenuCreate.
  • original_image_url: Used to automatically pull in images via the Menu API. More details included in the FAQ section.
  • nutritional_info: Used to define calorie information for items and modifiers.
  • classification_tags: Used to designate nutritional dietary tags for items and modifiers.
  • tax_rate: Optional field to define tax rate at the item and the item extra option level for non-Marketplace facilitator states. The rate should be sent as a whole number. For example, my tax rate is 5% for an item. The tax_rate should be sent as 5 in the menu payload (not .05). If tax rates are not sent in the menu, DoorDash third party tax engine will be used for tax calculations. Please reach out to your DoorDash contact for more information if you plan to send tax rates in the menu.
  • tax_category: Optional field to define tax category at the item and the item extra option level for non-Marketplace facilitator states. Please reach out to your DoorDash contact for more information if you plan to send tax category in the menu.