Upload menu

With the Upload Menu API you can:

  1. Create a new menu in Deliveroo.
  2. Update an existing menu using the same menu ID that was sent when the menu was created.
  3. Assign multiple sites to the same menu.
    Use the Upload menu API if you wish to create menus or update existing menus to let users see the most updated status of your menus and offerings. Reduce the chances of poor customer experience due to orders being placed against an outdated menu by updating outdated menus in real time without any manual intervention.

This endpoint is rate limited at 1 request per minute per site. Additionally, for menus with payloads over 5 MB, there is also a limit of 10 requests per 10 seconds per entire integration partner.

The request size limit is 10 MB. However, to make sure you can successfully GET your menus, you should keep your requests no larger than 9 MB as the GET response payload size can be larger than the menu you sent through PUT. In general for large menus we recommend using the new Catalogue API (the documentation is coming soon).

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Path Params
string
required

The unique identifier for the brand (Deliveroo's integration team will provide this).

string
required

The unique identifier for the menu for the given "brand" context.

Body Params

Request body for publishing a menu. Deliberately not composed from SiteMenu: that schema is also a GET response and marks name as required, which this endpoint ignores (the menu name comes from the URL path).
Also the shape of the document uploaded to the presigned URL from PUT /v3/brands/{brand_id}/menus/{id}, which has no request body of its own.

menu
object
required

Menu object

site_ids
array of strings
required

IDs of the sites the menu should be published to.

site_ids*
string

The POS system the merchant actually runs, applied to every site in site_ids - upload sites on different POS systems separately. Name the system behind the site, not yourself: your own name as a stand-in for a POS you cannot see tells us nothing we did not already know, and costs us the one thing this field is for. Leave it out rather than guess.

Optional free text, up to 128 characters rather than bytes; trimmed and NFC-normalised before storage. Over-length and other rejected values are reported rather than refused - see below - so the limit never fails an upload.

Rejecting the value never changes what happens to the menu itself: it is accepted or refused on its own merits, and the reason for the pos_name comes back in the non-fatal warnings array (too_long, empty, control_character, line_separator, zero_width_or_bidi, replacement_character). replacement_character means the request was mis-encoded, so check its encoding rather than the name. control_character, line_separator and zero_width_or_bidi all mean the value carried something invisible or line-breaking, usually from a copy-paste: send it as plain single-line text. On the v3 large-menu upload the same warning appears in details.warnings on GET /v3/brands/{brand_id}/jobs/{job_id}.

Three things we ask of you:

  1. Treat it as a dynamic value: send a menu update when a site changes POS system, otherwise the value we hold goes stale.

  2. If the name you are reporting is a white-labelled version of your own platform rather than an independent POS system, mark it with the suffix _WL - that exact token, at the end. It tells us the name is a rebadge of your platform rather than an independent POS, which we have no other way to know. We store the value verbatim, suffix included, and it counts toward the 128 characters.

  3. Omitting the field leaves the stored value unchanged; an empty string is rejected rather than clearing it. Where two overlapping uploads disagree for the same site, the last write wins.

Responses

Language
Credentials
OAuth2
URL
LoadingLoading…
Response
Choose an example:
application/json