If you build or maintain sites for service businesses (agencies, clinics, law firms, contractors, consultants), here's the problem in one line: LLM-powered search — ChatGPT, Perplexity, Google AI Overviews, Gemini — extracts facts from structured markup far more reliably than from prose, and most service-business sites still ship zero or broken Schema.org markup.
The fix is a well-formed JSON-LD graph describing the business, its services, and its reviews — validated, kept in sync with the actual page content, and shipped as part of the build, not bolted on after launch. This post walks through what to implement, real code, and the mistakes that get markup silently ignored (or worse, flagged).
What structured data is and how it works, technically
Schema is a shared vocabulary (maintained jointly by Google, Microsoft, Yahoo) for describing entities on a page in a machine-parseable way. Google's preferred implementation is JSON-LD — a single <script type="application/ld+json"> block, decoupled from your HTML/CSS, so you can generate and update it independently of your markup.
Minimal example for a service business homepage:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProfessionalService",
"@id": "https://example.com/#organization",
"name": "Example Legal Group",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"address": {
"@type": "PostalAddress",
"streetAddress": "12 Khreshchatyk St",
"addressLocality": "Kyiv",
"addressCountry": "UA"
},
"areaServed": "Kyiv Oblast",
"telephone": "+380-44-000-0000",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "18:00"
}
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "96"
}
}
</script>
Why this matters more than it used to: search crawlers have used this for rich results (star snippets, FAQ dropdowns) for a decade, but AI answer engines now use it as a primary extraction source when synthesizing an answer. Structured, typed JSON is simply cheaper and more reliable for an LLM's retrieval pipeline to trust than unstructured paragraph text — it reduces hallucination risk on their end, which means they're more likely to cite you accurately (or at all).
This is the core idea behind AEO (Answer Engine Optimization): optimizing not just for keyword relevance, but for machine-extractability.
Why it matters for the business (not just the ranking algorithm)
- People now ask ChatGPT/Gemini/Perplexity "who's a good [service] near me" the same way they used to Google it. No markup, no consideration set.
-
AggregateRating/Reviewmarkup pushes trust signals directly into AI-generated answers, shortening the buyer's decision loop. - It's a jointly maintained open standard, not a growth hack — every new AI search surface (Google AI Mode, Bing Copilot, Perplexity) depends on it more over time, not less.
The schema types that matter for service businesses
Here's the practical set, roughly in priority order:
1. Organization / LocalBusiness / ProfessionalService
Your root entity. Everything else should reference it via @id.
2. Service — one entity per distinct offering
Don't bury five services in one paragraph. Model each as its own node:
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Emergency Plumbing Repair",
"provider": { "@id": "https://example.com/#organization" },
"areaServed": "Kyiv Oblast",
"url": "https://example.com/services/emergency-plumbing"
}
This lets an AI system match a narrow query ("emergency plumber Kyiv weekend") to a specific offer instead of your generic homepage.
3. AggregateRating and Review
Only from genuine, verifiable reviews — this is a hard requirement in Google's, not a nice-to-have. Self-authored testimonials marked up as Review are a policy violation and risk a manual action.
4. FAQPage
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [{
"@type": "Question",
"name": "Do you offer emergency appointments?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we offer same-day emergency appointments Monday through Saturday."
}
}]
}
Note: Google narrowed which sites get the visual FAQ rich snippet back in 2023, but this markup remains high-value for AI systems that lift Q&A pairs directly into generated answers — don't skip it because the SERP snippet eligibility changed.
5. BreadcrumbList
Helps both crawlers and LLM retrieval pipelines understand site hierarchy — cheap to implement, easy to automate from your routing config.
6. Person
For named practitioners — link credentials to the org entity. Strengthens E-E-A-T signals that increasingly factor into AI source-ranking.
SoftWin's practical implementation notes
A few things we've learned building and auditing this across client sites:
- Automate generation from your CMS/database, don't hand-author it. Hand-written JSON-LD drifts from the live page within weeks. If your services or reviews live in a CMS, generate the JSON-LD server-side from the same source of truth.
- Validate on every deploy. We run Google's Rich Results in CI for client sites — malformed JSON-LD is silently dropped by parsers, so a broken deploy can go unnoticed for months.
- Keep markup and visible content in sync. Schema that contradicts what's rendered on the page (different rating, different hours) is flagged as a spam signal, not just ignored.
-
Consider a supplementary
llms.txt/ clean FAQ section. Not a schema.org standard, but a growing convention that AI crawlers are early adopters of — pairs well with structured markup rather than replacing it.
Common mistakes
❌ Copy-pasted template schema with the wrong @type or stale address
❌ Service schema for offerings you no longer provide (guideline violation)
❌ Fabricated AggregateRating with no real reviews behind it (risks manual action)
❌ Shipping once at launch, never revisited as the business changes
❌ Never validating — malformed JSON-LD gets silently ignored by parsers
FAQ
Does structured data directly affect Google ranking?
Not as a direct ranking factor — it's an eligibility and extraction mechanism. It makes you eligible for rich results and dramatically easier for AI systems to parse and cite correctly.
Is a plugin (Yoast, Rank Math) enough?
For a single-service site, maybe. For multi-service, multi-location, or multi-practitioner businesses, you need custom JSON-LD generated from your actual data model — plugin defaults can't represent that structure accurately.
Does this actually help with ChatGPT/Perplexity, not just Google Search?
Yes — AI tools that browse the live web weight structured, typed data heavily because it's cheaper to trust than parsing prose, which directly affects whether they cite you accurately.
How do I keep markup from going stale?
Generate it programmatically from the same data source that powers your visible content (CMS, database, API) rather than hand-authoring a static script block.
Worth it for a small business without a dev team?
Arguably more so — it's one of the few high-leverage, low-cost ways for a small service business to compete for AI-mediated visibility against larger competitors.
Wrapping up
AI search is already routing real clients toward businesses that machines can parse cleanly — and away from the ones they can't. If you're building or maintaining sites for service businesses, a validated, CI-checked JSON-LD graph is one of the highest-leverage things you can ship this quarter.
At https://softwin.io/, we build this into every service-business site we ship — generated from source data, validated in CI, and revisited whenever the business changes. If you want a free technical audit of what AI search engines currently parse (and fail to parse) on your site, reach out — we're happy to share the raw findings.

Top comments (0)