Access restaurant menu data as Schema.org-aligned JSON or JSON-LD. Filter by diet, allergens, price, and ingredients. No authentication required for public access.
Fetch a restaurant's full menu with a single GET request. No API key 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.
The API is publicly accessible without authentication. Optionally, include an API key via the X-API-Key header for usage tracking and higher rate limits.
curl https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu \
-H "X-API-Key: gmmo_your_api_key_here"Restaurant owners can create API keys from Settings → API Keys in the dashboard. Keys use the format gmmo_<32 hex chars>. The raw key is shown once on creation — store it securely.
When an X-API-Key header is present, the key must be valid. Unknown, revoked, or expired keys return a 401 Unauthorized response.
| 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.
Authenticated requests are rate-limited per API key using a 60-second sliding window. Unauthenticated (public) requests are not rate-limited.
| Tier | Requests per minute |
|---|---|
free | 60 |
basic | 300 |
premium | 1,000 |
All authenticated responses include these headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests in the current window |
X-RateLimit-Remaining | Remaining requests in the current window |
X-RateLimit-Reset | Unix timestamp when the oldest request expires |
Retry-After | Seconds until the window resets (only on 429) |
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..." } |
401 | Invalid, revoked, or expired API key | { "error": "Invalid API key" } |
404 | No active restaurant matches this slug | { "error": "Restaurant not found" } |
429 | API key rate limit exceeded | { "error": "Rate limit exceeded..." } |
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, Authorization, X-API-Key |
const response = await fetch(
"https://getmymenuonline.com/api/v1/restaurants/pizza-palace/menu",
{
headers: {
"X-API-Key": "gmmo_your_api_key_here",
},
}
);
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",
headers={"X-API-Key": "gmmo_your_api_key_here"},
)
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 get an API key. Public access is free — no key required.
Get Started Free