Restaurant schema is one of the highest-return types of structured data a food business can add: it feeds Google the structured hours, location, cuisine, and menu that power your presence in Maps and the local pack, it can make you eligible for Google's "best [city] restaurants" carousel, and increasingly it determines whether AI assistants can accurately recommend you when someone asks "best Italian near me." Diners are already asking ChatGPT, Gemini, and Google's AI where to eat, and structured data is how you make sure your restaurant is understood correctly rather than guessed at.
But there's one thing most restaurant-SEO guides get flatly wrong, and getting it right saves you real effort and real risk: you cannot show star ratings for reviews about your own restaurant, on your own site. That's not opinion, it's Google's explicit rule, and it catches a huge number of restaurants who spend hours marking up their own five-star reviews expecting stars that will never appear. So this guide does it accurately: the right schema type, the required and recommended fields, menu and reservation markup, multiple locations, the review-stars reality most guides botch, and how it all supports being found by diners and AI alike. Let's build it right.
What does Restaurant schema actually get you?
Restaurant structured data tells search engines that a page is about a specific eating establishment and describes its key facts (name, address, hours, cuisine, price range, menu) in a form they can display and rely on. Here's what that unlocks, in order of how reliably you'll see it.
Local visibility and the knowledge panel. This is the everyday payoff. Your structured address, geo coordinates, hours, phone, and cuisine feed Google's understanding of your business for Maps and the local pack, the three-result map block where most "restaurants near me" searches land. When Google shows a knowledge panel for your restaurant, that structured data helps populate the name, hours, and cuisine it displays.
The restaurant carousel, with an important caveat. When someone searches a type of business like "best NYC restaurants," Google can show a carousel of restaurants at the top of results. Restaurant markup is what makes a page eligible in principle. But be clear-eyed: Google states the Restaurant carousel is currently limited to a small set of restaurant providers, and you have to register interest through a form to participate. So treat the carousel as a real-but-gated bonus, not the reason you're marking up, the local and AI value below is what pays off for every restaurant.
AI recommendation and "best [cuisine] near me." This is the fastest-growing reason to get it right. When a diner asks an AI system "who does good ramen in Manchester" or "best family-friendly Italian near me," the system answering has to match a specific cuisine to specific restaurants in that place. Complete Restaurant schema, especially servesCuisine plus your location, hands the machine a clean, structured answer instead of making it infer your cuisine and area from your page's prose and hope it got it right. We'll come back to this because it's where restaurant schema is quietly becoming most valuable.
One honest framing up front, consistent with Google's own position: no schema guarantees a carousel slot, a rich result, or an AI recommendation. What good markup does is make your restaurant legible, unambiguous, and accurately represented to the systems diners use. That's the real goal, and it's genuinely worth pursuing.
Which schema type should a restaurant use?
Getting the type right is the foundation, and the rule is the same one that governs schema generally: use the most specific accurate type. Restaurant is a subtype of FoodEstablishment, which is a subtype of LocalBusiness, which is a subtype of Organization. The more precise you are, the more precisely a machine understands what kind of thing you are.
For most sit-down eateries, Restaurant is exactly right. But schema.org offers more specific food-establishment subtypes, and if one genuinely describes you, use it:
CafeOrCoffeeShop, cafés and coffee shopsBarOrPub, bars and pubsBakery, bakeriesFastFoodRestaurant, quick-serviceIceCreamShop, ice cream and gelatoBrewery,Winery,Distillery, for producers with a tasting-room or venue sideNightClub, clubs
A neighbourhood espresso bar marked as CafeOrCoffeeShop sends a clearer signal than a generic Restaurant, which in turn is clearer than a bare LocalBusiness. Pick the one that's true.
Because LocalBusiness is a subtype of Organization, Google recommends you also follow the Organization fields, your logo, sameAs links, and broader identity, in addition to the restaurant-specific ones. That connection between your restaurant and your broader brand identity is where the entity value lives, and we'll tie it together later.
What are the required and recommended fields?
Here's the part worth internalizing, because it's the difference between "technically eligible" and "actually competitive."
Google's Local Business rich result has just two required properties:
name, the restaurant's nameaddress, the physical location, as aPostalAddress
That's the eligibility floor. But a page carrying only name and address gives Google and AI systems almost nothing to work with. The recommended properties are where the real value is, and for restaurants they're effectively part of the job:
geo, latitude and longitude, to at least 5 decimal places (Google is specific about this)openingHoursSpecification, your hours, including seasonal and late-night variationstelephone, primary contact number with country and area codeurl, the fully-qualified URL of this specific locationservesCuisine, the cuisine you serve (the field that makes you matchable to "best [cuisine] near me")priceRange, a range like "$10-15" or a normalized "$$$" (keep it under 100 characters or Google won't show it)menu, the fully-qualified URL of your menuimage, high-resolution photos (16x9, 4x3, and 1x1 aspect ratios recommended)department, for a distinct in-house bar or bakery with its own hours
Two recommended properties come with a critical condition that most guides miss entirely: aggregateRating and review are only recommended for sites that capture reviews about other local businesses, a directory or review platform, not the restaurant itself. If you're a restaurant marking up reviews about your own restaurant, these won't earn you stars and can flag your site. This is the self-serving rule, and it's important enough that it gets its own section below.
A complete Restaurant example
Here's a full, well-formed Restaurant block for a single location, using the recommended fields, and deliberately without self-serving review markup:
{
"@context": "https://schema.org",
"@type": "Restaurant",
"@id": "https://brightbistro.example/#restaurant",
"name": "Bright Bistro",
"image": [
"https://brightbistro.example/photos/1x1/dining.jpg",
"https://brightbistro.example/photos/4x3/dining.jpg",
"https://brightbistro.example/photos/16x9/dining.jpg"
],
"url": "https://brightbistro.example/",
"telephone": "+1-512-555-0148",
"servesCuisine": "Italian",
"priceRange": "$$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "40 Bridge Street",
"addressLocality": "Austin",
"addressRegion": "TX",
"postalCode": "78704",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 30.25012,
"longitude": -97.75023
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Tuesday", "Wednesday", "Thursday"],
"opens": "17:00",
"closes": "22:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Friday", "Saturday"],
"opens": "17:00",
"closes": "23:30"
}
],
"menu": "https://brightbistro.example/menu",
"acceptsReservations": "True",
"sameAs": [
"https://www.instagram.com/brightbistro",
"https://www.facebook.com/brightbistro"
]
}A few things to notice. The geo coordinates carry five decimal places, as Google requires. servesCuisine is populated, that single field is doing outsized work for AI matching. The hours are split into two OpeningHoursSpecification blocks because weekday and weekend closing times differ. And there's no aggregateRating or review block, because a restaurant marking up its own reviews won't earn stars anyway. Get this structure right once and every variation below is a small adjustment to it.
Why is servesCuisine the field that matters most for AI?
Here's the concrete use case that makes restaurant schema increasingly valuable, and it's worth understanding clearly because it should shape how you fill things in.
When a diner asks an AI system "best Thai food in Leeds" or "where can I get vegan brunch near me," the system has to match a cuisine and a place to specific restaurants that fit. Your servesCuisine value combined with your address and geo is precisely how you make that match explicit. A Restaurant block that declares servesCuisine: "Thai" and an address in Leeds tells the machine, in structured terms it can rely on, this restaurant serves this cuisine in this place.
Without it, the AI has to infer your cuisine from your page copy, reading your prose, guessing at your style, and hoping it's accurate. Sometimes it gets it right; often it's unreliable or incomplete, especially for restaurants whose menus span styles or whose homepage leans on mood rather than plain description. Structured servesCuisine removes the guesswork.
A refinement worth doing: be specific and accurate rather than vague. "Neapolitan pizza" or "Sichuan" is a stronger, more matchable signal than a generic "Italian" or "Chinese" if it's genuinely what you serve. You want to be the confident answer to the specific question a diner actually asks, and the more precisely your cuisine is described in structured form, the more confidently a system can surface you. This is the same entity-clarity principle that underpins getting cited by AI systems generally: the clearer and more structured your information, the more accurately AI can understand and surface it.
How do I mark up my menu?
Your menu is one of the most valuable things to structure, and you have two levels of depth.
At minimum, use the menu property pointing to the URL of your menu page:
"menu": "https://brightbistro.example/menu"
One practical note that trips people up: point menu at an HTML menu page, not only a PDF. Crawlers and AI systems read HTML far more reliably than they parse a PDF, so if your menu lives only as a downloadable PDF, add an HTML version, it's better for diners on mobile anyway.
For richer structure, you can model the menu itself with hasMenu → Menu → MenuSection → MenuItem, which gives machines an explicit inventory of your dishes rather than a link to figure out:
"hasMenu": {
"@type": "Menu",
"hasMenuSection": [
{
"@type": "MenuSection",
"name": "Pasta",
"hasMenuItem": [
{
"@type": "MenuItem",
"name": "Cacio e Pepe",
"description": "Pecorino, black pepper, house tonnarelli.",
"offers": {
"@type": "Offer",
"price": "16.00",
"priceCurrency": "USD"
}
}
]
}
]
}This is genuinely useful when you want dish names, dietary tags, and prices to be machine-readable, the kind of detail that helps an AI answer "does anywhere near me do cacio e pepe under $20." It's more work to maintain by hand, though, which is exactly the maintenance problem we'll address in the WordPress section. For many restaurants the menu URL is enough to start; add structured menu items where the detail earns its keep.
Can I add reservations and online ordering to my schema?
You can describe these capabilities in your markup, and it's worth being precise about what that does and doesn't do.
acceptsReservations is a simple boolean-style property ("True") that tells machines you take bookings. It's a useful, honest signal.
You can also describe reservation and ordering actions with potentialAction using ReserveAction or OrderAction, pointing at your first-party booking or ordering page. Where you have a first-party ordering flow, pointing there keeps the valuable click on your own property rather than routing it to a third-party marketplace.
Here's the honest part most guides skip: the interactive "Reserve a table" and "Order online" buttons you see directly inside Google Search results aren't produced by plain schema alone. Those come through Google's Maps Booking API partner program, which is an integration with approved reservation and ordering providers, not something you switch on by adding a property to your JSON-LD. So mark up acceptsReservations and your action URLs because they're accurate, useful entity signals; just don't expect the in-SERP booking button to appear purely from schema. Setting the right expectation here saves you the frustration of hunting for a result that markup alone can't produce.
How do I handle multiple locations?
If you run more than one location, the rule is clear and important: each location gets its own page and its own Restaurant entity, with its own complete details. Don't stack two addresses and two phone numbers into one Restaurant block, that mixed signal confuses everyone.
Give each location a dedicated page (a proper location page, not just a pin on a shared map), and put a complete Restaurant block on each, describing that venue only: its own address, geo, hours, phone, and URL. If your locations differ in cuisine or price, reflect that per location. This is the same per-entity discipline that governs any multi-location local business, the patterns in our multi-location local business guide apply directly to restaurant groups.
If you want your set of locations eligible for the host carousel, that's where the Carousel object and the limited-access restaurant carousel program come in, but the foundation is always one clean, complete, accurate Restaurant entity per location.
The review-stars reality most guides get wrong
This is the single most important accuracy point in this guide, and it's the one that separates advice you can trust from advice that can cost you.
A restaurant cannot show star ratings for reviews about itself, on its own website. Google's self-serving review rule is explicit: if the entity being reviewed controls the reviews about itself, its pages using LocalBusiness or any Organization structured data, and Restaurant is a subtype of both, are ineligible for the star review feature. This has been Google's position since 2019 and it's restated plainly in the current review-snippet documentation.
Crucially, this includes reviews collected yourself and reviews pulled in through an embedded third-party widget (a Google reviews or Facebook reviews widget) placed on your own page. Google considers embedding a third-party widget as controlling the process, it's still self-serving. So the "obvious" tactic, add aggregateRating to your Restaurant schema so your homepage shows a shiny 4.8 with 300 reviews, is exactly the thing that doesn't work, and attempting it with mismatched or third-party-scraped data can flag your site.
Where do the star ratings you do see for restaurants come from, then? Independent third-party platforms, Google's own reviews, Yelp, TripAdvisor, and the like. Because those platforms are an independent party collecting reviews rather than the restaurant reviewing itself, their markup is eligible. That's not self-serving, so it can show stars.
So the legitimate strategy for a restaurant isn't to mark up your own reviews, it's to build a genuine, strong presence on the review platforms that matter, keep your Google Business Profile healthy, and let their eligible markup do the star-rating work. That's good for your business regardless of schema: real reviews on trusted platforms build reputation and increasingly feed the AI systems that recommend restaurants. Our full guide to earning star ratings covers the complete rules, including the eligible content types and the July 2026 tightening on incentivized reviews. The restaurant takeaway: don't waste effort self-marking-up your reviews, and be skeptical of any guide that tells you to.
One honest nuance: leaving your own testimonials on your site, unmarked or marked up correctly per guidelines, won't earn a manual action, Google simply won't display stars for them. On-page review sentiment can still help AI systems understand your reputation; it just won't produce the Google star snippet.
Restaurant events and specials
Restaurants often host events, tasting menus, live music nights, cooking classes, seasonal pop-ups, and those deserve their own markup rather than being crammed into your restaurant schema. Event schema is a separate entity type with its own required fields (name, start date with timezone, location) and its own payoff: eligibility for Google's event experience and clean machine-readability for the "what's on this weekend" queries people increasingly ask AI.
The pattern is: your Restaurant entity describes the venue; each event gets its own Event block on its own page, with the restaurant as the location or organizer. If you run a regular events calendar, our Event schema guide covers the in-person, recurring, and ticketed cases in depth, including the important rule that each occurrence of a recurring event needs its own dated block.
What are the common mistakes to avoid?
The errors that most often cost restaurants their results or muddle their signals:
Marking up your own reviews for star ratings. The classic, costly mistake. Restaurant is a LocalBusiness/Organization subtype, so self-reviews are ineligible for stars, including via embedded widgets. Earn reviews on independent platforms instead.
Two addresses in one Restaurant entity. Each location needs its own page and its own complete entity. Mixing venues confuses Google and AI.
Menu only as a PDF. Add an HTML menu page so crawlers and AI can actually read your dishes; point menu at that.
Vague or missing servesCuisine. This is the field that makes you matchable to cuisine queries. Leaving it out or keeping it generic wastes your strongest AI signal.
Imprecise geo coordinates. Google wants at least five decimal places. Rounded coordinates weaken your location precision.
Expecting in-SERP reservation buttons from plain schema. Those come via the Maps Booking API partner program, not a JSON-LD property. Mark up acceptsReservations honestly; don't expect the button from markup alone.
Markup that doesn't match the page. Your schema must reflect what's genuinely true and visible, real hours, real cuisine, real prices. Mismatches undermine trust in all your signals.
Set-and-forget schema. Hours change seasonally, menus change constantly, prices move, a location closes. Static markup drifts out of truth fast, which is the biggest ongoing problem for restaurants specifically.
How do I implement Restaurant schema on WordPress?
Most restaurants run WordPress, and the right approach depends on how many locations you have and, more than anything, how often your details change. Because that last point is where restaurant schema quietly breaks.
Check what your theme or SEO plugin outputs first. Many restaurant themes and general SEO plugins emit only generic LocalBusiness markup, missing the specific Restaurant (or CafeOrCoffeeShop) subtype, servesCuisine, structured hours, and menu, the fields that actually carry the value. View source on a location page and see what's really there.
The real challenge is accuracy over time. A restaurant's structured data is unusually perishable: seasonal hours, holiday closures, a changing menu, updated prices, a new location, a rebranded cuisine focus. Hand-maintained JSON-LD is exactly where this falls apart, someone updates the menu page or the holiday hours but forgets the schema, and the two silently drift apart. Inaccurate markup (wrong hours showing a diner you're open when you're closed) is worse than no markup at all.
This is where generating schema from your live content earns its keep. AI Schema Gen reads your restaurant pages and generates the right specific schema, Restaurant or the accurate food-establishment subtype, with servesCuisine, structured hours, menu, and price range, and because it generates from your actual content, your hours, menu, and details stay in sync as they change rather than requiring you to hand-edit a separate block every time something moves. It also keeps you clear of the traps that matter here, like generating markup that matches your visible content instead of self-serving review claims that won't earn stars anyway. For a multi-location group where every venue needs its own accurate, connected entity, that automatic alignment across the whole site is the difference between structured data that stays true and structured data that slowly lies. Whatever route you take, the tests are the same: the specific accurate type; servesCuisine and complete local details; one clean entity per location; and accuracy as your restaurant changes.
How do I validate my Restaurant schema?
Before and after publishing, run these checks:
Google's Rich Results Test confirms whether your page is eligible for the local business rich result and flags errors. Test a location page and confirm your required fields (name, address) and key recommended fields are present and parsing correctly.
The Schema Markup Validator at validator.schema.org checks general schema.org validity, useful for the menu, department, and action properties that don't all map to a specific Google rich result.
Cross-check consistency. Confirm your schema's name, address, phone, hours, and cuisine match your Google Business Profile and your on-page content exactly. For local search, your schema, your Business Profile, and your visible page all need to tell the same story, inconsistency undermines all three.
Search your own terms. Look up your restaurant name and "[your cuisine] near me" to see how you appear in local results, and ask an AI assistant about restaurants serving your cuisine in your area to see whether you're surfaced and accurately described. That functional test, are you actually being found and described correctly, is what the markup is really working toward.
Frequently Asked Questions
Running a restaurant on WordPress? AI Schema Gen generates the right specific schema from your content, Restaurant or your accurate food-establishment subtype, with cuisine, hours, menu, and price range, connected into your brand's entity profile and kept accurate as your details change, across 827+ schema types. Start free at aischemagen.com.
Generate perfect schema in 30 seconds
AI Schema Gen handles everything automatically, free to start.
Get Started Free