Guides

Structured data

Structured data for AI search: what helps and what doesn't

What Google and Microsoft say about schema.org markup in AI search, which types are worth adding, and a JSON-LD example you can adapt and test.

Structured data is schema.org markup that describes a page in a form software can read without guessing: this is an article, this company published it, it was updated on this date. Advice about AI search often presents it as the key to being cited. The search engines say something more modest, and it is worth knowing exactly what before spending a week on markup.

What the search engines say

Google: not required, still useful. Google’s guide to its generative AI features says “Structured data isn’t required for generative AI search, and there’s no special schema.org markup you need to add.” The same guide recommends keeping it “as part of your overall SEO strategy”, because it makes pages eligible for rich results. Google’s page on AI features lists “making sure your structured data matches the visible text on the page” among its best practices.

Microsoft: used by its models. At SMX Munich in March 2025, Fabrice Canel of Microsoft Bing said that schema markup helps Microsoft’s large language models understand content, which is relevant for Bing and Copilot. That is a statement on stage, not documentation, but it is the clearest one any AI search operator has made.

OpenAI, Anthropic and Perplexity have not said whether their crawlers read structured data.

So structured data is not a ranking switch for AI answers. It is a precise, cheap description of facts your page already states. That helps any system that reads it, and it keeps you eligible for the rich results that remain in Google Search.

Rules that apply to every type

These come from Google’s general structured data guidelines, and they are the rules most often broken:

  • Mark up only what the page shows. “Don’t mark up content that is not visible to readers of the page.” If the markup names an author, the page names the same author.
  • Do not use it to mislead. Markup that misdescribes the page can lead to a manual action, which removes the page’s eligibility for rich results. Google says this does not affect how the page ranks in web search.
  • Valid is not guaranteed. Correct markup makes a page eligible for a rich result; it does not guarantee one.

Put it in the HTML your server sends

Google recommends JSON-LD, a <script type="application/ld+json"> block, as the format that is easiest to get right. It also reads JSON-LD that JavaScript adds to the page after load.

AI crawlers mostly do not run JavaScript, as covered in Do AI crawlers run JavaScript?. Markup injected by a tag manager or a client-side component is invisible to them. Render the JSON-LD on the server, in the initial HTML.

Types worth adding

Start with the ones that describe who you are and what each page is. Add more only when a type matches the page.

Type Use it for Key properties
Organization The company behind the site, usually on the home page name, url, logo, sameAs
WebSite The site as a whole name, url, publisher
Article, BlogPosting, TechArticle Editorial pages and documentation headline, author, publisher, datePublished, dateModified
BreadcrumbList Where a page sits in the site itemListElement with position, name, item
Product A product page name, offers, aggregateRating where you show one
LocalBusiness A physical business address, openingHoursSpecification, telephone
SoftwareApplication An app or SaaS product name, applicationCategory, offers

A few details from Google’s documentation:

  • sameAs connects your organization to its other profiles, such as a LinkedIn page, a Wikipedia article or a review site. It is how a system confirms that your company and the one in its other sources are the same.
  • A logo must be at least 112 by 112 pixels, at a URL that can be crawled and indexed.
  • author should be a Person or an Organization, with the name alone in name. Add a url to a page about the author. List each author separately.
  • Dates use ISO 8601, ideally with a time zone, and must match the dates shown on the page. dateModified is the date the content last changed, not the date the page was rebuilt.

What not to bother with

Google no longer shows FAQ rich results. It limited them to government and health sites in August 2023 and stopped showing them in Search on May 7, 2026. HowTo rich results went in 2023, and several other types, such as course info, estimated salary and vehicle listings, were retired in 2025. Existing FAQPage markup does no harm, and other systems may still read it, but do not add it expecting a rich result.

An example you can adapt

One block per page, using @graph so the entities can refer to each other by @id. This is the shape of an article page; the home page would also carry the full Organization.

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Acme Analytics",
      "url": "https://example.com/",
      "logo": "https://example.com/logo-512.png",
      "sameAs": [
        "https://www.linkedin.com/company/acme-analytics",
        "https://github.com/acme-analytics"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "name": "Acme Analytics",
      "url": "https://example.com/",
      "publisher": { "@id": "https://example.com/#organization" }
    },
    {
      "@type": "Article",
      "@id": "https://example.com/blog/cookieless-analytics#article",
      "headline": "How cookieless analytics counts visitors",
      "url": "https://example.com/blog/cookieless-analytics",
      "datePublished": "2026-09-14T09:00:00+02:00",
      "dateModified": "2026-10-02T16:30:00+02:00",
      "author": {
        "@type": "Person",
        "name": "Maria Nowak",
        "url": "https://example.com/team/maria-nowak"
      },
      "publisher": { "@id": "https://example.com/#organization" },
      "isPartOf": { "@id": "https://example.com/#website" }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
        { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
        { "@type": "ListItem", "position": 3, "name": "How cookieless analytics counts visitors" }
      ]
    }
  ]
}

Every value here should come from the same data that renders the page: the headline from the title, the dates from the record, the author from the byline. Markup typed by hand drifts away from the page.

Rendering it safely

JSON-LD sits inside a <script> element, so a title containing </script> can break out of it. Escape < when you serialise the data:

# Rails view
<script type="application/ld+json"><%= raw json_escape(data.to_json) %></script>
// Next.js Server Component
<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
    __html: JSON.stringify(data).replace(/</g, "\\u003c"),
  }}
/>

On WordPress, an SEO plugin such as Yoast or Rank Math writes the markup on the server. Check what it outputs rather than adding a second set by hand.

Check it

# Is the markup in the HTML the server sends?
curl -sS https://example.com/blog/cookieless-analytics | grep -c 'application/ld+json'

0 means the markup is missing or added by JavaScript. Then validate it:

A CrawlWise scan parses the JSON-LD on each audited page and checks that it names an Organization or WebSite, describes the page with a specific type, includes breadcrumbs away from the home page, gives articles an author and a publisher, and carries valid dates. It reads the page after rendering, so compare with the curl test above to make sure the markup does not depend on JavaScript.

Sources

How CrawlWise checks this

Scan your page

Last updated .