Toasttab APIorder.toasttab.com ↗
Fetch complete menus, categories, and every menu item with prices, descriptions, images, and stock status for any Toast-hosted restaurant.
What is the Toasttab API?
The order.toasttab.com API exposes 1 endpoint — list_menu_items — that returns the full online-ordering menu for any restaurant hosted on Toast's order page. A single call delivers all menus, groups, and a flat list of every item across all categories, each row carrying 7+ fields including price, description, and group context. No secondary requests or joins are required.
curl -X GET 'https://api.parse.bot/scraper/149c81fe-f702-41f9-9c82-a5c9c2e97777/list_menu_items?restaurant_slug=zingsters-4169-cushing-parkway' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace order-toasttab-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Toast Online Ordering Menu API — fetch a restaurant's full menu."""
from parse_apis.order_toasttab_com_api import ToastMenu, RestaurantNotFound
client = ToastMenu()
# Fetch the complete menu catalog for a restaurant by its URL slug.
try:
catalog = client.menu_catalogs.get(restaurant_slug="zingsters-4169-cushing-parkway")
except RestaurantNotFound:
print("Restaurant not found for that slug")
raise
print(f"{catalog.restaurant.name} ({catalog.total_count} items)")
# Walk menus and their category groups.
for menu in catalog.menus:
print(f"\nMenu: {menu.name}")
for group in menu.groups:
print(f" {group.name} — {group.item_count} items")
# Browse individual items: price, stock status, and image.
for item in catalog.items[:5]:
stock = "in stock" if not item.out_of_stock else "OUT OF STOCK"
print(f" {item.name}: ${item.price:.2f} ({stock})")
if item.image_url:
print(f" image: {item.image_url[:80]}…")
print("\nexercised: menu_catalogs.get")
Returns the complete online-ordering menu for one Toast restaurant in a single round trip. The result is item-grained: `items` is a flat list of every menu item across all menus and groups, each row carrying its own menu_id/menu_name and group_id/group_name so no join is needed; `menus` is the menu → group outline with per-group item counts; `total_count` is the site's own published item total and `returned_count` is how many rows were extracted (they should match; a mismatch means the site changed shape). `price` is the first entry of `prices` in USD; `description` and `image_url` are null when the restaurant has not set them; `item_tags` is an empty array when no dietary tags are set. `has_modifiers` indicates the item has optional/required modifier choices (modifier details are not returned). Items the restaurant has hidden by time-based availability are excluded, matching what a guest sees. There is no pagination. An unknown slug returns a stale_input/input_not_found error.
| Param | Type | Description |
|---|---|---|
| restaurant_slugrequired | string | The restaurant's slug from its Toast online-ordering URL, i.e. the path segment after order.toasttab.com/online/ (lowercase letters, digits, hyphens). One shape: zingsters-4169-cushing-parkway. |
{
"type": "object",
"fields": {
"items": "flat array of every menu item: item_id, name, description, price (number, USD), prices (array of numbers), default_modifiers_price, has_modifiers, out_of_stock, unit_of_measure, master_id, item_tags (array of strings), image_url (nullable), menu_id, menu_name, group_id, group_name",
"menus": "array of menus, each with menu_id, name, description, and groups[] (group_id, name, description, item_count)",
"restaurant": "object: restaurant_id (Toast restaurant GUID), name, slug (echo of the input)",
"total_count": "integer: the site's published count of items across all menus",
"returned_count": "integer: number of rows in items"
},
"sample": {
"data": {
"items": [
{
"name": "Zing-1",
"price": 13.49,
"prices": [
13.49
],
"item_id": "28afc75d-854c-40ac-a94f-688f89d97b93",
"menu_id": "bbeae570-243f-4fa4-85e3-c0c83ccf116a",
"group_id": "937219c9-3833-451b-85bd-214aa14ee2b4",
"image_url": "https://d1w7312wesee68.cloudfront.net/IKguknDF6JiRbHDY2piG01lNKFghW2e0Gyuh0WSQUoI/resize:fit:1080:1080/plain/s3://toasttab/menu_service/restaurants/6d256cc1-4597-4882-ab61-63505a34784b/MenuItem/56abcaf0-7334-4184-97c9-ad5e01715da4.png",
"item_tags": [],
"master_id": "1600000000027185810",
"menu_name": "Menu",
"group_name": "Burgers",
"description": "Chicken ZINGER, comes with Pickle, Coleslaw, Cheese and our signature and Zing sauces",
"out_of_stock": false,
"has_modifiers": true,
"unit_of_measure": "NONE",
"default_modifiers_price": 0
},
{
"name": "Seasoned Fries ",
"price": 4.99,
"prices": [
4.99
],
"item_id": "4bc54c0e-0c88-4000-b021-6e9f5de7749d",
"menu_id": "bbeae570-243f-4fa4-85e3-c0c83ccf116a",
"group_id": "976575f0-0e29-439a-b22f-c7a57e99fd7d",
"image_url": null,
"item_tags": [],
"master_id": "1600000004871239494",
"menu_name": "Menu",
"group_name": "Sides",
"description": null,
"out_of_stock": false,
"has_modifiers": false,
"unit_of_measure": "NONE",
"default_modifiers_price": 0
}
],
"menus": [
{
"name": "Menu",
"groups": [
{
"name": "Burgers",
"group_id": "937219c9-3833-451b-85bd-214aa14ee2b4",
"item_count": 18,
"description": null
},
{
"name": "Tender Only",
"group_id": "198aecc4-eaa3-4b49-b1e2-ee190c9b350e",
"item_count": 3,
"description": null
}
],
"menu_id": "bbeae570-243f-4fa4-85e3-c0c83ccf116a",
"description": null
}
],
"restaurant": {
"name": "Zingsters - Fremont",
"slug": "zingsters-4169-cushing-parkway",
"restaurant_id": "6d256cc1-4597-4882-ab61-63505a34784b"
},
"total_count": 45,
"returned_count": 45
},
"status": "success"
}
}About the Toasttab API
What the API Returns
The list_menu_items endpoint accepts one required parameter — restaurant_slug — which is the path segment from the restaurant's Toast ordering URL (e.g. zingsters-4169-cushing-parkway from order.toasttab.com/online/zingsters-4169-cushing-parkway). The response comes back in a single round trip with three top-level objects: restaurant, menus, and items.
Item-Level Data
The items array is a flat list of every menu item across all menus and categories. Each row includes item_id, name, description, price (a numeric USD value), prices (an array covering any size or variant tiers), and default_modifiers_price. Crucially, each item also carries menu_id, menu_name, group_id, and group_name, so you can filter or group items by category without traversing the menu tree separately.
Menu and Restaurant Structure
The menus array provides the structural view: each menu entry has a menu_id, name, description, and a groups array. Each group carries group_id, name, description, and item_count. The restaurant object echoes back the restaurant_id (the Toast GUID), name, and slug. The response also includes total_count (the published item count from the source) and returned_count (actual rows in items), making it straightforward to detect any discrepancy.
Coverage and Scope
The API works against any restaurant with a publicly accessible online-ordering page on order.toasttab.com. Coverage depends on what the restaurant has published on its Toast ordering page — if a menu or item is not live for online ordering, it will not appear in the response.
The Toasttab API is a managed, monitored endpoint for order.toasttab.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when order.toasttab.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official order.toasttab.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Aggregate and compare menus across multiple Toast-hosted restaurant locations using the
restaurant_slugparameter. - Build a nutrition or allergen cross-reference tool using
descriptionandnamefields from theitemsarray. - Monitor price changes over time by polling
priceandpricesfields for specificitem_idvalues. - Populate a third-party food delivery or ordering interface with live menu data including group names and item counts.
- Audit menu consistency across franchise locations by comparing
itemsarrays from different slugs. - Detect out-of-stock or removed items by comparing
total_countagainstreturned_countbetween polling intervals.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Toast have an official developer API?+
What does `list_menu_items` return for restaurants with multiple menus (e.g. lunch and dinner)?+
menus array lists each menu with its own menu_id and groups, and every item in the flat items array carries menu_id and menu_name, so you can filter items to a specific menu entirely client-side without making additional requests.Does the API return modifier options or add-on pricing for items?+
items array includes default_modifiers_price, which reflects the base price contribution of any default modifiers. Full modifier groups and their individual options (e.g. specific toppings, sizes with distinct prices) are not broken out as separate fields in the current response. You can fork this API on Parse and revise it to add a modifier-detail endpoint if that granularity is needed.