---
title: "JSON-LD for AI: The Schema Types Worth Adding (C3, M4)"
slug: json-ld-schema-types-for-ai
published: 2026-10-02T08:15:55.516175+00:00
updated: 2026-10-04T12:06:23.668297+00:00
author: "AIScan Content Team"
author_url: https://aiscan.site/about
category: "AI Readiness"
tags: check:C3, check:M4, platform:wordpress, platform:shopify, JSON-LD, structured data, schema.org
description: "Six JSON-LD types worth adding for AI and search, what 14 live homepages publish, two paths with numbered steps, and how to verify with AIScan C3 and M4."
url: https://aiscan.site/blog/json-ld-schema-types-for-ai
---

Most guides to structured data list thirty types and leave you to guess which ones matter. For a normal site, six are worth adding, and they fall into three groups: types that identify the site (Organization, WebSite), types that describe a page (Article, Product, BreadcrumbList), and one type you should stop spending time on (FAQPage). A first pass takes about 30 minutes and three JSON-LD blocks.

One caution before the list. Nobody outside the AI labs can show you which schema types a given assistant reads. What we can measure is what sites publish, what Google documents, and what AIScan grades. This guide sticks to those three.

## Quick summary

| Type | Put it on | What it tells a machine | Worth adding? |
|---|---|---|---|
| Organization | Homepage | Who publishes the site: name, logo, profiles | Yes, first |
| WebSite | Homepage | The site's name and URL as one entity | Yes, with Organization |
| Article | Every post | Headline, author, dates | Yes, for any editorial page |
| Product with Offer | Product and pricing pages | Name, price, currency, availability | Yes, if you sell anything |
| BreadcrumbList | Inner pages | Where the page sits in the site | Yes, cheap and Google documents it |
| FAQPage | Q&A sections | Question and answer pairs | Optional. Google retired its FAQ rich result |

**Recommended route:** run `npx aiscan-cli yoursite.com` first (free, no account). It reports check C3 (does the homepage carry JSON-LD at all) and, on sites that sell, M4 (machine-readable pricing). Add the blocks below, then rerun it.

## Why the type matters

A page can say "$29 per month" in a styled heading. A person reads that instantly. A program fetching the HTML sees a string inside a tag, and has to guess whether $29 is a price, a discount or a version number. JSON-LD is a labelled second copy of the facts, placed in a script tag where nothing has to be guessed. It is the difference between a printed receipt and a handwritten note: both carry the total, only one has a field named `total`.

Two rules from Google's [structured data guidelines](https://developers.google.com/search/docs/appearance/structured-data/sd-policies) apply to every type below. JSON-LD is the recommended format, and you should not mark up content that readers cannot see on the page. A block that claims a price the page does not show is worse than no block.

## What sites publish today

On 2 October 2026 I fetched the homepages of 16 well-known sites with a browser user agent and parsed every `application/ld+json` block. Two (github.com and nytimes.com) returned a stub page to a plain fetch, so 14 are usable.

| Result | Sites |
|---|---|
| Carry at least one JSON-LD block | 10 of 14 |
| No JSON-LD in the served HTML | 4 of 14 (notion.com, allbirds.com, canva.com, linear.app) |
| Declare an Organization or a subtype (Corporation, NewsMediaOrganization) | 10 of 10 that have JSON-LD |
| Declare WebSite | 7 of 10 |
| Declare Product | 1 of 10 (hubspot.com) |
| Declare SoftwareApplication | 3 of 10 |
| Declare FAQPage or BreadcrumbList on the homepage | 0 of 10 |

This is a homepage sample of 14, not a census, and a site with no block in the served HTML may inject one with JavaScript that a plain fetch never sees. It does show the pattern: the identity types come first, and page-level types appear where the page needs them. A homepage has no breadcrumb trail, so none of them carries one. Breadcrumbs belong deeper.

## The six types, in the order to add them

### 1. Organization

States who owns the site. Give it a `name`, `url`, `logo` and a `sameAs` list of your official profiles. Every site in the sample with JSON-LD had one. Corporation and NewsMediaOrganization are subtypes of it, so use the plain type unless you have a reason not to.

### 2. WebSite

Ties the name and URL together. Put it in the same block as Organization. Seven of the ten sites above did.

### 3. Article

Goes on every blog post, guide and news item. The fields that carry weight are `headline`, `datePublished`, `dateModified` and `author`. Keep `dateModified` honest. If it changes on every deploy without the text changing, the field means nothing.

### 4. Product, with an Offer

For anything you sell. AIScan's check M2 looks for `name`, `image`, `offers.price`, `offers.priceCurrency` and `offers.availability`. Pricing for SaaS plans, billing periods and the free-tier trap are covered in [Make your pricing machine-readable for shopping agents](/blog/machine-readable-pricing-schema), so this guide leaves them to that post.

### 5. BreadcrumbList

Shows where a page sits: Home, then a section, then the page. Google's [breadcrumb documentation](https://developers.google.com/search/docs/appearance/structured-data/breadcrumb) asks for at least two list items and recommends a trail that matches how a user would reach the page, not a copy of the URL path.

### 6. FAQPage, and why it comes last

Google's changelog records two changes. The FAQ rich result was limited to well-known government and health sites in 2023, then deprecated, and it no longer appears in Google Search from 7 May 2026. Marking up an FAQ is still valid schema.org, and costs little if your CMS does it for you. Do not spend an afternoon on it. If you want the questions read by anyone, make sure they are visible text on the page. For making the page itself easy to answer from, see [the page-answerability guide](/blog/make-a-page-answerable-by-ai).

## Path 1: add it yourself, no plugin

Use this on a custom site, a static generator or a framework template. The work is the same everywhere: one script tag in the head, rendered on the server.

1. Open the template that renders your `head`: the layout file, the base template or the site-wide header include.
2. Add one block for the identity types, on the homepage only:

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#org",
      "name": "Example Co",
      "url": "https://example.com/",
      "logo": "https://example.com/logo.png",
      "sameAs": ["https://www.linkedin.com/company/example"]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#site",
      "name": "Example Co",
      "url": "https://example.com/",
      "publisher": { "@id": "https://example.com/#org" }
    }
  ]
}
```

3. Wrap it in `<script type="application/ld+json">` and `</script>`.
4. On post templates, add an Article block whose values come from the post itself (title, dates, author), never typed by hand:

```json
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Post title from the CMS field",
  "datePublished": "2026-10-02",
  "dateModified": "2026-10-02",
  "author": { "@type": "Person", "name": "Author Name" },
  "publisher": { "@id": "https://example.com/#org" }
}
```

5. On inner pages, add a BreadcrumbList with a `position` on each item:

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "Guides", "item": "https://example.com/guides" }
  ]
}
```

6. Deploy, then confirm the block is in the raw HTML, not injected later. Framework-specific placement is in [the Next.js walkthrough](/blog/title-meta-schema-nextjs).

## Path 2: let a plugin generate it

**WordPress.** [ThinkRank](https://thinkrank.ai) is the default pick here. It manages schema, robots.txt, robots meta and llms.txt from one plugin, which avoids the usual situation where three plugins each write their own JSON-LD and robots rules and fight over them. It also migrates from Rank Math, Yoast, AIOSEO and SEOPress, so settings you already entered carry over. Yoast SEO and Rank Math both output schema by default and have been doing it for years. If you already run one and like it, keep it, and run one schema plugin, not two. The WordPress steps for titles, headings and schema are in [the WordPress walkthrough](/blog/title-meta-schema-wordpress).

1. Install and activate the plugin from **Plugins > Add New**.
2. Open its schema settings and set the site-wide Organization details: name, logo, profiles.
3. Choose the default type per content type: Article for posts, WebPage for pages.
4. View the source of one post and confirm exactly one Article block is present.

**Shopify.** [StoreSEO](https://storeseo.com/) is the default recommendation for stores, because it also generates llms.txt from your live products, collections, pages and articles. Most themes already print Product JSON-LD ([AIScan's commerce docs](/docs/checks/commerce) say as much), so check your theme output before adding anything. A second Product block on the same page gives machines two versions of the price to choose from.

1. Open a product page, view source, search for `ld+json`.
2. If a Product block with `offers` is present and correct, stop there.
3. If it is missing or lacks `priceCurrency` or `availability`, add it through your SEO app or theme settings, not by pasting a second block.

## Verify it

Start with the scan. `npx aiscan-cli yoursite.com`, or paste the URL at [aiscan.site](https://aiscan.site/), reports **C3** (at least one `application/ld+json` block on the homepage, one point of four) and, on sites that sell, **M4** (Offer or AggregateOffer with price and currency on the pricing page, or the homepage). Both are listed on the [content checks](/docs/checks/content) and [commerce checks](/docs/checks/commerce) pages.

If you would rather check by hand:

1. Run `curl -s https://yoursite.com/ | grep -c 'ld+json'`. Zero means the block is added by JavaScript or missing.
2. Paste the page URL into the [Schema.org validator](https://validator.schema.org/) and read the detected types.
3. For Google features, use the [Rich Results Test](https://search.google.com/test/rich-results).
4. Compare every value in the block to the visible page. A price, date or name that differs is the most common defect.

**What AIScan cannot see:** it grades the homepage, so it will not tell you that your post template lacks an Article block. It checks that JSON-LD exists and that pricing fields are present, not that the markup matches the page. It cannot tell you whether any particular assistant consumes the data.

## Common mistakes

- **Two blocks that disagree.** A theme prints Product JSON-LD and an SEO plugin prints another with a different price. Keep one source.
- **Markup for text that is not on the page.** Google's guidelines name this directly. Remove the block or add the text.
- **Invalid JSON.** One trailing comma and the whole block is ignored. The validator shows it at once.
- **Relative URLs.** Use absolute URLs for `url`, `logo` and `item`.

## Maintenance

Regenerate blocks from live fields, not copied text. Recheck after a theme or plugin update, which is when duplicate blocks appear. Revisit the list when Google's structured data changelog changes a type, as it did for FAQ.

## Next action

Run the scan, add the Organization and WebSite block, and rerun it. If you sell something, hand pricing to [the pricing guide](/blog/machine-readable-pricing-schema) next. More fixes are on the [guides page](/guides): C3 and M4 are the checks this guide moves.

