Structured Data Validator: Schema Markup Checker avatar

Structured Data Validator: Schema Markup Checker

Pricing

from $2.00 / 1,000 page checkeds

Go to Apify Store
Structured Data Validator: Schema Markup Checker

Structured Data Validator: Schema Markup Checker

Schema markup validator for your pages. Checks JSON-LD, Microdata and RDFa against schema.org and the Google rich result rules for Product, Article, Event, Recipe, Local business and more. One row per URL with types, errors and warnings. Reads URLs or sitemaps, with a change-only mode.

Pricing

from $2.00 / 1,000 page checkeds

Rating

0.0

(0)

Developer

Malik Said

Malik Said

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Security

Limited permissions

Share

This structured data validator checks the schema markup on your web pages. It reads JSON-LD, Microdata and RDFa, validates every item against the schema.org vocabulary, and checks the required and recommended properties of Google rich results. You get one row per URL with the types found, errors, warnings and which rich results are valid. Give it page URLs, an XML sitemap, or let it follow links on your site. A change-only mode tells you when a page's markup breaks.

It is built for site owners, SEO consultants, agencies and developers who test their own or their clients' sites in bulk.

What the schema markup validator checks

AreaWhat you get
FormatsJSON-LD (including @graph and @id references), HTML Microdata (including itemref) and schema.org RDFa Lite
JSON-LD syntaxBlocks that are not valid JSON, empty blocks, a missing or non-schema.org @context
schema.org typesUnknown types, wrong letter case (for example product), superseded types, items with no type
schema.org propertiesUnknown properties, properties schema.org does not list for the type, superseded properties
ValuesDates and times (ISO 8601), durations (PT1H30M), prices with currency signs, currency codes, numbers in ratings, enumeration values such as availability, URLs, empty values
Rich result rulesRequired and recommended properties for 19 Google rich result features (list below)
Retired featuresFAQ and How-to markup is flagged, because Google no longer shows these rich results

Rich result features covered

Product snippet, Merchant listing, Review snippet, Article (also NewsArticle and BlogPosting), Breadcrumb, Event, Recipe, Job posting, Local business (and subtypes such as Restaurant), Organization, Video, Software app, Course, Dataset, Discussion forum, Movie, Q&A, Profile page and Image metadata.

The rules were written by hand from Google Search Central's public structured data pages, read on 21 October 2026. The Actor does not call any Google API. Its results can differ from Google's Rich Results Test. Google decides what it shows in search.

Structured data validator output

One dataset row per page:

  • url, finalUrl, httpStatus, contentType
  • jsonLdCount, microdataCount, rdfaCount, itemCount, hasStructuredData
  • types: the schema.org types of the top-level items
  • richResults: one entry per rich result feature found, with valid, errorCount and warningCount
  • validRichResults: features with at least one item that has no errors
  • errorCount, warningCount, errorCodes, issueCounts
  • errors and warnings: up to 200 each, with code, format, itemIndex, itemType, path (for example offers.price) and a plain message
  • items: the raw items as JSON, when Include raw items is on
  • changeStatus, previousErrorCount, previousTypes: in change-only mode
  • fetchError: why a page could not be checked

Errors block a rich result. Warnings are missing recommended properties and schema.org notes that do not block it.

Error and warning codes

CodeSeverityMeaning
JSONLD_PARSE_ERRORErrorA JSON-LD block is not valid JSON
JSONLD_MISSING_CONTEXTErrorA JSON-LD item has no @context
JSONLD_NON_SCHEMA_CONTEXTWarningThe @context is not schema.org
MISSING_TYPEErrorA top-level item has no type
UNKNOWN_TYPEErrorThe type is not in schema.org
UNKNOWN_PROPERTYErrorThe property is not in schema.org
MISSING_REQUIREDErrorA required rich result property is missing
INVALID_DATEErrorA date is not ISO 8601
INVALID_DURATIONErrorA duration is not ISO 8601
INVALID_PRICEErrorA price is not a plain number
INVALID_CURRENCYErrorA currency is not a 3-letter ISO 4217 code
INVALID_NUMBERErrorA rating or count is not a number
MISSING_RECOMMENDEDWarningA recommended rich result property is missing
PROPERTY_NOT_FOR_TYPEWarningschema.org does not list the property for this type
INVALID_ENUM_VALUEWarningThe value is not a member of the expected list, for example availability
INVALID_URLWarningA URL property holds text with spaces
EMPTY_VALUEWarningA property is empty
DEPRECATED_TYPE, DEPRECATED_PROPERTYWarningschema.org marks the name as superseded
NON_SCHEMA_ORG_TYPEWarningThe type is from another vocabulary and was not validated
RICH_RESULT_RETIREDWarningFAQ or How-to markup that Google no longer shows

Run summary

The key-value store record OUTPUT holds the run summary: pages checked, pages with structured data, pages with errors, pages without markup, items by format, pages by type, valid and invalid counts per rich result feature, error and warning code counts, change counts, pages skipped by robots.txt and the sitemap result.

How to validate structured data in bulk

  1. Enter your page URLs in Page URLs. Or enter your sitemap in Sitemap URLs, or turn on Find sitemaps in robots.txt.
  2. Turn on Follow links on the same site to check pages you did not list.
  3. Set Maximum pages. The default is 100. Set 0 for no limit.
  4. Run the Actor. Open the Overview view for one row per page, or the Errors view for one row per error.

Change-only mode

Turn on Change-only mode and schedule the Actor, for example daily. The first run saves every page with changeStatus: NEW. Later runs save only pages whose result changed: BROKE (more errors), FIXED (fewer errors), MARKUP_REMOVED, CHANGED or FETCH_FAILED. Use a different Change-only state key for each site. In a local test on 20 blog pages, the second run saved 0 rows.

Input example

{
"startUrls": [{ "url": "https://webscraper.io/test-sites/e-commerce/allinone" }],
"sitemapUrls": [],
"crawlLinks": false,
"includeItems": false,
"changeOnly": false,
"maxItems": 100
}

Output example

Real row for the webscraper.io test page, from a run on 22 October 2026. The richResults, errors and warnings lists are shortened to 2 entries each.

{
"id": "https://webscraper.io/test-sites/e-commerce/allinone",
"url": "https://webscraper.io/test-sites/e-commerce/allinone",
"finalUrl": "https://webscraper.io/test-sites/e-commerce/allinone",
"httpStatus": 200,
"contentType": "text/html; charset=utf-8",
"jsonLdCount": 0,
"microdataCount": 4,
"rdfaCount": 0,
"itemCount": 4,
"hasStructuredData": true,
"types": [
"SiteNavigationElement",
"Product"
],
"richResults": [
{
"feature": "Product snippet",
"itemIndex": 1,
"itemType": "Product",
"format": "microdata",
"valid": false,
"errorCount": 2,
"warningCount": 4
},
{
"feature": "Merchant listing",
"itemIndex": 1,
"itemType": "Product",
"format": "microdata",
"valid": false,
"errorCount": 1,
"warningCount": 8
}
],
"validRichResults": [],
"errorCount": 6,
"warningCount": 36,
"errors": [
{
"severity": "error",
"code": "INVALID_PRICE",
"format": "microdata",
"itemIndex": 1,
"itemType": "Product",
"path": "offers.price",
"message": "Price \"$1769\" must be a number, for example 1179.00, with no currency sign. Put the currency in priceCurrency."
},
{
"severity": "error",
"code": "MISSING_REQUIRED",
"format": "microdata",
"itemIndex": 1,
"itemType": "Product",
"path": "aggregateRating.ratingValue",
"message": "Product snippet: required property \"aggregateRating.ratingValue\" is missing."
}
],
"warnings": [
{
"severity": "warning",
"code": "MISSING_RECOMMENDED",
"format": "microdata",
"itemIndex": 1,
"itemType": "Product",
"path": "review",
"message": "Product snippet: recommended property \"review\" is missing."
},
{
"severity": "warning",
"code": "MISSING_RECOMMENDED",
"format": "microdata",
"itemIndex": 1,
"itemType": "Product",
"path": "offers.availability",
"message": "Product snippet: recommended property \"offers.availability\" is missing."
}
],
"errorCodes": [
"INVALID_PRICE",
"MISSING_REQUIRED"
],
"issueCounts": {
"INVALID_PRICE": 3,
"MISSING_REQUIRED": 3,
"MISSING_RECOMMENDED": 36
},
"changeStatus": null,
"previousErrorCount": null,
"previousTypes": null,
"items": null,
"fetchError": null,
"scrapedAt": "2026-10-22T08:19:36.521Z"
}

Real findings from test runs

  • On the webscraper.io e-commerce test page, every product's Microdata price includes a dollar sign, for example $1102.66. Each one is an INVALID_PRICE error. The AggregateRating items have reviewCount but no ratingValue, so each product also gets MISSING_REQUIRED at aggregateRating.ratingValue.
  • On a public blog, one article's second JSON-LD block had a raw line break inside a string. The row showed JSONLD_PARSE_ERROR. Python's JSON parser confirmed the same error.
  • On the same blog, articles with an extra FAQPage item got RICH_RESULT_RETIRED.
  • On another site's blog, datePublished was written as August 24, 2026. Each post got INVALID_DATE.
  • A local full crawl of a test site with Follow links on the same site checked 534 pages in about 7 minutes at 120 requests per minute. Linked CSV, JSON and Excel downloads were skipped without a row or a charge.

Pricing

Pay per event:

  • $0.02 per run start.
  • $2.00 per 1,000 pages checked ($0.002 per page).

A run of 500 pages costs $1.02. In change-only mode every checked page is charged, saved or not. You can set a maximum cost per run in the run options.

Polite crawling and limits

  • The Actor obeys robots.txt for every page and sitemap. Skipped pages are listed in the summary.
  • It loads at most 60 pages per minute from one site by default. Change Requests per minute per site only for your own servers.
  • Each page has a 30-second load limit and 2 retries.
  • It reads server HTML only. Markup that JavaScript adds after the page loads is not seen.
  • Sitemap reading stops after 50 files or 2 minutes.
  • Check only sites you own or have permission to audit.

FAQ

Is this the same as Google's Rich Results Test? No. It applies its own rules, written from Google's public documentation, and the schema.org vocabulary. Use it to find problems across many pages. Confirm key pages in Google's tools.

Why does a Microdata name on a link show a URL? The HTML Microdata standard reads the href of an <a> element as the property value. Put itemprop="name" on a <span> inside the link to give the text.

Which schema.org version is used? The current schema.org release, fetched on 21 October 2026. schema.org data is licensed under CC BY-SA 3.0.

Does it render JavaScript? No. Most sites put JSON-LD in the server HTML. If yours adds it with JavaScript, the page shows hasStructuredData: false.

Support

Open an issue on the Actor's Issues tab. Include the run ID and the page URL.