Access restaurant menu data as Schema.org-aligned JSON or JSON-LD. Filter by diet, allergens, price, and ingredients. No authentication required.
Fetch a restaurant's full menu with a single GET request. No authentication required.
curl https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menuReplace pizza-palace with the restaurant's URL slug. The response is a Schema.org-aligned JSON document containing the full menu tree.
| Method | Path | Description |
|---|---|---|
GET | /api/v1/restaurants/{slug}/menu | Fetch the full public menu tree for a restaurant |
OPTIONS | /api/v1/restaurants/{slug}/menu | CORS preflight |
| Parameter | Type | Description |
|---|---|---|
slug | string | The restaurant's URL slug (e.g. pizza-palace) |
All query parameters are optional. Combine them freely to filter and format results.
| Parameter | Type | Description | Example |
|---|---|---|---|
format | string | Output format. Omit for JSON; use jsonld for JSON-LD | ?format=jsonld |
diet | string | Comma-separated dietary requirements (AND logic) | ?diet=vegan,gluten-free |
exclude | string | Comma-separated allergens to exclude (OR logic) | ?exclude=nuts,dairy |
maxPrice | number | Maximum price — items above this are removed | ?maxPrice=15 |
ingredient | string | Comma-separated ingredient search (AND logic, substring match) | ?ingredient=truffle |
The default response is a Schema.org-aligned JSON document following the hierarchy: Restaurant → Menu → MenuSection → MenuItem. Every entity includes a @type annotation.
{
"data": {
"@type": "Restaurant",
"id": "r_abc123",
"name": "Pizza Palace",
"slug": "pizza-palace",
"url": "https://getmymenuonline.com/pizza-palace",
"description": "The best pizza in town",
"servesCuisine": "Italian",
"telephone": "+44 1234 567890",
"address": {
"@type": "PostalAddress",
"addressCountry": "GB",
"streetAddress": "123 High Street, London"
},
"hasMenu": [
{
"@type": "Menu",
"name": "Lunch Menu",
"hasMenuSection": [
{
"@type": "MenuSection",
"name": "Starters",
"hasMenuItem": [
{
"@type": "MenuItem",
"name": "Bruschetta",
"description": "Toasted bread with tomatoes",
"isAvailable": true,
"suitableForDiet": [
"https://schema.org/VegetarianDiet"
],
"allergens": ["gluten"],
"offers": {
"@type": "Offer",
"price": "6.50",
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock"
}
}
]
}
]
}
]
}
}suitableForDiet — full Schema.org RestrictedDiet URLs (e.g. https://schema.org/VeganDiet)allergens — parsed string array (e.g. ["gluten", "dairy"])offers.price — decimal string (e.g. "12.99")offers.priceCurrency — ISO 4217 code (e.g. "GBP")offers.availability — Schema.org URL: InStock or OutOfStockisAvailable — boolean convenience field for item availabilitynutrition — Schema.org NutritionInformation (e.g. "250 calories"); null when not setSuccessful responses include Cache-Control: public, s-maxage=60, stale-while-revalidate=300 for CDN caching with a 60-second max age and 5-minute stale-while-revalidate.
Add ?format=jsonld to get a proper JSON-LD document with Content-Type: application/ld+json. Designed for search engines, AI agents, and linked data consumers.
curl "https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu?format=jsonld"@context and @id added{ data } envelopeid, slug, isAvailable, allergens, modifiers, timeOfDaysuitableForDiet collapsed to a single string when only one valueingredients converted to comma-separated stringappliedFilters in the response{
"@context": "https://schema.org",
"@type": "Restaurant",
"@id": "https://getmymenuonline.com/pizza-palace#restaurant",
"name": "Pizza Palace",
"url": "https://getmymenuonline.com/pizza-palace",
"servesCuisine": "Italian",
"hasMenu": [
{
"@type": "Menu",
"name": "Lunch Menu",
"hasMenuSection": [
{
"@type": "MenuSection",
"name": "Starters",
"hasMenuItem": [
{
"@type": "MenuItem",
"name": "Bruschetta",
"description": "Toasted bread with tomatoes",
"suitableForDiet": "https://schema.org/VegetarianDiet",
"offers": {
"@type": "Offer",
"price": "6.50",
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock"
}
}
]
}
]
}
]
}Filter menu items by dietary requirements, allergens, price, and ingredients. When filters are active, items that don't match are removed. Empty sections and menus are pruned. The appliedFilters object in the response shows the normalised filter values.
curl "https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu?diet=vegan&maxPrice=15"{
"data": { "..." },
"appliedFilters": {
"diet": ["https://schema.org/VeganDiet"],
"exclude": ["nuts"],
"maxPrice": 15,
"ingredient": ["truffle"]
}
}| Short name | Schema.org URL |
|---|---|
vegan | https://schema.org/VeganDiet |
vegetarian | https://schema.org/VegetarianDiet |
gluten-free | https://schema.org/GlutenFreeDiet |
halal | https://schema.org/HalalDiet |
kosher | https://schema.org/KosherDiet |
diabetic | https://schema.org/DiabeticDiet |
low-calorie | https://schema.org/LowCalorieDiet |
low-fat | https://schema.org/LowFatDiet |
low-lactose | https://schema.org/LowLactoseDiet |
low-salt | https://schema.org/LowSaltDiet |
Non-hyphenated variants (e.g. glutenfree) and Schema.org enum names (e.g. VeganDiet) are also accepted. Unrecognised values are silently ignored.
Allergen names are free-form strings (e.g. gluten, dairy, nuts, shellfish). Matching is case-insensitive against the item's allergens array. Items containing any listed allergen are removed.
Search terms are matched as case-insensitive substrings against ingredient names. When multiple terms are provided, items must contain all terms (AND logic). Items with no ingredients are excluded when an ingredient filter is active.
Errors return a JSON body with an error field describing what went wrong.
| Status | Description | Example body |
|---|---|---|
400 | Invalid request (bad slug, filter, or format) | { "error": "Missing or invalid slug..." } |
404 | No active restaurant matches this slug | { "error": "Restaurant not found" } |
500 | Unexpected server error | { "error": "Internal server error" } |
All responses include CORS headers allowing access from any origin. You can call the API directly from browser-side JavaScript.
| Header | Value |
|---|---|
Access-Control-Allow-Origin | * |
Access-Control-Allow-Methods | GET, OPTIONS |
Access-Control-Allow-Headers | Content-Type |
const response = await fetch(
"https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu"
);
const { data } = await response.json();
// Access restaurant info
console.log(data.name); // "Pizza Palace"
console.log(data.servesCuisine); // "Italian"
// Iterate menus and items
for (const menu of data.hasMenu) {
for (const section of menu.hasMenuSection) {
for (const item of section.hasMenuItem) {
console.log(`${item.name} — ${item.offers.priceCurrency} ${item.offers.price}`);
}
}
}import requests
response = requests.get(
"https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu",
)
response.raise_for_status()
data = response.json()["data"]
# Access restaurant info
print(data["name"]) # "Pizza Palace"
print(data["servesCuisine"]) # "Italian"
# Iterate menus and items
for menu in data["hasMenu"]:
for section in menu["hasMenuSection"]:
for item in section["hasMenuItem"]:
price = item["offers"]["price"]
currency = item["offers"]["priceCurrency"]
print(f"{item['name']} — {currency} {price}")Stack multiple query parameters to narrow results:
curl "https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu?diet=vegan&exclude=nuts&maxPrice=15&ingredient=truffle"Sign up to create your restaurant and publish your menu. The public API is free — no key required.
Get Started Free