Skip to main content
← All news

August 5, 2026

The Schema a Service Business Actually Needs (and the Three Kinds That Get You in Trouble)

Four types. Organization, Service, FAQPage and BreadcrumbList — the working set for almost every service business. Everything else is optional, and three types actively hurt you: Review or AggregateRating you wrote about yourself, LocalBusiness with an address you don't have, and plugin markup nobody has read. Every type you keep has to agree with the words a human can read on the page.

What schema actually does — and what it doesn't

Schema markup is JSON-LD: a block of structured data in your page head that restates, in machine-readable form, what the page already says in English. It is not a ranking factor — Google has said so repeatedly, and no amount of markup will rescue a page with nothing to say.

What it does do is narrower:

  • Makes you eligible for certain search features — breadcrumb trails in the SERP, article and event enhancements. Eligible, not entitled.
  • Removes ambiguity. A crawler reading prose has to infer that "we install heat pumps across the west GTA" names a service, a provider and a service area. Schema states all three.
  • Gives AI engines something quotable. An LLM assembling an answer about who to hire in your city is reconciling scraped text against structured claims. Clean schema is the cheapest way to be legible to it — which is why this is AI SEO work, not a plugin settings page.

What it does not do: rank you, verify you, or replace content. Anyone selling schema as a ranking lever is selling you the wrapper and calling it the gift.

The four types that carry weight

TypeWhat it doesWhat it does not do
OrganizationEstablishes the business as an entity: name, logo, official profiles, one stable IDDoes not create a knowledge panel or verify anything you claim
ServiceNames the specific thing you sell, who provides it, and whereDoes not produce a rich result — it is entity plumbing, not a badge
FAQPageMarks question-and-answer pairs as exactly that; heavily parsed by AI enginesNo longer shows accordion rich results for most sites — Google narrowed that to government and health sources
BreadcrumbListReplaces the raw URL in the SERP with a readable pathDoes not create hierarchy — it reports the one your URLs already have

Each block below goes inside a JSON-LD script tag — type="application/ld+json" — in the page head. Swap every value for yours. "Example Mechanical" is nobody: a generic heating and cooling contractor standing in for your business.

1. Organization — the identity node

Emit this once, sitewide, from your layout. It is the anchor every other node points at, which is why the @id matters more than anything else in it: pick a URL fragment, never change it, reference it from everywhere else.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://example-mechanical.ca/#organization",
  "name": "Example Mechanical",
  "url": "https://example-mechanical.ca/",
  "logo": "https://example-mechanical.ca/logo.png",
  "description": "Heat pump, furnace and air conditioning installation and service for homeowners across the west GTA.",
  "areaServed": [
    { "@type": "City", "name": "Mississauga" },
    { "@type": "City", "name": "Oakville" },
    { "@type": "State", "name": "Ontario" }
  ],
  "sameAs": [
    "https://www.facebook.com/examplemechanical",
    "https://www.linkedin.com/company/example-mechanical"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "contactType": "customer service",
    "url": "https://example-mechanical.ca/#contact",
    "availableLanguage": ["en"]
  }
}

Two notes. sameAs should list profiles you actually control and keep current — search engines follow those URLs to corroborate that you are who you say you are, and a 404 at the end of one is a real trust hit. And contactPoint accepts a URL, which matters if you run form-only contact. We do — there is no public phone number here to mark up.

2. Service — what you actually sell

One Service node per service page. This is the type most home-service sites skip, and the one that most directly answers the question an AI engine is asking: does this business do the specific thing the user described?

{
  "@context": "https://schema.org",
  "@type": "Service",
  "@id": "https://example-mechanical.ca/services/heat-pump-installation/#service",
  "name": "Heat Pump Installation",
  "serviceType": "Heat pump installation",
  "description": "Cold-climate heat pump sizing, installation and commissioning, including removal of the old system.",
  "url": "https://example-mechanical.ca/services/heat-pump-installation/",
  "provider": { "@id": "https://example-mechanical.ca/#organization" },
  "areaServed": [
    { "@type": "City", "name": "Mississauga" },
    { "@type": "City", "name": "Oakville" },
    { "@type": "City", "name": "Brampton" }
  ]
}

Notice what is missing: offers. Schema.org will accept an Offer node, and plenty of templates bolt one on by default. Only include it if a price is visibly printed on that page. Marking up a price the reader cannot see is the exact failure the next section is about.

3. FAQPage — the one AI engines read hardest

Google pulled FAQ rich results for most commercial sites in 2023, and a lot of agencies quietly stopped shipping FAQ schema when the visual reward disappeared. That was a mistake. The rich result went away; the parsing did not. Question-and-answer pairs are the most citable shape content can take, and answer engines treat them as pre-chunked source material.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Will a heat pump still heat the house in January?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A cold-climate unit sized for the house holds heat well below freezing. We size for your design temperature and set the backup to take over only when it has to."
      }
    },
    {
      "@type": "Question",
      "name": "How long does an installation take?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Most single-family changeovers are done in one day. Older homes needing electrical or ductwork changes run to two."
      }
    }
  ]
}

Non-negotiable: every question and every answer in that block must appear, in full, in the visible page. FAQ schema describing content the reader cannot find is a direct violation of Google's structured-data guidelines — the markup has to match what is on the page.

4. BreadcrumbList — cheap, and the one with a visible payoff

The least glamorous of the four and the only one that reliably changes what a searcher sees: a readable path instead of a URL string. It also states hierarchy explicitly, which matters once you have depth — a build with dozens of town pages, the shape of a 37-town service-area architecture, has to tell a crawler that the town page is a child of the service and not an orphan.

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home",
      "item": "https://example-mechanical.ca/" },
    { "@type": "ListItem", "position": 2, "name": "Services",
      "item": "https://example-mechanical.ca/services/" },
    { "@type": "ListItem", "position": 3, "name": "Heat Pump Installation",
      "item": "https://example-mechanical.ca/services/heat-pump-installation/" }
  ]
}

One rule: the trail has to match the URLs and the on-page navigation. A breadcrumb that puts a service under a Services page which does not exist is the same lie as any other mismatch.

Does my schema have to match what's on the page?

Yes. Schema must agree with the visible copy, or it is a liability, not an asset.

That is the whole discipline. Structured data is a set of sworn statements about a page, and Google — increasingly every AI engine — treats a mismatch between the statement and the visible page as a reason to distrust the page, then the site, then the entity. You do not get partial credit for the parts that were true.

The practical test takes ten seconds per field. Read the value. Find it on the page with your eyes. If you can't, one of two things is wrong: delete the markup, or add the content. There is no third option where you leave it and hope.

The three kinds that get you in trouble

  1. Review and AggregateRating you wrote about yourself. A star rating you assigned to your own business, on your own domain, sourced from nothing, is explicitly against Google's review-snippet guidelines, which prohibit reviews about the business collected on the business's own site. If you have genuine reviews on a third-party platform, they already carry markup there. Cite them in visible copy and link out. Don't restate them as your own rating.

  2. LocalBusiness with an address you don't have. If you run out of a truck, a home, or a unit you'd rather customers didn't visit, LocalBusiness with a fabricated or borrowed PostalAddress is a genuinely bad idea — it can jeopardize a Business Profile, and it is a lie a machine can check against other sources. The correct pattern is Organization plus honest areaServed, and it is a large enough topic to have its own post: service-area SEO when you don't have an address. We use a real Mississauga address in our own markup because we have one. That is the only qualification.

  3. Plugin-generated markup nobody has ever read. The default failure on WordPress: an SEO plugin emits a graph, the theme emits a second, a review plugin emits a third, and the page ends up asserting three identities with three different IDs — some of them describing demo content that shipped with the theme. Nominally "there," functionally worse than nothing. Every stack we build emits its schema from source we wrote, on a static architecture with no database and no plugins, so there is nothing to reinfect. We once rebuilt a business out of a roughly 1,200-page spam infestation onto exactly that architecture, cleaned it, and re-ranked it. We don't name clients in sensitive situations and we won't, so take the method and skip the logo — the sequence is in what to do when a WordPress site gets hacked.

A validation pass you can run today

  1. View source, don't trust the dashboard. Ctrl+U (Cmd+Option+U on Safari), then find ld+json. Count the blocks. More than you expected means duplicates.
  2. Paste the URL into the Schema Markup Validator at validator.schema.org. It reports every type on the page. Google's Rich Results Test only reports the types Google supports, so it stays silent on a broken Service node — use both, in that order.
  3. Read every value against the visible page. The ten-second test, field by field. The step people skip is the step that matters.
  4. Check ID consistency. One Organization @id sitewide, and every provider and publisher reference pointing at that exact string. Mismatched IDs create two businesses in the graph.
  5. Confirm what Google rendered, not what you shipped: Search Console → URL Inspection → Test Live URL. Client-side schema often doesn't survive.
  6. Re-run after any template change. Templates break schema silently, because nothing on the page looks different.

These types are running on the brands we build, so you can check the work instead of taking the advice. Open view-source on batsandwildlife.ca: one Organization node and no LocalBusiness — there is no public address to claim — with every town in the service area emitted as a typed City entity pointing at its own page. Open thecritterguy.ca: a Service node on the service pages, each one naming the same #organization ID as its provider. We didn't write those examples for this post. They shipped.

Then do the same thing to us. View-source on the x-veen.com homepage and you'll find one identity node at #organization, typed both Organization and ProfessionalService, plus a ProfessionalService node for the Mississauga office at #localbusiness that points back at it with parentOrganization. Two nodes, one identity, explicitly linked. Open our AI SEO page and you'll find FAQPage and BreadcrumbList — and every question in that FAQ block is printed on the page beneath it. Don't take our word for any of it. Read the source.

Why this is an AI SEO job, not a plugin job

Schema is how a machine confirms what your page claims. Prose is the claim; structured data is the corroboration. When an answer engine has to choose between two roofing companies for a Toronto homeowner's question, it is not weighing adjectives — it is weighing which entity it can describe with confidence. Clean, consistent, honest structured data is the difference between a business a model can name and one it can only gesture at.

That is the same mechanic behind why ChatGPT recommends your competitor, and most of what entity clarity means in practice. Four types, correctly stated, matching the page. That's the job.

If you'd rather someone else read your source than do it yourself — or you already looked and found three conflicting graphs in there — tell us what you want to rank for. One form, and a real reply from the people who'd do the work.