Answer the Business

LocalBusiness schema, written out line by line

AB
The Answer the Business team
· 8 min read

Structured data is the one place you can state your facts in a form built to be copied. Here is the whole block, with the reasoning for every line in it.

What it actually does for you

Structured data does not make you rank. It does something narrower and more useful: it states your facts in a format designed to be lifted without being misread.

Everything else on your site has to be interpreted. A machine reading your homepage has to work out that the numbers in the footer are opening hours, that the town names in a paragraph are a service area rather than a list of past jobs, and that the phone number in the header belongs to you rather than to a supplier. Sometimes it works that out correctly. Structured data removes the guess.

That is why it carries the largest single share of the readiness half of a visibility score — more than a sitemap, more than an llms.txt. Not because it is magic, but because it is the one thing on your site that says here are my facts, labelled, in a form nothing has to infer.

It is also an afternoon of work, once, and then it is done.

Which type counts

LocalBusiness, or one of its subtypes. The subtypes are better where one fits, because they say more with the same effort — a plumber, a dentist, a roofing contractor, a restaurant, a beauty salon and a legal service all have their own types, and each carries the category into the markup rather than leaving it to be inferred from your prose.

If nothing fits, plain LocalBusiness is correct and sufficient. What does not count is Organization on its own, which describes an entity without describing a place you can visit or call, and which is what most template-generated markup emits by default.

The block

Here is the whole thing. Every line is explained underneath.

{
  "@context": "https://schema.org",
  "@type": "Plumber",
  "@id": "https://example.com/#business",
  "name": "Ridgeline Plumbing",
  "url": "https://example.com",
  "telephone": "+1-303-555-0134",
  "image": "https://example.com/photos/shopfront.jpg",
  "priceRange": "$$",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "2100 S Broadway",
    "addressLocality": "Denver",
    "addressRegion": "CO",
    "postalCode": "80210",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 39.6789,
    "longitude": -104.9876
  },
  "areaServed": [
    { "@type": "City", "name": "Denver" },
    { "@type": "City", "name": "Englewood" },
    { "@type": "City", "name": "Littleton" }
  ],
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "18:00"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "09:00",
      "closes": "13:00"
    }
  ],
  "sameAs": [
    "https://www.google.com/maps/place/?q=place_id:EXAMPLE",
    "https://www.facebook.com/example",
    "https://www.yelp.com/biz/example"
  ]
}

Line by line

@context never changes. It tells a parser which vocabulary the rest of the block is written in. Copy it exactly.

@type is the category, and it is the line worth thinking about longest. Pick the most specific type that is genuinely true. Do not pick a more impressive one because it sounds better — a contradiction between the type and the visible page is a contradiction on your own domain, which is the expensive kind.

@id gives the entity a stable identifier so other blocks on other pages can refer to the same business rather than describing a second one. Use your domain with a fragment and never change it.

name must be the string you use everywhere else. Not the trading name here and the limited-company name on a directory. This is the single most-copied field you own, and a variant spelling is how one business becomes two records that neither of them fully populates.

url and telephone are the two fields most often quoted straight into an answer. The phone number should be the one a customer should actually ring, in international format, and it should be the same number as the one on your profile.

image wants a real photograph of the place, not a logo on white. It is used in more surfaces than you would expect and it is cheap to get right.

priceRange is a coarse band rather than a price. It is worth including because it is a question people ask, and it is worth understanding that it does not replace putting actual prices on the site — a band tells somebody you are mid-market, not what the job costs.

address should be a nested PostalAddress rather than one string. Separate fields are what let a parser match your address to a record in a directory without fuzzy matching, and fuzzy matching on addresses is where duplicates come from.

geo is optional and cheap. Include it if you can get the coordinates from your own map listing; skip it rather than guess.

openingHoursSpecification is the field with the highest cost of being wrong, because hours are what engines get confidently wrong most often and a wrong closing time sends somebody to a locked door. Use the array form, one entry per distinct pattern, times in twenty-four-hour notation. Remember to come back to it when your hours change seasonally.

areaServed is what makes you eligible for questions about a specific town. An engine will not name you for a place you never claim, and this is the machine readable half of claiming it — the other half is the same towns written out in prose somewhere on the site.

sameAs is the most underused line in the block. It links this entity to your profiles elsewhere, which is how a parser knows that the record on a directory and the record on your site describe one business rather than two. If you have done the work of making your listings agree, this is the line that tells a machine they are meant to.

Where to put it

In a <script type="application/ld+json"> tag in the head of your homepage. One block for the business, on the page that represents the business.

Do not scatter partial copies across every page — a differing copy on a service page is another contradiction to reconcile. Service pages can carry their own Service markup that refers back to the business by its @id, but that is refinement, and the homepage block is the ninety per cent.

The rules that keep it honest

Two, and they matter more than any field above.

The markup must agree with the visible page. If your structured data says you open at eight and the page says nine, you have published a contradiction about yourself in the one place that was supposed to remove ambiguity. Every field in the block should be a fact a visitor can also read in the text.

Do not invent ratings. Marking up an aggregate rating you assembled yourself, or that no visible reviews on the page support, is against the guidelines of every platform that reads it, and it is the fastest way to have your markup discounted entirely. Reviews belong on the platforms that host them, and sameAs is how you point at those.

There is a version of this advice that goes further and it is worth naming so you can ignore it: instructions to models hidden in markup, keyword-stuffed description fields, types chosen for prestige. All of it is either ignored or actively counted against the page, and none of it survives the first person who looks at your source.

What it will not do

It will not put you in an answer on its own. A perfectly marked-up site with no prices, no service pages and no listings anywhere else is a well-formed way of saying nothing, and it will score full marks on readiness while losing every question that turns on substance.

Readiness and content fail independently — that separation is deliberate, and the scoring breakdown explains why. Structured data is the plumbing. It makes the facts you have legible. It does not generate facts you have not got.

But my facts are already on my profile

They are, and that is not the same thing.

A directory record is a copy of your facts held by somebody else, on a page you do not control, in a format they can change. It is genuinely useful — engines read it constantly — and it is the reason a business with no website at all can still be described tolerably well.

What it cannot do is make your own domain a source. When every fact an engine holds about you came from a third party, the third parties are writing your description and your site is decoration. Publishing the same facts on your own domain, in a form built to be copied, is how your site enters the set of things worth quoting — which is the ownership half of the citation pillar and the slowest number in the report to move.

The sameAs line is what stops this becoming a competing account. It says: this entity, here, is the same one described over there. Done properly, the markup does not argue with your listings, it claims them.

If your site is built on a platform

Most are, and most platforms already emit something. Before you write a line, check what is actually being published: view the page source and search for ld+json.

Three things turn up regularly. The first is an Organization block with a name and a logo and nothing else, which is technically valid and does none of the work above. The second is a theme emitting a block with placeholder values left in from the demo content — an address in another country is not unusual. The third, and the most annoying, is two blocks describing the same business differently, one from the theme and one from a plugin somebody installed a year ago.

Two blocks disagreeing is worse than one thin block, so resolve that before you add anything. Where a plugin owns the markup, configure the plugin rather than hand-writing a second copy; where the theme hardcodes it, override the theme. The goal is exactly one description of the business on the domain.

When the fields do not fit your business

Not every local business is a shop with a door.

If you work from home or from a van and do not publish an address, do not invent one and do not publish a residential address you would rather keep private. Omit address, keep areaServed, and lean on the towns. A service business that covers a region is a normal thing to describe and the vocabulary handles it.

If you have several locations, each one gets its own page and its own block with its own @id, and the addresses differ. One block listing three addresses describes nothing coherently.

If your hours are genuinely irregular — appointment only, seasonal, by arrangement — say that in prose on the page and omit the hours specification rather than publishing a pattern you will not keep. A missing field costs you a point. A wrong one costs you a customer standing outside.

Checking it

Paste the page into a structured data validator and fix anything it flags. Then do the check that matters more: read the block against the page and against your own profile, field by field, and confirm all three say the same thing.

While you are in the source, make sure the crawlers that would read it are allowed in at all — which is a separate afternoon, and a shorter one.

See where you stand right now.

A free scan across every engine we probe. No card, no login.

Scan my business — free