Guide SEO AI search Technical

Schema markup for AI search and Google: the six types a service business needs.

By Bob Clary Updated October 2026 16 min read 3,332 words

Every few weeks an owner sends me a proposal from an "AI SEO" vendor that lists schema markup as the secret to getting named by ChatGPT. It isn't a secret and it isn't magic. It's a way of stating facts about your business in a format machines can't misread, and most service businesses either don't have it, have a generic block a plugin added, or have three blocks that contradict each other. This guide is the version I wish those proposals included: what schema actually does in 2026, the six types a law firm, contractor or advisor needs, the exact JSON-LD to paste, and the mistakes that get it ignored.

What schema does and doesn't do in 2026

Schema markup (structured data, usually written as JSON-LD in the page's head) tells search engines and AI systems what the page is about in a vocabulary they share: this is a LegalService named X, at this address, open these hours, run by these Persons, offering these Services at these prices. The vocabulary lives at schema.org. Google reads it, Bing reads it, and the AI engines that lean on those indexes inherit it.

Three things it does well:

  • Rich results. Breadcrumbs, article dates, event and product details, and a handful of other enhancements in Google's results depend on it.
  • Entity clarity. When your name is spelled three ways across the web and your address changed in 2023, a single correct block on your own site is the tiebreaker. The AI engines build their answer from facts they can corroborate; a page that states the facts in text and again in markup is the easiest kind to corroborate.
  • Linking the pieces. The @id field lets you say "this Person works for this LegalService, which provides this Service, which this Article is about." That graph is what turns fourteen bio pages and twenty service pages into one firm.

Three things it doesn't do:

  • It doesn't rank you. Google's own guidance on AI features (published May 2026) says plainly: "Structured data isn't required for generative AI search," and that its AI features are built on the same core Search ranking and quality systems as everything else. Schema is a clarity tool, not a ranking lever.
  • It doesn't put stars on your listing. Since 2019, Google doesn't show review stars for "self-serving" markup, meaning a business marking up reviews of itself. The stars in local results come from your Google Business Profile.
  • It doesn't make FAQ dropdowns appear anymore. In August 2023 Google limited FAQ rich results to a narrow set of government and health sites, and removed HowTo rich results entirely the following month. Keep FAQ markup for what it still is: a clean, machine-readable version of the questions your buyers ask.
The honest summary

Schema won't get you named by an AI engine on its own. Missing or contradictory schema can keep you from being named, because it leaves the engine guessing about facts it could have been told. Do it once, do it correctly, and move on to the work that compounds: corroboration and quotable pages.

The six types a service business actually needs

You can mark up almost anything. You should mark up six things, on the pages where they live, and connect them with @id.

TypeGoes onWhat it establishesCommon mistake
The business (LegalService, RoofingContractor, FinancialService, or the closest LocalBusiness subtype)Homepage, and referenced by @id everywhere elseName, address, phone, hours, area served, founding date, what you do, where else you exist onlineRepeating the full block on every page with small differences
PersonEach team or bio pageWho the professionals are, their titles, licences, credentials, memberships, and which business they work forLeaving it off entirely, or using it only for the founder
ServiceEach service or practice-area pageWhat exactly is offered, where, by whom, and what it costsMarking up the page as a second copy of the business
FAQPagePages with a real, visible question-and-answer sectionThe buyer's questions, answered in quotable sentencesQuestions and answers that aren't visible on the page
BreadcrumbListEvery page below the homepageWhere the page sits in the siteBreadcrumbs in the markup that don't match the ones on the page
Article / BlogPostingGuides and postsWho wrote it (a Person with an @id), when, and for whomAuthor set to "admin" or to the company instead of a person

Everything below uses two fictional businesses: a Syracuse estate-planning firm and a Central New York roofer. Swap in your own facts; keep the structure.

The business: LegalService, RoofingContractor, FinancialService

Use the most specific type that fits. Schema.org has subtypes of LocalBusiness for most service categories: LegalService and Attorney for law firms; RoofingContractor, HVACBusiness, Plumber, Electrician, GeneralContractor and HomeAndConstructionBusiness for the trades; FinancialService, InsuranceAgency and AccountingService for advisors. If none fit, ProfessionalService or plain LocalBusiness is fine.

This block goes once, on the homepage. Every other page refers to it by its @id instead of repeating it.

A law firm

{
  "@context": "https://schema.org",
  "@type": "LegalService",
  "@id": "https://www.harborvalelaw.com/#firm",
  "name": "Harbor & Vale Law",
  "alternateName": "Harbor and Vale",
  "legalName": "Harbor & Vale Law Professional Corporation",
  "url": "https://www.harborvalelaw.com/",
  "logo": "https://www.harborvalelaw.com/img/logo.png",
  "image": "https://www.harborvalelaw.com/img/office.jpg",
  "telephone": "+1-315-555-0142",
  "email": "hello@harborvalelaw.com",
  "description": "Estate planning and probate law firm in Syracuse, New York. Flat-fee wills and trusts since 2009.",
  "foundingDate": "2009",
  "founder": {
    "@type": "Person",
    "@id": "https://www.harborvalelaw.com/team/dana-vale/#person"
  },
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "120 E Washington St, Suite 400",
    "addressLocality": "Syracuse",
    "addressRegion": "NY",
    "postalCode": "13202",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 43.0481,
    "longitude": -76.1474
  },
  "areaServed": [
    {
      "@type": "AdministrativeArea",
      "name": "Onondaga County, NY"
    },
    {
      "@type": "AdministrativeArea",
      "name": "Madison County, NY"
    }
  ],
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": [
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday"
      ],
      "opens": "08:30",
      "closes": "17:00"
    }
  ],
  "priceRange": "$$",
  "knowsAbout": [
    "Estate planning",
    "Wills and trusts",
    "Probate",
    "Elder law"
  ],
  "sameAs": [
    "https://www.linkedin.com/company/harbor-vale-law",
    "https://www.avvo.com/attorneys/harbor-vale-law",
    "https://www.facebook.com/harborvalelaw"
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Services",
    "itemListElement": [
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "@id": "https://www.harborvalelaw.com/estate-planning/#service"
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "@id": "https://www.harborvalelaw.com/probate/#service"
        }
      }
    ]
  }
}

Notes on the fields that matter most:

  • @id is a stable label, not a page. https://www.yoursite.com/#firm is the convention. Every Person, Service and Article will point back to it.
  • name, alternateName, legalName are where you settle the spelling question for good. If your brand is "B.I.G. Law" and half the web writes "BIG Law," put the variant in alternateName so the engines connect them.
  • areaServed should say where you actually take clients, not every town within driving distance. A list of forty cities reads as spam to a human reviewer and adds nothing for a machine.
  • sameAs is your corroboration list: the profiles that are definitely you. LinkedIn, the state bar directory, Avvo, the BBB, Facebook. Don't include anything you haven't checked.
  • priceRange accepts free text. "$$" is nearly useless; "$1,800 flat fee for a will-based plan" is a fact an engine can quote.

A roofing contractor

Same shape, different type, with licence and price range stated because those are the two things a homeowner's prompt asks about.

{
  "@context": "https://schema.org",
  "@type": "RoofingContractor",
  "@id": "https://www.ridgelineroofingcny.com/#business",
  "name": "Ridgeline Roofing",
  "url": "https://www.ridgelineroofingcny.com/",
  "telephone": "+1-315-555-0188",
  "image": "https://www.ridgelineroofingcny.com/img/crew.jpg",
  "description": "Residential roof replacement and storm repair in Central New York since 2004. GAF-certified installers, financing available, free inspections.",
  "foundingDate": "2004",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "4410 Route 31",
    "addressLocality": "Clay",
    "addressRegion": "NY",
    "postalCode": "13041",
    "addressCountry": "US"
  },
  "areaServed": [
    {
      "@type": "City",
      "name": "Syracuse"
    },
    {
      "@type": "City",
      "name": "Liverpool"
    },
    {
      "@type": "City",
      "name": "Cicero"
    },
    {
      "@type": "City",
      "name": "Baldwinsville"
    }
  ],
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": [
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday"
      ],
      "opens": "07:00",
      "closes": "18:00"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "08:00",
      "closes": "14:00"
    }
  ],
  "priceRange": "$8,000–$30,000 typical full replacement",
  "hasCredential": {
    "@type": "EducationalOccupationalCredential",
    "credentialCategory": "NYS Home Improvement Contractor License",
    "name": "License #XXXXXX"
  },
  "sameAs": [
    "https://www.facebook.com/ridgelineroofing",
    "https://www.bbb.org/us/ny/clay/profile/roofing-contractors/ridgeline-roofing-0041-XXXXX"
  ],
  "makesOffer": [
    {
      "@type": "Offer",
      "itemOffered": {
        "@type": "Service",
        "name": "Asphalt shingle roof replacement"
      },
      "priceCurrency": "USD",
      "priceSpecification": {
        "@type": "PriceSpecification",
        "minPrice": 8000,
        "maxPrice": 30000,
        "priceCurrency": "USD"
      }
    },
    {
      "@type": "Offer",
      "itemOffered": {
        "@type": "Service",
        "name": "Storm damage repair and insurance claim support"
      }
    }
  ]
}

For a financial advisor, use "@type": "FinancialService" and put the regulatory registration (SEC or state, CRD number) in a hasCredential block the same way the roofer's licence is shown. The AI engines' answers to "is this advisor legitimate" come from exactly these facts, corroborated against the regulator's own database.

Person: every professional, with the licence number

This is the block most service sites skip, and for law firms and advisors it's the most valuable one. The engines weight authorship and verifiable credentials. A bio page that says "Dana is passionate about helping families" gives them nothing; a Person block with a job title, a bar registration number, a law school and a bar association membership gives them a record they can check against the state's own directory.

{
  "@context": "https://schema.org",
  "@type": "Person",
  "@id": "https://www.harborvalelaw.com/team/dana-vale/#person",
  "name": "Dana Vale",
  "honorificSuffix": "J.D.",
  "jobTitle": "Attorney and Founding Partner",
  "url": "https://www.harborvalelaw.com/team/dana-vale/",
  "image": "https://www.harborvalelaw.com/img/team/dana-vale.jpg",
  "worksFor": {
    "@type": "LegalService",
    "@id": "https://www.harborvalelaw.com/#firm"
  },
  "identifier": {
    "@type": "PropertyValue",
    "propertyID": "New York Attorney Registration Number",
    "value": "4XXXXXX"
  },
  "hasCredential": {
    "@type": "EducationalOccupationalCredential",
    "credentialCategory": "Admission to the New York State Bar",
    "recognizedBy": {
      "@type": "Organization",
      "name": "New York State Unified Court System"
    }
  },
  "alumniOf": {
    "@type": "CollegeOrUniversity",
    "name": "Syracuse University College of Law"
  },
  "memberOf": {
    "@type": "Organization",
    "name": "Onondaga County Bar Association"
  },
  "knowsAbout": [
    "Estate planning",
    "Trust administration",
    "Probate litigation"
  ],
  "sameAs": [
    "https://www.linkedin.com/in/danavale",
    "https://iapps.courts.state.ny.us/attorneyservices/search"
  ]
}
  • identifier carries the licence or registration number. Name the issuing system in propertyID so it's unambiguous.
  • worksFor points at the business's @id. That single line is what connects the bio to the firm.
  • sameAs should include the person's LinkedIn and, where one exists, their entry in the regulator's public directory.
  • Put the same facts in the visible bio text. Markup that says something the page doesn't is the fastest way to get all of your markup ignored.

Service: one block per service page, with the price

A service page should be marked up as a Service provided by the business, not as another copy of the business. This is where the price goes, and if you've been avoiding putting prices on the site, this is the argument for stopping: the engines answer "how much does X cost" constantly, and they answer it from pages that say.

{
  "@context": "https://schema.org",
  "@type": "Service",
  "@id": "https://www.harborvalelaw.com/estate-planning/#service",
  "name": "Estate planning",
  "serviceType": "Estate planning",
  "description": "Wills, revocable trusts, powers of attorney and health care proxies for New York residents. Flat fee, two meetings, documents signed within three weeks.",
  "url": "https://www.harborvalelaw.com/estate-planning/",
  "provider": {
    "@type": "LegalService",
    "@id": "https://www.harborvalelaw.com/#firm"
  },
  "areaServed": {
    "@type": "State",
    "name": "New York"
  },
  "offers": {
    "@type": "Offer",
    "priceCurrency": "USD",
    "price": "1800",
    "description": "Flat fee for a will-based plan for an individual; trust-based plans from $3,500."
  }
}

Ranges are fine. For the roofer above, a PriceSpecification with minPrice and maxPrice states the typical job without committing to a quote. "Starts at" with a number beats "contact us for pricing" every time an engine is deciding which page to lift a sentence from.

FAQPage: the questions buyers ask, visible on the page

The dropdowns are mostly gone from Google's results, so the reason to keep FAQ markup is the AI engines. A question followed by a direct, specific, dated answer is the most quotable thing on a service website. Three rules: the questions must be the ones buyers actually ask (pull them from your inbox and your call notes, not from a keyword tool), the answers must be visible on the page in the same words, and the answers should carry a specific: a number, a timeframe, a place.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How much does a will cost in New York?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "At Harbor & Vale a will-based estate plan for an individual is a flat $1,800, which includes the will, a power of attorney and a health care proxy. Trust-based plans start at $3,500. Prices are current as of October 2026."
      }
    },
    {
      "@type": "Question",
      "name": "How long does probate take in Onondaga County?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "An uncontested estate with a valid will typically takes nine to fourteen months from filing to final distribution in Onondaga County Surrogate's Court. Contested matters take longer."
      }
    }
  ]
}

Notice the date in the first answer. Prices change; an answer that says when it was true gives the engine (and the reader) a reason to trust it, and gives you a reason to update it.

Small, mechanical, and worth doing on every page below the homepage because Google uses it for the breadcrumb line in results and because it tells every engine how your site is organized. The markup should match the visible breadcrumb exactly.

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://www.harborvalelaw.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Estate planning",
      "item": "https://www.harborvalelaw.com/estate-planning/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Revocable trusts"
    }
  ]
}

Article: who wrote it, and when

If a professional at the firm writes guides (and they should; that's most of the AI-search game for a law firm), each one needs an Article block whose author is a Person @id, not a name string, and whose publisher is the business @id. That's how the engine learns that the person with the bar number is the person who wrote the guide on probate timelines.

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "What a revocable trust costs in New York, and when you don't need one",
  "description": "A plain-language guide to revocable trust costs in New York, written by an estate planning attorney.",
  "datePublished": "2026-09-12",
  "dateModified": "2026-10-02",
  "author": {
    "@type": "Person",
    "@id": "https://www.harborvalelaw.com/team/dana-vale/#person"
  },
  "publisher": {
    "@type": "LegalService",
    "@id": "https://www.harborvalelaw.com/#firm"
  },
  "mainEntityOfPage": "https://www.harborvalelaw.com/guides/revocable-trust-cost-new-york/"
}

Want me to check your schema?

Send your website and I'll tell you what's on the page now, what's missing or contradicting itself, and the exact blocks to add. Free, written, within 24 hours.

Prefer to talk? 315.430.0782. I answer my own phone.

The mistakes that get schema ignored

In the structured-data checks I run, these account for nearly every problem:

  1. The markup says what the page doesn't. Google's guidelines require marked-up content to be visible to the reader. An FAQ block with questions that aren't on the page, a rating with no reviews shown, an address the contact page contradicts: any of these can get the whole page's markup disregarded.
  2. Three blocks, three stories. A theme adds one Organization block, an SEO plugin adds another, and someone pasted a third from a generator in 2021. They disagree on the name or the phone. Pick one, delete the rest.
  3. The business block on every page. Forty pages each claiming to be the business, with slightly different fields, is forty chances to contradict yourself. One block on the homepage, @id references everywhere else.
  4. Self-serving reviews expecting stars. Covered above. The markup isn't against the rules; the expectation is wrong.
  5. Generic type where a specific one exists. "LocalBusiness" for a law firm throws away the one word (LegalService) that would have told the engine your category.
  6. Fake precision. geo coordinates pointing at the wrong block, hours that don't match the Business Profile, an areaServed list copied from a competitor. The engines cross-check; mismatches cost more than omissions.
  7. Markup that's blocked. If the page is noindexed, behind a login, or served only through JavaScript that your platform blocks for crawlers, the schema is invisible. Check the page in Google's Rich Results Test first; if it can't fetch the page, nothing else matters.

How to test it in ten minutes

  1. Read what's there now. View the page source (right-click, View Page Source) and search for application/ld+json. Read every block. Most owners are surprised by what their site has been telling machines.
  2. Validate the syntax. Paste each block into the Schema Markup Validator. It catches broken JSON and unknown properties.
  3. Check Google's view. Put the URL into the Rich Results Test. It shows which items Google detected and which are eligible for rich results. "No items detected" on a page that has markup usually means a syntax error or a blocked page.
  4. Watch Search Console. After the change, the Enhancements section reports errors and warnings per type over the following weeks.
  5. Re-run your buyer prompts in thirty days. Schema is one input among several. The test that matters is whether the engines state your facts correctly when a buyer asks. The twenty-minute version of that check is here.

Where to put it on Webflow, WordPress, Squarespace and Wix

  • Webflow. Site settings → Custom code → Head code for the business block (sitewide), and Page settings → Custom code → Inside head tag for per-page blocks. On CMS collection pages, you can build the block from collection fields with an embed, which is how a firm with fourteen lawyers gets fourteen correct Person blocks without hand-editing each.
  • WordPress. Yoast and Rank Math both generate a sitewide graph (Organization or Person, WebSite, WebPage, Article). Configure the business details there once, then check the output; add Service and Person blocks per page with a custom HTML block or the plugin's schema builder. Disable any second schema plugin.
  • Squarespace. Settings → Advanced → Code injection → Header for the business block; per-page code injection under each page's Advanced settings. Squarespace also adds its own basic LocalBusiness block from your business information settings, so check for duplicates.
  • Wix. Each page's SEO settings include a structured data section where you can add custom JSON-LD; Wix also auto-generates some types, which you can edit or disable there.

Whatever the platform, the sequence is the same: one correct business block, one Person block per professional, one Service block per service page, FAQ and breadcrumb where they apply, Article on the guides. Then test, then move on.

Questions I get about this

Does schema markup help you show up in ChatGPT and AI Overviews?

Indirectly. Google says structured data isn't required for its AI features, and no engine has said it ranks you higher for having it. What schema does is state your facts in a form that can't be misread: who you are, where, what you do, who the people are, what things cost. The engines build their answers from facts they can corroborate, and a page that states them plainly in text and in markup is easier to corroborate than one that doesn't.

Will adding AggregateRating give me star ratings in Google?

Not on your own business pages. Since September 2019, Google doesn't show review stars for "self-serving" markup, which is a LocalBusiness or Organization marking up reviews of itself. The stars you see in local results come from Google's own review system through your Business Profile. You can still include the rating in your markup as a fact about the entity; just don't expect a rich result from it.

Do FAQ schema dropdowns still show in Google search?

Rarely. In August 2023 Google limited FAQ rich results to well-known government and health sites. Keep the markup on a real FAQ page anyway: it's a clean, machine-readable version of the questions buyers ask, and the question-and-answer format is exactly what AI engines lift. Just make sure every question and answer is visible on the page.

Should I use LocalBusiness or the specific type like LegalService?

The specific type, when one exists. LegalService, Attorney, RoofingContractor, HVACBusiness, Plumber, Electrician, GeneralContractor, FinancialService, InsuranceAgency and AccountingService are all subtypes of LocalBusiness, so you lose nothing and you gain precision. If no subtype fits, LocalBusiness or ProfessionalService is fine.

My SEO plugin already adds schema. Do I need to do anything?

Check what it actually outputs. Plugins and themes commonly add a generic Organization or WebSite block, sometimes two, and sometimes one that contradicts what you typed into the plugin settings months ago. View the page source, search for application/ld+json, and read every block. One correct block beats three partial ones.

How long until schema changes show up?

Google usually re-reads a changed page within days to a couple of weeks; you can request indexing in Search Console to speed it up. The AI engines that use Bing's index or their own crawlers vary. The practical answer is to re-run your buyer prompts thirty days after the change and compare.

Bob Clary
Written by
Bob Clary
Senior marketing strategist. Runs SEO and AI search, paid media, and AI automation directly for owner-led companies. 14× Inc. 5000. Syracuse, NY · 315.430.0782

Want the schema done,
not just explained?

The free SEO audit includes a structured-data check: what Google and the AI engines can read about you today, what they can't, and the blocks I'd add first.

Get my free audit →

Or call 315.430.0782.

Call Bob Run it for me