Overview

The baseline set (WebSite, Organization, BreadcrumbList, Article, Person) is on structured-data, along with the list of retired rich results and the validation steps. This page holds the field-level detail for the next tier, where Google still shows a feature when the page genuinely is that thing. Every example is subject to one rule: markup must match what a human sees on the page.

Product: price, availability, and ratings from the visible page

Google’s product snippet requires name plus at least one of offers, review, or aggregateRating. Merchant listings carry extra commerce requirements and a separate Search Console report.

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Mechanical Keyboard",
  "image": "https://example.com/keyboard.jpg",
  "sku": "KB-001",
  "brand": { "@type": "Brand", "name": "Example Brand" },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/keyboard",
    "priceCurrency": "USD",
    "price": "149.00",
    "availability": "https://schema.org/InStock"
  },
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.7", "reviewCount": "127" }
}
  • The price must match the price on the page.
  • aggregateRating needs real reviews users can see on the same page; ratings pulled from elsewhere violate the guidelines.
  • Use Product on single-product pages only; category pages use ItemList.
  • For variants, use ProductGroup with hasVariant; see ecommerce-seo.

Course: list markup needs at least three courses

Course markup supports Google’s course list rich result, which needs at least three courses marked up and carousel (ItemList) markup on a summary page. The separate Course Info result was retired in June 2025. Required on each Course: name, description (display limit 60 characters), and provider.

{
  "@context": "https://schema.org",
  "@type": "Course",
  "name": "Intro to Postgres",
  "description": "A 4-week intro to Postgres fundamentals.",
  "provider": { "@type": "Organization", "name": "Example University", "url": "https://example.com" }
}

Mark up real courses only, not a blog series without enrollment or completion.

VideoObject: required fields and the watch-page rule

Google requires name, thumbnailUrl, and uploadDate. description is recommended, not required, along with contentUrl (preferred) or embedUrl, duration, and creator. The markup belongs on a page where users can watch the video.

{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "Postgres Backup Tutorial",
  "description": "A 12-minute walkthrough of pg_dump.",
  "thumbnailUrl": "https://example.com/thumb.jpg",
  "uploadDate": "2026-05-14T09:00:00-07:00",
  "duration": "PT12M",
  "contentUrl": "https://example.com/video.mp4"
}

For a YouTube embed, the markup lives on your embedding page. See video-seo for hosting, captions, and sitemaps.

DefinedTerm: glossary entries for machine readers

DefinedTerm inside a DefinedTermSet marks up glossary pages. Google shows no rich result for it, but it gives AI agents and other parsers a clean term and definition.

{
  "@context": "https://schema.org",
  "@type": "DefinedTerm",
  "name": "Crawl Budget",
  "description": "The number of URLs a search engine will fetch from a site within a window.",
  "inDefinedTermSet": { "@type": "DefinedTermSet", "name": "SEO Glossary", "url": "https://example.com/glossary/" }
}

Use it on dedicated definition pages, and pair with Article when the page also has editorial body content.