Schema markup for AI search: what still matters

Which JSON-LD types actually help AI engines resolve your brand as an entity, with complete copy-pasteable code and an @id graph you can ship today.

Elminson De Oleo Baez · Founder, Spottlo · · 8 min read

The short answer

Schema markup does not make an AI engine cite you, but it does help engines resolve your brand as a distinct entity rather than a string of text, which is a prerequisite for being recommended by name. The types worth shipping are Organization, WebSite, SoftwareApplication or Product, Article, and BreadcrumbList, wired together into a single @id-linked graph. FAQPage lost its Google rich result for most sites in August 2023, but it is still parsed and it still makes your Q&A pairs cleanly liftable, so it is worth keeping.

Contents

Schema markup will not make ChatGPT recommend you. Nobody at OpenAI, Google or Perplexity has ever said structured data is a citation input, and you should be suspicious of any post that implies otherwise.

What schema does is make your brand resolvable as an entity. An engine deciding whether to name you in an answer has to first be confident that the "Spottlo" on your homepage, the "Spottlo" in a G2 listing, and the "Spottlo" in a Reddit thread are the same thing, with one canonical name, one logo, one product, one price. That reconciliation is what schema is for. It is plumbing, not magic, and pages that skip it lose arguments they never see.

This post is the JSON-LD I would actually ship, complete and copy-pasteable, plus an honest note on which types have quietly stopped earning their keep.

What structured data actually does for an AI engine

It converts facts that were only visible to a human into facts that survive parsing. Your pricing page might render "$39" inside a <span> in a flex container next to a "/mo" in another <span>, with the per-brand add-on in a tooltip. A human reads that instantly. A parser reads $39 and /mo and $19 and has to guess at the relationship.

Put it in an offers block and the relationship is explicit. That is the whole mechanism. There is no ranking bonus; there is just less ambiguity, and less ambiguity means fewer chances for an engine to get your facts wrong or to decide it is not confident enough to mention you.

The evidence that this matters is indirect but not weak. Google's AI Overviews are generated over the same index Googlebot builds, and that index is enriched by structured data. AI Overviews now appear on roughly 48% of tracked queries and 82% of B2B technology queries, so anything that improves how Google understands your entity has a large surface area. (Semrush's more conservative panel puts AI Overviews on 15.69% of keywords, which tells you the measured number depends heavily on the keyword set — but the direction is the same either way.)

Which schema types still matter in 2026?

Five carry real weight, one is a zombie worth keeping, and the rest are situational.

Type Still worth it? Why
Organization Yes, highest value The entity anchor. sameAs is how engines reconcile your brand across the web.
WebSite Yes Establishes the site as a named entity and declares the canonical name engines should use.
SoftwareApplication / Product Yes Makes price, category, platform and rating machine-readable. Feeds comparison-style answers.
Article / BlogPosting Yes Author, publish date, publisher, and a headline that maps cleanly to a citable passage. Freshness signals matter to AI retrieval.
BreadcrumbList Yes, cheap Gives the page a position in a hierarchy. Still renders in Google. Costs nothing.
FAQPage Keep it, expect nothing visual Lost its Google rich result for commercial sites in Aug 2023. Still parsed, still liftable. See below.
HowTo Deprecated by Google (2023) Rich result removed entirely. Only ship if you like the DOM structure.
Speakable Skip Never got traction outside a tiny news pilot.
Review / AggregateRating Yes, if honest Self-serving review markup on your own product gets ignored or penalized. Third-party ratings are fine.

The FAQPage situation, honestly

In August 2023 Google restricted the FAQ rich result to well-known government and health sites. If you run a SaaS, an agency, an ecommerce store, or basically any commercial site, your FAQPage markup produces zero visual treatment in Google results. That is a real deprecation and people who tell you otherwise have not looked at a SERP recently.

Ship it anyway. Three reasons:

  1. It is still parsed. The markup is valid schema.org, and it is present in the DOM for anything crawling the page, including AI search crawlers that are not Googlebot.
  2. It forces the right content shape. A FAQPage requires a literal question and a self-contained answer. That is precisely the chunk shape AI engines lift, which is the whole argument of content structure for AI citation.
  3. Bing and other engines never restricted it.

What you should not do is stuff twelve fake questions onto a page to farm markup. The answer text has to also exist as visible HTML on the page — that is a hard requirement of the spec, and shipping JSON-LD answers that do not appear on the page is a straightforward way to get your structured data ignored.

What does a complete entity graph look like?

One <script> tag, one @graph array, every node addressable by a stable @id, nodes referencing each other instead of repeating themselves. That is the pattern, and it is the single biggest upgrade over what most sites ship.

The anti-pattern is four separate script tags that each re-declare Organization with a slightly different name and a different logo URL. A parser cannot tell whether that is one entity or four, so it hedges, and hedging is how you end up unmentioned.

Here is the graph I would put in the <head> of every page on a SaaS site. The site-wide part never changes:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://spottlo.com/#organization",
      "name": "Spottlo",
      "legalName": "Spottlo",
      "url": "https://spottlo.com",
      "logo": {
        "@type": "ImageObject",
        "@id": "https://spottlo.com/#logo",
        "url": "https://spottlo.com/images/logo-512.png",
        "contentUrl": "https://spottlo.com/images/logo-512.png",
        "width": 512,
        "height": 512,
        "caption": "Spottlo"
      },
      "image": { "@id": "https://spottlo.com/#logo" },
      "description": "Spottlo tracks whether ChatGPT, Perplexity, Gemini and Google AI Overviews mention your brand when buyers ask questions in your category.",
      "foundingDate": "2026-01-15",
      "founder": {
        "@type": "Person",
        "@id": "https://spottlo.com/#founder",
        "name": "Elminson De Oleo Baez",
        "jobTitle": "Founder",
        "url": "https://spottlo.com/about"
      },
      "sameAs": [
        "https://www.linkedin.com/company/spottlo",
        "https://x.com/spottlo",
        "https://github.com/spottlo",
        "https://www.crunchbase.com/organization/spottlo"
      ],
      "contactPoint": {
        "@type": "ContactPoint",
        "contactType": "customer support",
        "email": "[email protected]",
        "availableLanguage": ["en"]
      }
    },
    {
      "@type": "WebSite",
      "@id": "https://spottlo.com/#website",
      "url": "https://spottlo.com",
      "name": "Spottlo",
      "description": "AI visibility tracking for ChatGPT, Perplexity, Gemini and Google AI Overviews.",
      "publisher": { "@id": "https://spottlo.com/#organization" },
      "inLanguage": "en-US"
    },
    {
      "@type": "SoftwareApplication",
      "@id": "https://spottlo.com/#software",
      "name": "Spottlo",
      "applicationCategory": "BusinessApplication",
      "applicationSubCategory": "AI Visibility Tracking",
      "operatingSystem": "Web",
      "url": "https://spottlo.com",
      "publisher": { "@id": "https://spottlo.com/#organization" },
      "featureList": [
        "Weekly scans across ChatGPT, Perplexity, Gemini and Google AI Overviews",
        "Brand mention and rank-position tracking",
        "Share of Voice against named competitors",
        "25 tracked prompts per brand"
      ],
      "offers": [
        {
          "@type": "Offer",
          "name": "Base plan",
          "price": "39.00",
          "priceCurrency": "USD",
          "availability": "https://schema.org/InStock",
          "url": "https://spottlo.com/pricing",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "39.00",
            "priceCurrency": "USD",
            "billingIncrement": 1,
            "unitCode": "MON"
          }
        },
        {
          "@type": "Offer",
          "name": "Additional brand",
          "price": "19.00",
          "priceCurrency": "USD",
          "availability": "https://schema.org/InStock",
          "url": "https://spottlo.com/pricing",
          "priceSpecification": {
            "@type": "UnitPriceSpecification",
            "price": "19.00",
            "priceCurrency": "USD",
            "referenceQuantity": {
              "@type": "QuantitativeValue",
              "value": 1,
              "unitText": "brand"
            },
            "unitCode": "MON"
          }
        }
      ]
    }
  ]
}
</script>

Note "@id": "https://spottlo.com/#organization". That fragment URI is a stable name for the entity. Every other node on every other page references it with { "@id": "https://spottlo.com/#organization" } and never restates the name, logo or description. Change the logo once, in one place.

Article and breadcrumbs, wired into the same graph

On a blog post, you append WebPage, BreadcrumbList, Article and FAQPage nodes to the same @graph, all pointing back at the site-wide nodes:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebPage",
      "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#webpage",
      "url": "https://spottlo.com/blog/schema-markup-for-ai-search",
      "name": "Schema markup for AI search: what still matters",
      "isPartOf": { "@id": "https://spottlo.com/#website" },
      "about": { "@id": "https://spottlo.com/#organization" },
      "primaryImageOfPage": {
        "@type": "ImageObject",
        "url": "https://spottlo.com/images/blog/schema-ai-search.png"
      },
      "datePublished": "2026-06-09T09:00:00-04:00",
      "dateModified": "2026-06-09T09:00:00-04:00",
      "breadcrumb": { "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#breadcrumb" },
      "inLanguage": "en-US"
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#breadcrumb",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://spottlo.com" },
        { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://spottlo.com/blog" },
        { "@type": "ListItem", "position": 3, "name": "Getting Cited", "item": "https://spottlo.com/blog/category/getting-cited" },
        { "@type": "ListItem", "position": 4, "name": "Schema markup for AI search" }
      ]
    },
    {
      "@type": "Article",
      "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#article",
      "isPartOf": { "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#webpage" },
      "mainEntityOfPage": { "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#webpage" },
      "headline": "Schema markup for AI search: what still matters",
      "description": "Which JSON-LD types actually help AI engines resolve your brand as an entity, with complete copy-pasteable code.",
      "datePublished": "2026-06-09T09:00:00-04:00",
      "dateModified": "2026-06-09T09:00:00-04:00",
      "author": { "@id": "https://spottlo.com/#founder" },
      "publisher": { "@id": "https://spottlo.com/#organization" },
      "articleSection": "Getting Cited",
      "keywords": ["schema markup", "JSON-LD", "AI search", "entity SEO"],
      "wordCount": 1780,
      "inLanguage": "en-US"
    },
    {
      "@type": "FAQPage",
      "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#faq",
      "isPartOf": { "@id": "https://spottlo.com/blog/schema-markup-for-ai-search#webpage" },
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Does schema markup help you get cited by ChatGPT or Perplexity?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Not directly. No AI engine has said structured data is a ranking or citation input. What schema does is disambiguate your brand as an entity and make key facts machine-readable in a form that survives HTML parsing."
          }
        },
        {
          "@type": "Question",
          "name": "Is FAQPage schema dead?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "It is dead as a Google rich result for commercial sites, restricted in August 2023 to government and health sites. The markup is still valid, still parsed, and still produces clean question-answer pairs, so it remains worth shipping."
          }
        }
      ]
    }
  ]
}
</script>

headline, datePublished and dateModified are load-bearing. AI retrieval systems weight recency, and a page with no date is a page an engine cannot confidently call current. Set dateModified when you actually change the content, not on every deploy — a site where every page was "modified today" is a site whose dates mean nothing.

Generating it, not hand-writing it

Hand-maintained JSON-LD rots. In a Laravel app, build the graph once and reference it:

<?php
// app/Support/Schema.php

namespace App\Support;

class Schema
{
    private const ORG = 'https://spottlo.com/#organization';
    private const SITE = 'https://spottlo.com/#website';

    /** Site-wide nodes. Rendered in the layout on every page. */
    public static function siteGraph(): array
    {
        return [
            [
                '@type' => 'Organization',
                '@id' => self::ORG,
                'name' => 'Spottlo',
                'url' => 'https://spottlo.com',
                'logo' => [
                    '@type' => 'ImageObject',
                    'url' => 'https://spottlo.com/images/logo-512.png',
                    'width' => 512,
                    'height' => 512,
                ],
                'sameAs' => [
                    'https://www.linkedin.com/company/spottlo',
                    'https://x.com/spottlo',
                    'https://github.com/spottlo',
                ],
            ],
            [
                '@type' => 'WebSite',
                '@id' => self::SITE,
                'url' => 'https://spottlo.com',
                'name' => 'Spottlo',
                'publisher' => ['@id' => self::ORG],
                'inLanguage' => 'en-US',
            ],
        ];
    }

    /** Per-post nodes, appended to the site graph. */
    public static function article(Post $post): array
    {
        $url = route('blog.show', $post->slug);

        return [
            [
                '@type' => 'Article',
                '@id' => $url.'#article',
                'mainEntityOfPage' => $url,
                'headline' => $post->title,
                'description' => $post->description,
                'datePublished' => $post->published_at->toAtomString(),
                'dateModified' => $post->updated_at->toAtomString(),
                'author' => ['@id' => 'https://spottlo.com/#founder'],
                'publisher' => ['@id' => self::ORG],
                'articleSection' => $post->category,
                'inLanguage' => 'en-US',
            ],
            [
                '@type' => 'FAQPage',
                '@id' => $url.'#faq',
                'mainEntity' => collect($post->faqs)->map(fn ($f) => [
                    '@type' => 'Question',
                    'name' => $f['q'],
                    'acceptedAnswer' => ['@type' => 'Answer', 'text' => $f['a']],
                ])->all(),
            ],
        ];
    }

    public static function render(array $nodes): string
    {
        return '<script type="application/ld+json">'
            .json_encode(
                ['@context' => 'https://schema.org', '@graph' => $nodes],
                JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
            )
            .'</script>';
    }
}

The FAQ nodes come from the same front-matter field that renders the visible FAQ section on the page, which means the markup and the HTML cannot drift apart. That is the point.

How do you know it is working?

Validate the syntax, then measure the outcome. They are different questions and people confuse them constantly.

For syntax, three tools, in order of usefulness:

Tool What it checks URL
Schema Markup Validator Pure schema.org validity, no Google opinions validator.schema.org
Google Rich Results Test Whether Google will render a rich result (it mostly won't, for FAQ) search.google.com/test/rich-results
Search Console → Enhancements Errors on pages Google has already crawled, at scale search.google.com/search-console

For the outcome, there is no schema report that tells you whether an AI engine now recommends you. You have to ask the engines. That is what Spottlo does — it runs your buyer questions through ChatGPT, Perplexity, Gemini and Google AI Overviews weekly and reports whether your brand got named, at what position, and how often relative to competitors. Ship the graph, then watch whether mention rate moves over the following six to eight weeks. If it does not, the problem was never the markup.

What to do next

  1. Consolidate to one @graph. Grep your templates for application/ld+json. If you have more than one script tag on a page, merge them and give every node a stable @id.
  2. Fill in sameAs properly. LinkedIn, X, GitHub, Crunchbase, G2, Wikidata if you have an item. This is the property that does the entity-reconciliation work, and most sites leave it empty or list two socials.
  3. Add offers to your product page with real prices. If an engine is going to answer "how much does X cost," give it an unambiguous number instead of a <span>.
  4. Keep FAQPage, but make the answers visible in the HTML. Same text in both places, generated from one source.
  5. Establish a baseline before you ship, so you can tell whether it did anything. Run a free AI visibility report today, ship the graph, re-check in a month. Then read entity SEO for AI search, because schema is only half of entity resolution — the other half is being described consistently on sites you do not control.

Frequently asked questions

Does schema markup help you get cited by ChatGPT or Perplexity? +

Not directly. No AI engine has said structured data is a ranking or citation input. What schema does is disambiguate your brand as an entity, tie together your name, logo, domain, socials and product, and make key facts machine-readable in a form that survives HTML parsing. Engines that ground answers in a retrieval index benefit from that clarity, even if they never read the JSON-LD blob verbatim.

Is FAQPage schema dead? +

It is dead as a Google rich result for most sites. In August 2023 Google restricted FAQ rich results to well-known government and health sites, so a normal commercial page gets no visual treatment from it. The markup is still valid, still parsed, and still gives you clean question-answer pairs in the DOM, which is the shape AI engines lift. Keep it, just do not expect blue-link real estate from it.

What is an @id entity graph in JSON-LD? +

It is a set of schema nodes that reference each other by stable URIs instead of repeating themselves. You define your Organization once at https://example.com/#organization, then every Article, Product and WebPage points at that @id as its publisher or author. Parsers reconcile the graph into one entity with many facts instead of dozens of disconnected, slightly-inconsistent copies.

How many schema types should one page have? +

One graph, several nodes. A typical article page carries Organization, WebSite, WebPage, BreadcrumbList, Article and optionally FAQPage in a single @graph array. What you should not do is ship five separate script tags that each re-declare the organization with slightly different values.

Do I need sameAs links in Organization schema? +

Yes, and it is the single highest-value property in the whole file. sameAs points at the other places your entity is described, such as your LinkedIn, Crunchbase, GitHub, X profile and Wikidata item. That is how a parser confirms that the Spottlo on your site is the same Spottlo it saw in a G2 listing, which is exactly the reconciliation problem an AI engine has to solve before it can recommend you by name.

Should I use Product or SoftwareApplication for a SaaS? +

SoftwareApplication, with an offers block. It is the more specific type, it carries applicationCategory and operatingSystem, and it accepts the same offers and aggregateRating properties Product does. If you sell physical goods too, use both on the appropriate pages rather than forcing everything into one type.

schema json-ld structured-data entity-seo

Keep reading

Find out what AI says about you — free

Enter your domain. We'll run it through ChatGPT, Perplexity, Gemini and Google AI Overviews and show you exactly where you land. No signup, no card.