AI Search & SEO

Schema markup for AI search, done properly

Which schema types matter for AI search, how @id graph linking beats isolated blocks, and the mistakes that quietly make your structured data useless.

Published 8 min read By DoubleTime AI

What is schema markup for AI search?

Schema markup for AI search is structured data in JSON-LD that states, in machine-readable form, what your business is, what each page is about, and how those things relate — so an AI engine can resolve your entities instead of inferring them from prose. The types that carry the most weight are Organization, WebSite, WebPage, Article, Service, BreadcrumbList, FAQPage and HowTo. The single biggest improvement most sites can make is linking those types into one @graph with stable @id values rather than shipping them as disconnected blocks.

Schema markup has been an SEO chore for a decade, mostly justified by rich results — stars in the search listing, recipe cards, FAQ dropdowns. That justification has been eroding. Google removed HowTo rich results in September 2023 and finished deprecating FAQ rich results in June 2026, and its supported-types gallery no longer lists either.

The chore survived the justification, and the reason is worth understanding. Rich results were always a side effect. The real function of structured data is disambiguation: telling a machine that "Rivet" is an HVAC contractor in Portland and not a fastener, a font, or a bank. That function got more valuable when the consumer of the markup became a language model synthesizing an answer rather than a template rendering a star rating.

The types that actually earn their place

You do not need forty schema types. You need seven or eight, applied consistently.

TypeWhere it goesWhat it establishes
OrganizationSitewide, defined onceWho the business is — name, URL, logo, contact points, social profiles, address
WebSiteSitewideThe site as an entity, and its publisher
WebPageEvery pageThis URL as a thing, its title, its about, its primaryImageOfPage
ArticleGuides, blog posts, newsAuthorship, publish and update dates, headline, publisher
ServiceService pagesWhat you sell, to whom, in what area, by whom
BreadcrumbListEvery page below rootWhere this page sits in the site's hierarchy
FAQPagePages with real Q&AQuestion/answer pairs as discrete, extractable units
HowToGenuinely sequential instructionsOrdered steps with tools, supplies and time

Two of those need a caveat. FAQPage and HowTo no longer generate rich results in Google Search — Google's changelog records HowTo removal on 14 September 2023 and the completion of FAQ removal on 15 June 2026. They are still valid schema.org vocabulary, and they still do the thing that matters here: they carve a page into labeled, self-contained question/answer or step units, which is exactly the shape an answer engine wants to lift. Keep them. Just stop promising anyone a snippet.

HowTo also has a discipline problem. It should only be used when your ## headings are literally sequential steps that a person performs in order. Applying it to a list of considerations is markup that lies about the page, which is worse than no markup.

Why @id linking beats isolated blocks

Most sites ship structured data as a set of unrelated islands: an Organization block in the footer template, an Article block in the post template, a BreadcrumbList somewhere else. Each one validates. Together they describe nothing coherent — a parser sees three unlinked objects and has to guess whether the Article's publisher is the same organization named in the footer.

JSON-LD solves this with two features. @graph lets you put multiple entities in one document. @id gives each entity a stable, globally unique identifier — in practice, a URI on your own domain with a fragment, like https://example.com/#organization. Once an entity has an @id, every other entity can reference it by that identifier instead of restating it.

The practical result: your Article's publisher is not a duplicate Organization object with possibly-different values. It is a pointer to the Organization, defined once. Change the logo in one place and the whole graph updates. More importantly, a machine reading any single page can traverse from the page, to the article, to the publisher, to the service you sell, without inference.

Pick a convention and never change it. Fragments on the canonical URL work well:

The identifiers do not need to resolve to anything. They need to be stable and unique.

A complete, valid example

This is one <script type="application/ld+json"> block for a single guide page. It defines the organization, the site, the page, the article and the breadcrumb trail, and links all five.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Rivet & Co.",
      "url": "https://example.com/",
      "logo": {
        "@type": "ImageObject",
        "@id": "https://example.com/#logo",
        "url": "https://example.com/img/logo.png",
        "width": 512,
        "height": 512
      },
      "areaServed": {
        "@type": "AdministrativeArea",
        "name": "Portland metropolitan area"
      },
      "contactPoint": {
        "@type": "ContactPoint",
        "contactType": "customer service",
        "email": "hello@example.com",
        "availableLanguage": "English"
      },
      "sameAs": [
        "https://www.linkedin.com/company/example",
        "https://www.youtube.com/@example"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com/",
      "name": "Rivet & Co.",
      "publisher": { "@id": "https://example.com/#organization" },
      "inLanguage": "en-US"
    },
    {
      "@type": "WebPage",
      "@id": "https://example.com/guides/rtu-replacement/#webpage",
      "url": "https://example.com/guides/rtu-replacement/",
      "name": "When to replace a rooftop HVAC unit",
      "isPartOf": { "@id": "https://example.com/#website" },
      "about": { "@id": "https://example.com/#organization" },
      "breadcrumb": { "@id": "https://example.com/guides/rtu-replacement/#breadcrumb" },
      "inLanguage": "en-US"
    },
    {
      "@type": "Article",
      "@id": "https://example.com/guides/rtu-replacement/#article",
      "isPartOf": { "@id": "https://example.com/guides/rtu-replacement/#webpage" },
      "mainEntityOfPage": { "@id": "https://example.com/guides/rtu-replacement/#webpage" },
      "headline": "When to replace a rooftop HVAC unit",
      "description": "How to decide between repairing and replacing a commercial RTU.",
      "datePublished": "2026-07-22T09:00:00-07:00",
      "dateModified": "2026-07-22T09:00:00-07:00",
      "author": {
        "@type": "Person",
        "name": "Dana Ruiz",
        "url": "https://example.com/team/dana-ruiz/"
      },
      "publisher": { "@id": "https://example.com/#organization" },
      "inLanguage": "en-US"
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://example.com/guides/rtu-replacement/#breadcrumb",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://example.com/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Guides",
          "item": "https://example.com/guides/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "When to replace a rooftop HVAC unit"
        }
      ]
    }
  ]
}
</script>

Note the last breadcrumb item has no item property. That is correct — the current page is its own position and does not need to link to itself.

Mistakes that quietly waste the work

Markup that describes something the page doesn't contain. FAQ schema for questions that appear nowhere in the visible content, review markup for reviews that aren't shown, Service schema for services you don't list. This violates Google's structured data guidelines and, separately, gives an answer engine grounds to distrust everything else you assert.

Duplicating Organization on every page with drifting values. Three templates each emitting their own Organization block, with the phone number updated in two of them, produces a genuinely ambiguous entity. Define it once, reference it by @id.

Markup that only exists after JavaScript runs. Some crawlers execute JavaScript; several AI crawlers do not, or do so inconsistently. Server-render your JSON-LD. Verify by fetching the raw HTML — curl the URL and search the response for application/ld+json. If it isn't there, assume half your audience never sees it.

Wrong @type for the thing. LocalBusiness when there is no physical location customers visit. Product for a service. Article on a category page. The vocabulary is large and specific; using the closest correct type matters more than using the most impressive one.

Dates that never change. dateModified that is set once at publish and then frozen, or worse, bumped automatically on every deploy so every page claims to have been updated this morning. Both are noise. Update it when the content actually changes.

Validating and stopping. A validator confirms syntax and eligibility. It does not confirm your graph is connected, your @id values are consistent across templates, or that the block survives to production. Check a real production URL, not a staging preview.

Structured data is one input among several. It will not compensate for a page that answers no question, and it is not a substitute for the content structure work described in answer engine optimization. What it does is remove ambiguity — and ambiguity is the thing that gets you left out of an answer in favor of a competitor the engine is more certain about.

Frequently asked questions

It helps by removing the need for inference. An AI engine assembling an answer has to determine what a business is, what a page covers, who wrote it, and when — and structured data states all of that explicitly instead of leaving it to be extracted from prose. There is no published ranking factor to point at, and no engine has committed to weighting schema in retrieval. What is observable is that ambiguity costs you: when an engine is uncertain which entity a site refers to, it tends to name the source it is more confident about. Schema is how you stop being the uncertain one.

Which schema types should I implement first?

Organization first, defined once sitewide, because every other type references it. Then WebSite and WebPage, which establish the site and each URL as entities. Then Article on any editorial content, since it carries authorship and dates that engines use to judge freshness and provenance. Then BreadcrumbList, which is cheap and communicates site hierarchy. Service pages get Service. FAQPage and HowTo come last and only where the page genuinely contains question-answer pairs or ordered steps. Implementing four types correctly and consistently beats implementing twelve with drifting values.

Is FAQ schema still worth adding?

Yes, but not for the reason it used to be. Google's changelog records the completion of FAQ rich result removal on 15 June 2026, so the visible search feature is gone and FAQPage no longer appears in Google's supported structured data gallery. The markup itself is still valid schema.org vocabulary, and it still does something useful: it partitions a page into discrete, labeled question-and-answer units, which is precisely the granularity an answer engine wants to extract. Add it where you have real FAQs. Do not add it to pages that don't, and do not expect a snippet.

What is @id in JSON-LD and why does it matter?

@id assigns a stable, unique identifier to an entity in your structured data, typically a URI on your own domain with a fragment such as https://example.com/#organization. Once an entity has one, every other block can reference it by that identifier instead of restating its properties. That turns a set of disconnected blocks into a connected graph a parser can traverse — from a page, to its article, to the publisher, to the services that publisher offers. It also eliminates the drift that happens when the same organization is described slightly differently in three templates.

Can schema markup hurt my site?

Incorrect schema can, in two ways. Markup that describes content not present on the page violates Google's structured data guidelines and can trigger a manual action removing rich result eligibility. Separately, an engine that catches a contradiction between your markup and your visible content has a reason to discount the rest of your assertions — which is the more expensive outcome in AI search, where trust in the source is the whole game. Syntactically broken JSON-LD is usually harmless; it is simply ignored. Dishonest JSON-LD is the problem.

Want this built for you?

The audit is free and takes 30 minutes. We map where your hours actually leak, price the leak in dollars, and tell you what we would automate first — whether or not you hire us.

Book a free audit ↗

Sources

  1. Structured data markup that Google Search supports — Google Search Central
  2. Latest documentation updates — Google Search Central
  3. JSON-LD 1.1 — W3C
  4. Schema.org — Schema.org