September 20, 2026

Fix These 5 LocalBusiness Schema Fields Proven in Agency Audits

See the five LocalBusiness schema fields agencies test, why exact Google Business Profile matching matters, and how to deploy validated JSON-LD that earns...

Fix These 5 LocalBusiness Schema Fields Proven in Agency Audits

LocalBusiness schema audit workspace

The floor for LocalBusiness schema is five properties: the most specific @type you can find, name, a PostalAddress, telephone, and url. Add geo coordinates and openingHoursSpecification for real rich-result impact. The one rule that overrides everything else: every value must match your Google Business Profile character for character, or none of it counts.


TL;DR:

  • Using the most specific LocalBusiness subtype enhances eligibility for category-specific rich results and should match your Google Business Profile exactly.
  • The core properties include name, address, phone, and URL, with geocoordinates at five to six decimal places verified against your GBP pin for accuracy.
  • For multi-location businesses, link each LocalBusiness node to a sitewide Organization using a stable @id and avoid copying schema blindly across pages to prevent data drift.
  • Deployment requires placing JSON-LD in the <head> or just before </body>, avoiding duplicate nodes on a page, and validating with Google’s tools and manual checks before monitoring Search Console results.
  • Maintaining exact NAP and hours data aligned with your GBP is critical for trust signals, while schema errors often stem from mismatched data, wrong types, or poor geo precision.

Radkaadvertising
Strengthen Your Local Search Presence
Radka Advertising helps brands with strategic positioning, digital marketing, and data-driven campaigns designed for competitive digital markets.
Explore Radka Advertising

Table of Contents

Step-by-step: building and deploying LocalBusiness JSON-LD

Getting schema markup for local business live and working correctly comes down to five stages: choosing the right type, assembling the properties, writing the code, deploying it cleanly, and validating it before you walk away. Skip a stage and you end up with markup that looks fine in the source code but never earns a rich result.

1. Pick the deepest LocalBusiness subtype for your trade.

Schema.org lists over 50 subtypes under the LocalBusiness umbrella, and Google’s own guidance is explicit: use the most specific one available rather than the generic parent type. A dental practice should mark itself up as Dentist, not LocalBusiness. A bistro should use Restaurant, not FoodEstablishment. Browse the full hierarchy on Schema.org before you write a single line, because subtype specificity changes which rich-result features you’re even eligible for. A generic LocalBusiness node can technically validate and still miss out on category-specific display options that a Restaurant or Dentist node unlocks automatically.

2. Assemble the floor and recommended properties.

A working single-location block looks like this:

{
  "@context": "https://schema.org",
  "@type": "Dentist",
  "@id": "https://example.com/#business",
  "name": "Example Dental Practice",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "14 High Street",
    "addressLocality": "Manchester",
    "postalCode": "M1 2AB",
    "addressCountry": "GB"
  },
  "telephone": "+44 161 555 0123",
  "url": "https://example.com/",
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 53.48095,
    "longitude": -2.23743
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "09:00",
      "closes": "17:30"
    }
  ],
  "sameAs": [
    "https://www.facebook.com/exampledental",
    "https://www.instagram.com/exampledental"
  ]
}

Every value here needs a source, and that source is your Google Business Profile, not your invoicing system or your website copy from three years ago. Latitude and longitude should run to at least five decimal places, taken from the verified GBP pin, not a rough guess from Google Maps’ address search.

3. Use @id to link locations to a sitewide Organization.

If you run more than one site or one location, give your Organization node a stable @id (typically your homepage URL with a #organization fragment) and reference it from each location’s LocalBusiness node using parentOrganization. This tells search engines the locations belong to one brand without duplicating brand-level data on every page.

4. Deploy it without breaking it.

  • Place the <script type="application/ld+json"> tag in the <head> or immediately before the closing </body> tag, whichever your CMS handles more reliably.
  • Confirm your CMS or caching layer doesn’t strip or minify the JSON in a way that breaks valid syntax.
  • Check you haven’t got two LocalBusiness nodes firing on the same page, one from a plugin and one hand-coded. Duplicate nodes are one of the most common self-inflicted errors on WordPress and Shopify builds.

5. Validate before you consider it done.

Run the page through a developer preview first, then Google’s Rich Results Test to check eligibility, then the Schema Markup Validator to inspect the full graph and confirm your @id references resolve correctly. Finally, monitor Search Console over the following fortnight to see whether the enhancement actually appears, rather than just validates.

Pro Tip: Geocode from the exact pin you verified in Google Business Profile, not from a fresh address lookup. The two can differ by several metres, and that tiny mismatch is enough to muddy geo-based relevance signals over time.

JSON-LD examples for different business types

Copy-pasting a single template across every business type is exactly how mismatches creep in. Each business model needs different fields treated as required, and each has one or two fields that trip people up more than the rest.

Single-location retail. A shop uses the same skeleton as the dental example above, but with a retail subtype such as Store or a more specific child type like ClothingStore if one fits. PostalAddress is mandatory here because a physical shop has a fixed, findable location customers walk into.

Restaurant. Restaurants get extra mileage from properties that don’t apply to most other business types:

{
  "@context": "https://schema.org",
  "@type": "Restaurant",
  "@id": "https://example-bistro.com/#business",
  "name": "Example Bistro",
  "servesCuisine": ["Italian", "Mediterranean"],
  "menu": "https://example-bistro.com/menu",
  "image": [
    "https://example-bistro.com/images/exterior-1x1.jpg",
    "https://example-bistro.com/images/dish-4x3.jpg"
  ],
  "priceRange": "££"
}

Use an image array with multiple aspect ratios, and make sure the images are actually crawlable, not lazy-loaded behind JavaScript that blocks the crawler. menu can be a URL or a full Menu object; a URL is faster to implement and usually sufficient.

Service-area business. A plumber, mobile groomer, or electrician who travels to customers rather than trading from a shopfront should generally omit streetAddress if the business doesn’t accept walk-ins, and use areaServed instead:

{
  "@context": "https://schema.org",
  "@type": "Plumber",
  "name": "Example Plumbing Services",
  "telephone": "+44 20 7946 0958",
  "url": "https://example-plumbing.co.uk/",
  "areaServed": [
    { "@type": "City", "name": "Croydon" },
    { "@type": "City", "name": "Bromley" }
  ]
}

Inventing a street address for a service-area business just to satisfy a validator is a bad habit picked up from copy-paste templates, and it directly contradicts what Google Business Profile shows for that same listing. Named place nodes or a GeoCircle radius are the safer pattern when the service area is broad rather than a fixed list of towns.

Multi-location chain. Each location gets its own LocalBusiness node on its own canonical URL, linked back to a sitewide Organization:

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://example-chain.com/#organization",
  "name": "Example Chain",
  "url": "https://example-chain.com/",
  "sameAs": ["https://www.linkedin.com/company/example-chain"]
}

Each store page then carries its own LocalBusiness block with "parentOrganization": { "@id": "https://example-chain.com/#organization" }.

Business type Required fields beyond the floor Field developers most often get wrong
Single-location retail PostalAddress, priceRange Missing postal code or wrong addressCountry code
Restaurant servesCuisine, menu, image Low-crawlability lazy-loaded images
Service-area areaServed (City or GeoCircle) Inventing a fake streetAddress
Multi-location parentOrganization, @id linking Duplicated brand data on every page

Before publishing any of these, check the minimum edits: swap in the real GBP-verified address and phone number, confirm the @id URLs are the live canonical page, and delete any placeholder image paths left over from the template.

Rules that protect your rich-result eligibility

Google’s structured data policies are less about syntax and more about honesty. The general guidelines state plainly that markup must only describe content actually visible on the page. Mark up a review that doesn’t appear anywhere in the visible text, or an FAQ that’s hidden or fabricated, and you risk losing rich-result eligibility entirely, not just for that one item.

NAP matching is not a suggestion. Your name, address, and phone number in JSON-LD must match your Google Business Profile exactly, down to abbreviations. “St” versus “Street,” a missing suite number, or a phone number with a different area code formatting are all the kind of small drift that erodes trust signals over time, even though each one looks trivial in isolation.

Opening hours formatting catches people out constantly:

  • Use hh:mm:ss or hh:mm format for opens and closes, and use 23:59 to represent end-of-day rather than 00:00, which reads as midnight at the start of the day and creates ambiguity.
  • Split shifts (open for lunch, closed mid-afternoon, open again for dinner) need two separate OpeningHoursSpecification blocks, not one block with a confusing time range.
  • Use specialOpeningHoursSpecification with validFrom and validThrough dates for Christmas, Bank Holidays, or seasonal closures, rather than manually editing your standard hours and forgetting to revert them.

Reviews and ratings need a light touch. AggregateRating and Review types are legitimate schema properties, but Google treats self-generated, site-controlled reviews with scepticism, and rightly so, since a business marking up its own five-star reviews without any independent verification is an obvious integrity gap. If you’re going to use these types at all, source them from a genuine review platform and make sure the count and average shown in the markup match what’s visible on the page exactly.

Google’s own threading on this topic confirms that everything in structured data needs a visible counterpart on the page. There’s no exception for “it’s true, just not shown.”

Fixing the schema errors that actually cost you rich results

Two tools do two different jobs, and using the wrong one wastes time. The Rich Results Test tells you whether a page is eligible for specific rich-result features. The Schema Markup Validator shows you the full structured-data graph, including node references and @id links, which matters enormously once you’re running multi-location or Organization-linked schema.

Work through errors in this order:

  1. Extract the JSON-LD from the live page (view source, not your CMS editor, since what renders can differ from what you typed).
  2. Run the Schema Markup Validator first to catch structural errors: broken references, missing closing brackets, wrong nesting.
  3. Run the Rich Results Test to check eligibility for the specific feature you’re targeting.
  4. Reconcile every value against the visible page and your Google Business Profile. This step catches the errors the validators can’t see, because a mismatched address validates perfectly as valid JSON-LD.
  5. Correct, redeploy, and re-test rather than assuming a fix worked.
  6. Monitor Search Console’s Enhancement reports over the following weeks for new warnings.

The errors that recur most often:

  • Wrong @type: using generic LocalBusiness when a specific subtype like Dentist or Restaurant exists and fits better.
  • Missing required properties: no telephone, or an address object missing postalCode.
  • Insufficient geo precision: coordinates rounded to two or three decimal places instead of five or six.
  • Mismatched counts: an AggregateRating claiming 340 reviews when the visible page shows 210.
  • FAQ or review markup with no visible counterpart: the single fastest route to a manual action.

Pro Tip: A page can pass both validators cleanly and still get flagged. Syntax validity and content-truthfulness are separate checks, and only one of them is automated. Always do the manual visible-content comparison as a final step, not an optional one.

If you receive a structured-data manual action in Search Console, the fix is straightforward but unforgiving: correct every flagged mismatch across the site, not just the one example Google shows you, then file a reconsideration request explaining what changed. Resubmitting without a genuine fix rarely works and burns a review cycle you’ll want back later.

Scaling schema across multiple locations without it falling apart

The pattern that holds up at scale is simple to state and easy to get wrong in practice: one Organization node sitewide, one LocalBusiness node per visible location page, linked through parentOrganization and a stable @id. Practitioners who audit multi-location sites regularly find that deviating from this, usually by copying one location’s schema block across twenty pages and swapping a few strings, is the single biggest cause of contradictory data reaching search engines.

Organization node linked to location nodes

The safest defence against copy-paste drift is generating schema programmatically from the same content source that renders the visible page, rather than maintaining a separate schema template that someone has to remember to update in parallel. When the address changes in your CMS, the schema should update automatically because it’s pulling from the same field, not because someone remembered to edit two places instead of one.

Audit cadence should scale with your location count:

  • Initial rollout: validate every page individually before going live, no exceptions for “it’s the same as the others.”
  • Weekly or monthly automated checks: run a lightweight script or third-party monitor across all location pages to catch new validator errors.
  • Quarterly full audits for chains with more than ten locations: a manual, page-by-page reconciliation against each Google Business Profile listing, because automated checks catch syntax errors, not truthfulness drift.

Seasonal hours deserve their own process rather than a manual edit each December. Set up specialOpeningHoursSpecification blocks with validFrom and validThrough dates well in advance, and if you’re managing more than a handful of locations, automate the override so nobody has to remember to revert Boxing Day hours back to normal on 27 December.

Rollout stage What to check Recommended frequency
Initial launch Every page validated individually against its GBP listing Before go-live, no exceptions
Ongoing monitoring Automated validator scan across all location pages Weekly to monthly
Full reconciliation Manual NAP and content match against GBP, location by location Quarterly

What agency audits actually find, and how to fix it fast

Running technical audits across client sites at Radka Advertising turns up the same handful of problems repeatedly, and almost none of them are exotic. The most common finding is a phone number in schema that doesn’t match Google Business Profile because someone updated GBP after a rebrand and never touched the site’s JSON-LD. The second most common is generic LocalBusiness typing on a business that had a specific subtype sitting right there in the Schema.org vocabulary, unused.

Corrective action is rarely complicated once the mismatch is spotted: pull the current GBP values, overwrite the schema fields, and re-run both validators to confirm the fix actually took.

For a single location, a realistic implementation and validation window is 60 to 90 minutes: collect the canonical GBP strings, geocode from the verified pin, assemble the JSON-LD, validate, deploy. A multi-location rollout takes considerably longer, often a week or more, depending on how much of the process your CMS lets you automate versus hand-build.

A short checklist worth running before you call any implementation finished:

  • GBP name, address, and phone copied exactly, not retyped from memory.
  • The most specific @type available for the business category.
  • Geo coordinates at five or six decimal places from the verified pin.
  • Opening hours formatted correctly, including any split shifts.
  • Both validators run clean, and the visible page manually checked against every marked-up field.

Pro Tip: If you’re procuring this work externally, ask the provider for their multi-location audit cadence before signing anything. A one-off implementation with no follow-up review is how schema quietly drifts out of date within a year.

Why exact matching beats clever schema every time

Subtype precision and exact GBP matching aren’t cosmetic details, they’re the mechanism by which AI systems and local pack algorithms decide your listing is trustworthy enough to cite. A Dentist node that matches GBP character for character carries more weight than a beautifully structured generic LocalBusiness node with a typo in the postcode. Get the boring fields right before you touch anything else.

My priority order for any team tackling this: accuracy first, always. Automation and monitoring second, because they only protect data that was correct to begin with. Cosmetic additions like extra sameAs links come a distant third.

If you only fix one thing this quarter, fix your NAP matching against GBP. Everything else on this page is secondary to that one alignment.

— Bart

Get your schema audited and implemented properly

Some agencies run schema work the way it should be run: audit first, then a phased rollout, then ongoing validation, rather than a one-off script tag and a wave goodbye. That’s the gap between a schema block that validates once and one that keeps earning rich results consistently over time. For businesses managing several locations, that audit-then-monitor structure matters more than any individual JSON-LD field.

If you want a technical read on where your current markup stands against Google Business Profile and the visible content on your pages, start with an SEO audit. For ongoing implementation across a growing site or a multi-location rollout, the full scope sits under Radkaadvertising’s services, where schema work runs alongside the technical SEO and content support that keeps it accurate as the business changes.

Sources

FAQ

What is schema markup, explained simply?

Schema markup is a standardised code vocabulary, based on Schema.org, that tells search engines exactly what a piece of content means rather than just what it says. Instead of a search engine guessing whether “14 High Street” is an address or a random string of text, schema labels it explicitly as a PostalAddress.

Can you give an example of schema markup?

A basic example marks up a business name, address, and phone number as structured JSON-LD, like the Dentist snippet shown earlier in this guide with name, address, and telephone properties. The same vocabulary can mark up a recipe’s ingredients, a product’s price, or an event’s date.

What is a local business schema?

Local business schema is the LocalBusiness type from Schema.org, used to describe a physical or service-area business with properties like address, phone number, and opening hours. Google recommends using the most specific subtype available, such as Restaurant or Dentist, rather than the generic LocalBusiness type.

Can you give an example of a LocalBusiness schema?

Yes: a single-location example includes @type, name, a PostalAddress object, telephone, url, geo coordinates, and openingHoursSpecification, all set out in the JSON-LD block earlier in this guide. Every value in that block needs to match the business’s Google Business Profile listing exactly, since mismatches undermine eligibility even when the code itself validates cleanly.

Do service-area businesses need a street address in their schema?

Not usually. A business that travels to customers rather than accepting walk-ins should typically use areaServed with named place nodes or a GeoCircle, and can omit streetAddress if it doesn’t correspond to a real customer-facing location, as outlined in the service-area example above.