Skip to content

List menu items

Try it

Lists menu items with their add-ons, filtered by name, category, availability or whether they are on the menu.

GEThttps://tablebuddy.radioworkflow.com/api/v1/menu/items
Read

Paged in id order. Filters combine: q matches the name or the code, in any case; available=false lists what is sold out (86ed) and active=false what has been taken off the menu. A cursor holds only with the same filters.

Each item carries its add-on groups and the add-ons in them. No cost price and no recipe: those are the stockroom's. Toast owns a linked item's name, price, description and place on the menu, so those read as Toast has them.

Authentication

Key
Authorization: Bearer <key>, or the same key in x-api-key. A key acts as the person who made it, cut down to this endpoint’s scope, and never as an owner. How keys work
Scope
menu:readRead the menu
The key's creator needs
Take orders on the POS (pos.use) or Edit the menu (menu.manage)

Request headers

Authorizationrequired
Bearer <key>. x-api-key: <key> works too; Authorization wins when both are sent.
Idempotency-Keyignored
Ignored: a read changes nothing, so there is nothing to repeat. Idempotency

Query parameters

limitinteger1–100optional
Rows per page, 1 to 100.

Default 50.

cursorstringidoptional
next_cursor from the previous page.
qstring1–80 charsoptional
Only items whose name or code contains this, in any case: 1 to 80 characters, not blank.

Not blank; no NUL character or unpaired surrogate.

category_idstringidoptional
Only items in this category.
availableenumoptional
true for items on sale, false for items sold out (86ed).
truefalse
activeenumoptional
true for items on the menu, false for items taken off it.
truefalse

Any other parameter, or one sent twice, is answered 422 invalid_request naming it. A list pages by cursor: see Pagination.

Response

200OK

In id order. A cursor holds only with the same filters.

Text in this answer can be typed in another system the restaurant uses (Toast) and synced in.

currencystringISO 4217
The restaurant's currency: every amount in this answer is in its minor units.
minor_digitsinteger0–3
Digits after the point when an amount is shown: 2 for USD (cents), 0 for JPY.
dataarray of object
This page's rows, in the list's order.
data[].idstringid
The item's id.
data[].category_idstringid
Its category.
data[].namestring
Its name: typed here, or synced from Toast for a linked item.
data[].descriptionstringnullable
Its menu description, when it has one.
data[].codestringnullable
Its short code for keyed entry on the POS ("B12"), when it has one.
data[].priceintegerminor units
Its price.
data[].is_availableboolean
False while it is sold out (86ed); it stays on the menu.
data[].is_activeboolean
Whether it is on the menu at all.
data[].food_typestringnullable
A tag shown on the POS tile (VEG, VEGAN), when it has one.
data[].stationstringnullable
The kitchen station its tickets go to ("Grill"); null for the main kitchen.
data[].prep_minutesintegernullable
How long it takes to prepare, in minutes, when set.
data[].addon_groupsarray of object
The add-on groups it offers.
data[].addon_groups[].groupobject
An add-on group the item offers.
data[].addon_groups[].group.idstringid
The group's id.
data[].addon_groups[].group.namestring
Its name ("Extras").
data[].addon_groups[].group.min_selectinteger
How many add-ons must be chosen from it; 0 when it is optional.
data[].addon_groups[].group.max_selectinteger
How many may be chosen; 0 for as many as the guest likes.
data[].addon_groups[].group.addonsarray of object
Its add-ons that are on sale.
data[].addon_groups[].group.addons[].idstringid
The add-on's id: send it in addon_ids.
data[].addon_groups[].group.addons[].namestring
Its name.
data[].addon_groups[].group.addons[].priceintegerminor units
What it adds to the line, per unit.
has_moreboolean
Whether another page follows.
next_cursorstringidnullable
The cursor for the next page: send it as cursor. Null on the last page.

An answer may gain fields within v1: ignore the ones you do not know. Versioning

Response headers

request-idalways
This request’s id. Quote it when asking for help.
Cache-Controlalways
no-store: an answer is never cached.
RateLimit-Limit, RateLimit-Remaining, RateLimit-Resetonce the key is known
The key’s units a minute, what is left of this minute’s, and the seconds until the window starts again. Never on a 401. Rate limits
x-error-codeon an error
The error’s code, the same as error.code in the body.
Retry-Afteron a 429
Seconds to wait before sending the same request again.
WWW-Authenticateon a 401, and a 403 insufficient_scope
The Bearer challenge, naming what was wrong with the key or the scope it lacks.

Errors

403insufficient_scope
The key does not carry the endpoint's scope.

Fix: Scopes are fixed when a key is made: make a new key with the scope.

403issuer_access_ended
The key's creator has left the restaurant, was suspended, or was removed and invited back.

Fix: Make a new key from an active account.

403issuer_permission_changed
The key's creator no longer holds any permission that could put this scope on a key.

Fix: Ask an owner to restore the permission, or make a new key from an account that holds it.

403permission_required
The key's permissions for this endpoint (its creator's, cut down to the endpoint's scope) do not include what this endpoint, or this argument, needs. The message names it.

Fix: Use a key with the named scope, from a creator who holds the named permission.

422invalid_request
A filter out of range: q blank or over 80 characters, or available or active other than true or false.

Fix: Fix the named fields. Nothing was done, and an Idempotency-Key is not used up.

422invalid_cursor
The cursor is not an item in this list with these filters.

Fix: Start without cursor, keeping the same filters.

Possible on every endpoint
401missing_api_keyNo Authorization: Bearer header and no x-api-key header.
401invalid_api_keyThe key is unknown, revoked or expired (answered alike).
429rate_limitedOver the key's 60 units a minute, or over 30 unknown keys a minute from one network (an address; an IPv6 caller's /64).
500internal_errorSomething failed on our side. Nothing kept the Idempotency-Key.

Every code, and when to retry

Request
curl -X GET "$TABLEBUDDY_URL/api/v1/menu/items?q=salmon&active=true" \
  -H "Authorization: Bearer $TABLEBUDDY_API_KEY"
Response200
{
  "currency": "USD",
  "minor_digits": 2,
  "data": [
    {
      "id": "cmg5x2b4f0002tb2jd8k1q7wz",
      "category_id": "cmg5x2b4f0001tb2jx0v5n3ps",
      "name": "Cedar-plank salmon",
      "description": "Maple glaze, charred lemon",
      "code": "E7",
      "price": 2600,
      "is_available": true,
      "is_active": true,
      "food_type": null,
      "station": "Grill",
      "prep_minutes": 18,
      "addon_groups": [
        {
          "group": {
            "id": "cmg5x2b4f0003tb2jm6c2r9ua",
            "name": "Sides",
            "min_select": 0,
            "max_select": 2,
            "addons": [
              {
                "id": "cmg5x2b4f0004tb2jf1s8t0yb",
                "name": "Garlic mash",
                "price": 400
              }
            ]
          }
        }
      ]
    }
  ],
  "has_more": false,
  "next_cursor": null
}