LocalBusiness Schema for AI Search: A Step-by-Step Implementation Guide
LocalBusiness schema is JSON-LD structured data, schema.org vocabulary embedded in a page, that states a physical business's name, address, phone number, hours, and category in machine-readable form instead of leaving an AI engine to infer those facts from a header, a footer, or a paragraph of prose. For a location page, three types do the work: LocalBusiness (or a more specific vertical subtype), Review/AggregateRating for reputation, and FAQPage for the location-specific questions a real local buyer asks. Done right, it removes ambiguity a model would otherwise have to resolve on its own. Done wrong, in the three ways covered below, it actively works against you.
This guide assumes you've read our general schema markup for AI search engines playbook, covering FAQPage, HowTo, and Organization site-wide. Everything here is the local-specific layer: the schema type describing a physical, visitable place, and the mistakes that only surface once a business has an address and, often, more than one location.
Which Schema Type: LocalBusiness or a Vertical Subtype
LocalBusiness is the base schema.org type, but it has dozens of more specific subtypes: Restaurant, MedicalClinic, ProfessionalService, Dentist, Plumber, HairSalon, Attorney, and more. Use the subtype that genuinely describes what the business does, not the closest-sounding label, since it's a second, machine-readable confirmation of category alongside whatever text appears on the page and in your Google Business Profile.
Only use a subtype that's literally true. A catering-only kitchen with no dine-in seating isn't a Restaurant, even if food service is the closest available type; FoodEstablishment or plain LocalBusiness with an accurate description is the honest choice. A mismatched subtype adds a wrong fact for something to eventually cross-reference against the visible page, not helpful specificity.
Step 1: Build the Core LocalBusiness Block
Start with name (exactly as it appears on the page and your Google Business Profile), address as a nested PostalAddress object (streetAddress, addressLocality, addressRegion, postalCode, addressCountry), telephone, and url. Add geo as a GeoCoordinates object so a model has an unambiguous location beyond a text address. Add openingHoursSpecification as an array, one entry per day (or group of days) with dayOfWeek, opens, and closes. Add sameAs pointing to your live Google Business Profile URL and any other verified profile, a corroborating source instead of the schema's word alone.
Give every location its own @id, a stable identifier for that node. Without it, a system reconciling multiple location pages has no reliable way to tell them apart, the exact failure mode below.
Step 2: Add Review and AggregateRating Schema Correctly
AggregateRating, nested inside the LocalBusiness block, states a ratingValue and a reviewCount (or ratingCount). Individual Review objects, each with an author, a reviewRating, and a reviewBody, can sit alongside it. The rule governing both: the numbers have to match a real, visible, verifiable set of reviews on that exact page, not an aggregate pulled from a different page, location, or platform you don't control.
If reviews genuinely live on Google or Yelp rather than your own site, don't reconstruct your own AggregateRating from a partial or stale pull. Either embed the live count and average exactly as the source platform shows, or leave AggregateRating off that page. A rating that reads 4.9 from 214 reviews when the page shows 40 is worse than none at all, the same "inconsistency reads as manipulation" problem that governs FAQPage and HowTo, applied to reputation data instead of content.
Step 3: Add FAQPage Schema for the Location Itself
A location page's FAQPage schema should answer questions specific to that location, not a copy of your company-wide FAQ. "Is there parking on-site at the downtown location," "does this location accept walk-ins," "which insurance plans does this office take," these are the shape of question a local buyer actually types, and they only make sense answered per location. Give this block its own @id, distinct from any site-wide FAQPage schema on your homepage, so the two never collide.
Three Mistakes Specific to Local Business Schema
Multi-location duplication. The single most common failure: one location's full schema block gets copy-pasted across every other location page, with only the visible city name edited in the prose. The address, telephone, geo, and sameAs fields inside the JSON-LD still describe the original location. A model, or any system reconciling the two, sees ten pages claiming to be ten places while the structured data insists they're all one. Fix: every location page gets its own block, built from that location's real data, with its own @id.
Mismatched NAP between schema and Google Business Profile. Name, address, and phone (NAP) drift is usually small and unintentional: "Joe's Plumbing LLC" in the schema versus "Joe's Plumbing" on the profile, a toll-free number in one place and the direct local line in the other, "Ave" abbreviated in one record and spelled out in the other. Individually trivial, but an identity check across the two records can't confirm they describe the same business when the strings don't match. Copy the exact string from the live Google Business Profile into the schema, don't retype it from memory or an old template.
Stale openingHours. An openingHoursSpecification block set once at launch and never revisited is the most common decay: holiday closures never reflected via specialOpeningHoursSpecification, seasonal hours left unchanged, or a permanently closed location still asserting regular hours months later. A confidently wrong hours citation is worse than no hours markup at all, a customer who shows up to a closed door because a model cited stale schema is a specific, attributable failure, not an absent signal. Whoever updates the physical hours or the profile should update the schema the same day, ideally from one source rather than three copies.
How to Validate What You've Built
Run the page through Google's Rich Results Test or the Schema Markup Validator to confirm the JSON-LD parses and the types and properties are used correctly. That confirms syntax, not accuracy. What actually matters is a three-way comparison, per location: does the schema match the visible page, and does the visible page match the live Google Business Profile, for name, address, phone, and hours. A validator pass with a mismatched NAP still fails the thing that matters.
None of this guarantees a citation on any AI engine. What it reliably does is remove structural ambiguity, wrong classification, unverifiable ratings, stale hours, duplicated identities, that gives a model a reason to skip a location in favor of a competitor whose structured data and visible page actually agree.
Related Reading
For the site-wide schema types this playbook extends, FAQPage, HowTo, and Organization, see schema markup for AI search engines. For the other Google Business Profile fields that feed AI-generated local answers directly, see what a Google Business Profile should say to get cited by AI. For the full five-step sequence this schema work fits into, see how a local business gets recommended by ChatGPT.
Want to see where your own location pages currently stand before editing JSON-LD, and how you compare against the specific competitors you're losing local citations to? Our one-time Compete report ($249) and Deep Research report ($499) check the technical and structural basics and go deeper, both single-purchase reports, not a subscription.
Frequently asked questions
Do I need LocalBusiness schema if I already have a Google Business Profile?
Yes, the two serve different purposes. Your Google Business Profile is a Google-controlled data layer that Google's own AI Overviews and Maps draw from directly. LocalBusiness schema on your website is a separate, machine-readable version of the same facts, name, address, phone, hours, that any AI engine crawling and indexing your site, not just Google's, can read without inferring it from prose. A business with a strong profile and no site schema is invisible to engines that never touch a live GBP connection.
Which schema type should I use, LocalBusiness or a subtype like Restaurant?
Use the most specific subtype that genuinely matches your business, Restaurant, MedicalClinic, ProfessionalService, Dentist, Plumber, and so on, because it gives an AI engine an extra layer of unambiguous categorization beyond a text description. Fall back to the generic LocalBusiness type only when no subtype fits. Forcing a mismatched subtype onto a business that doesn't fit it, marking a catering-only kitchen up as Restaurant, reads as wrong classification, not helpful specificity.
Should I add AggregateRating schema even if I only have a handful of reviews?
Only if the ratingValue and reviewCount in the markup match a real, visible set of reviews on that exact page. Four reviews marked up as four is fine. The count and average always have to be verifiable against what a visitor, or an auditor, can actually see on the page. Fabricated or inflated review counts violate schema.org and Google's own guidelines, and read as a credibility risk rather than a shortcut.
What's the most common LocalBusiness schema mistake for a business with multiple locations?
Duplicating one location's entire schema block across every location page and only editing the visible city name, while the address, phone number, geo-coordinates, or linked Google Business Profile inside the JSON-LD still describe the original location. Each location page needs its own accurate block with a distinct @id, matching that specific location's own live profile, not a copy-pasted template.