# LocalBusiness Schema: The Markup That Wins Local + AI Search

**Author:** John Morabito (Founder, /winston)
**Published:** June 14, 2026
**Reading time:** 11 minutes
**Canonical:** https://www.winstondigitalmarketing.com/playbooks/local-business-schema-guide/

Most local sites either ship no structured data or ship the wrong type with half the fields missing. LocalBusiness schema is the one block that tells Google and the AI engines what you are, where you operate, and how to verify it. Here is the right type, the fields that actually move things, copy-paste examples, and the four mistakes that quietly void the whole thing.

## What LocalBusiness schema does, in one paragraph

LocalBusiness schema is a JSON-LD block that names your business as a verifiable entity: what it is, where it sits, when it is open, and which profiles confirm it. It is a subtype of `Organization`, so it inherits `name`, `url`, `logo`, and `sameAs`, then adds the local fields that decide the map pack and feed the AI answer: `address`, `geo`, `openingHoursSpecification`, `telephone`, `priceRange`, and `areaServed`. Google uses it to confirm the entity behind your Business Profile. The AI engines use it to reconcile your site with an entity they can cite by name instead of guessing from prose.

## Pick the most specific type you can

The single most common mistake is shipping the generic `LocalBusiness` type when a precise subtype exists. Schema.org publishes dozens of them, and a specific type tells an engine more than the parent does. A dentist marks up as `Dentist`, a law firm as `Attorney` or `LegalService`, a furnace company as `HVACBusiness`, a clinic as `MedicalBusiness`. Only fall back to bare `LocalBusiness` when nothing fits.

| Business | Right type | Why |
|---|---|---|
| Dental practice | `Dentist` | Its own type with medical fields |
| Law firm | `Attorney` / `LegalService` | Practice-area context |
| HVAC / home service | `HVACBusiness` | Service-area business semantics |
| Med spa / clinic | `MedicalBusiness` | Treatment and provider context |
| Anything with no subtype | `LocalBusiness` | The honest fallback |

## The fields that actually matter

You do not need every property schema.org allows. You need the handful that engines read for ranking and verification, filled accurately and kept identical to your Google Business Profile.

- **`name`, `url`, `telephone`, `address`.** Your NAP, byte-for-byte the same as your GBP and your footer. A mismatch here is the fastest way to look like two different businesses.
- **`geo`.** Latitude and longitude. It removes the guesswork for proximity and disambiguates you from a similarly named business across town.
- **`openingHoursSpecification`.** Structured hours, not a sentence. Engines surface "open now" from this.
- **`areaServed`.** The cities, neighborhoods, or radius you actually serve. For a service-area business with no walk-in storefront, this is the field that tells engines where you operate, and it is the one most templates omit.
- **`sameAs`.** The verification array. Links to your GBP, LinkedIn, Facebook, Yelp, and industry profiles. This is how an AI engine reconciles your page with the entity it already trusts, which is one of the strongest citation signals you can send.
- **`priceRange`, `image`, `aggregateRating`.** Helpful context. Only add `aggregateRating` if the reviews are real and on-page; faking it is a manual-action risk.

## The copy-paste example

Here is a connected `Dentist` block (swap the type for yours) with a stable `@id` so the rest of your graph can reference it. Server-render it; do not inject it only through a tag manager.

```json
{
  "@context": "https://schema.org",
  "@type": "Dentist",
  "@id": "https://example.com/#business",
  "name": "Astoria Smile Studio",
  "url": "https://example.com/",
  "telephone": "+1-718-555-0142",
  "priceRange": "$$",
  "image": "https://example.com/assets/storefront.jpg",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "31-12 Ditmars Blvd",
    "addressLocality": "Astoria",
    "addressRegion": "NY",
    "postalCode": "11105",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 40.7752,
    "longitude": -73.9121
  },
  "areaServed": [
    { "@type": "City", "name": "Astoria" },
    { "@type": "City", "name": "Long Island City" }
  ],
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
    "opens": "09:00",
    "closes": "18:00"
  }],
  "sameAs": [
    "https://www.google.com/maps/place/?q=place_id:YOUR_PLACE_ID",
    "https://www.linkedin.com/company/astoria-smile-studio",
    "https://www.facebook.com/astoriasmilestudio"
  ]
}
```

That `@id` matters. It lets your `Article`, `Person`, and `FAQPage` blocks point back to the same business entity instead of floating as disconnected fragments. The connected-graph pattern, and the broader entity-graph minimum every page should hit, lives in [schema markup for AI engines](https://www.winstondigitalmarketing.com/playbooks/schema-markup-for-ai-engines-2026/).

## The four mistakes that void the block

1. **Wrong type.** Generic `LocalBusiness` when `Dentist` or `HVACBusiness` exists. You leave context on the table.
2. **NAP that disagrees with GBP.** A different phone format or suite number reads as a second entity and dilutes both.
3. **Markup that does not match the visible page.** Schema describing hours, ratings, or an address the user cannot see is a structured-data violation and can trigger a manual action. Mark up what is on the page.
4. **Injected client-side only.** If the block exists only after JavaScript runs through a tag manager, some crawlers and AI fetchers never see it. Server-render it. This is the same rendering-parity rule we apply across a build in [local landing pages at scale](https://www.winstondigitalmarketing.com/playbooks/local-landing-pages-50-in-a-week/).

## The quick win

For a single-location business, a correct LocalBusiness block is an afternoon of work with outsized return: it firms up the map pack, hands the AI engines a verifiable entity, and costs nothing but accuracy. If you run a multi-location or service-area operation, the per-location `@id` graph and `areaServed` logic is where it gets real, and it is part of the technical foundation we set on every [SEO retainer](https://www.winstondigitalmarketing.com/services/seo/). The structured-data section of an [E-A-T audit](https://www.winstondigitalmarketing.com/playbooks/eat-audit-google-rater-guidelines/) is where we usually surface the broken blocks first.

## How to verify it shipped

1. **Validate.** Run the page through Google's Rich Results Test and the schema.org validator. Zero errors, and the type reads as the specific subtype you chose.
2. **Confirm server-render.** View source (not the rendered DOM) and find the JSON-LD in the raw HTML.
3. **Cross-check NAP.** Name, address, phone identical across the schema, the footer, and the Google Business Profile.
4. **Watch the entity.** Over the following weeks, spot-check whether AI engines name your business on local queries. When they name a competitor instead, the gap is usually a missing `sameAs` link or a thinner entity, not a content problem.

## Frequently asked questions

**What is LocalBusiness schema?**

LocalBusiness schema is structured-data markup (a block of JSON-LD) that tells search engines and AI engines what your business is, where it is, what it does, and how to verify it. It is a subtype of Organization, so it inherits fields like name, url, logo, and sameAs while adding local-specific ones: address, geo coordinates, openingHoursSpecification, telephone, priceRange, and areaServed. A connected, accurate LocalBusiness block helps you win the map pack and gives AI engines a machine-readable entity they can cite by name.

**Which LocalBusiness type should I use?**

Use the most specific subtype that exists for your business, not the generic LocalBusiness type. Schema.org publishes dozens of subtypes: Dentist, Attorney, HVACBusiness, MedicalBusiness, Restaurant, AutoRepair, and many more. A specific type tells engines more about you than the parent. If no subtype fits, fall back to LocalBusiness. For a multi-service company, pick the type that matches your primary service and list the rest in your service pages and GBP categories rather than stacking multiple top-level types.

**Does LocalBusiness schema help with AI search?**

Yes. AI engines assemble answers from sources they can parse and trust, and a clean LocalBusiness block gives them a verifiable entity to attribute. The sameAs array (links to your GBP, LinkedIn, and other profiles) lets an engine reconcile your site with the entity it already knows, which is one of the strongest citation signals. Schema does not guarantee a citation on its own, but without it you are asking the engine to infer your identity from prose, and inference loses to verification every time.

---

Service: https://www.winstondigitalmarketing.com/services/seo/
Audit: https://www.winstondigitalmarketing.com/contact/#audit
