Free Schema Markup Validator

Paste a URL or your own JSON-LD and every structured data block on the page gets checked: is the JSON valid, does it declare a type, and does that type have the fields it needs. You get errors, warnings and your markup formatted back to you, in about a second. No signup, nothing stored.

Schema Markup Validator

Check JSON-LD structured data on a page — or paste a snippet directly — against common Schema.org requirements.

Structured data helps assistants trust your entity facts - see how often they mention your brand with the AI Visibility Tool.

What this validator checks

It finds every JSON-LD block on the page and runs four checks on each one.

Is the JSON parseable? A stray comma or an unclosed brace means the whole block is invisible to Google, and this is the most common reason markup silently does nothing.

Is there an @context. It should be https://schema.org.

Is there an @type, and is it a type the checker knows.

Does that type carry its required and recommended fields. Missing required fields come back as errors. Missing recommended fields come back as warnings.

Two limits worth knowing before you run it. It reads JSON-LD only, so markup written as microdata or RDFa in your HTML attributes will not be found and the tool will report no blocks. And it reads the HTML your server returns, so structured data injected by JavaScript after load is invisible to it - the same way it is invisible to a crawler that does not render.

How to read your results

An error means the block is broken in a way that costs you the whole thing. Google parses it, finds a required property missing, and discards it. You get nothing, not a partial result.

A warning means the block works but is thinner than it could be. It will be read; it just will not earn as much as it could.

Here is a Product block that returns one error and five warnings:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "offers": {
    "@type": "Offer",
    "price": "119.00",
    "priceCurrency": "USD"
  }
}

The error is a missing name. Product requires it, and without it there is no product to show. The warnings are image, description, aggregateRating, review and brand - all recommended, and the last two are what put stars on a result.

Fix errors first. An error costs you the whole block. A warning costs you one enhancement.

The schema types worth your time

Schema.org has hundreds of types. A handful change what your result looks like.

Organization, once, sitewide. It tells Google who publishes the site and it is what a knowledge panel is built from. Include name, url, logo and sameAs pointing at your real profiles.

Product, on product pages. Requires name. You also want an offers block carrying both price and priceCurrency - a price with no currency is not a price, and Google drops the offer.

Article, on posts. Requires headline, image, datePublished and author - this checker treats all four as required, matching what Google needs before it will show an Article enhancement.

LocalBusiness, on location pages. Requires name and address, plus openingHoursSpecification if you want hours shown.

FAQPage, on any page with genuine questions and answers visible on it. Still worth adding, but read the FAQ below on what it earns now. It is not what it earned two years ago.

One rule across all of them: use the single type that describes what the page actually is, plus Organization sitewide. Stacking types that do not describe the page is the most common way to make markup worse rather than better.

The @graph pattern, and why most sites use it

Most real markup does not look like the flat example above. It looks like this:

{
  "@context": "https://schema.org",
  "@graph": [
    { "@type": "Organization", "@id": "https://example.com/#org", "name": "Example" },
    { "@type": "WebSite", "@id": "https://example.com/#site",
      "publisher": { "@id": "https://example.com/#org" } },
    { "@type": "WebPage", "url": "https://example.com/about",
      "isPartOf": { "@id": "https://example.com/#site" } }
  ]
}

@graph lets one script tag hold several connected entities that share a single @context and refer to each other by @id. The Organization is declared once and pointed at from everywhere else, instead of being repeated across three separate blocks that Google then has to guess describe the same company.

Two things follow, and both trip people up. A child inside @graph must NOT carry its own @context - it inherits the parent one, and adding it again is the mistake. And an @id only works if it is used consistently: the string in the reference has to match the string in the declaration exactly, fragment included.

Yoast, RankMath, Squarespace, Shopify and Framer all emit @graph by default. If you did not hand-write your markup, this is almost certainly what you have.

Five things that quietly break structured data

A syntax error anywhere in the block. One trailing comma and Google skips the entire script tag. This is why validating before publishing is worth the thirty seconds.

A required field present but empty. An empty string is not a value - a name set to empty behaves exactly like a name that is missing.

Markup describing something that is not on the page. Review markup with no reviews visible, or a price in the markup that differs from the price on screen. This is a policy violation rather than a technical error, and it is the one that can earn a manual action rather than simply being ignored.

A price with no currency. priceCurrency sits inside the offers block, and this checker now flags it as a warning - but Google drops the offer entirely without it, so it is worth confirming by eye too.

Two blocks describing the same thing differently. A plugin emits Organization, the theme emits it again with a different logo, and Google picks one - usually not the one you wanted. Consolidate into a single @graph.

Validator, generator, or the Rich Results Test

Use this validator when you have markup and want to know whether it is well formed and complete. It works on types Google shows no rich result for, and on markup that is not published yet.

Use the Schema Markup Generator when you do not have markup and need it built from a page or a description.

Use Google Rich Results Test when you want to know whether Google will show a specific enhancement for a live URL. It applies Google own requirements, which are stricter than the field lists here, and it only works on pages Google can already reach.

The usual order is generate, validate here, publish, then confirm in Search Console a week later. See our Generative Engine Optimization services.

Need to generate schema rather than check it? The Schema Markup Generator builds JSON-LD from a URL or a description, grounded in what it can verify.

Building FAQPage markup from scratch? The FAQ schema generator escapes your questions and answers correctly, then checks they’re really in your page source, before you validate here.

FAQ

Frequently Asked Questions

Is this the same as the Google Rich Results Test?

No. The Rich Results Test applies Google own requirements for a specific enhancement, and only to a live URL it can reach. This validator checks whether your JSON-LD is well formed and carries the fields its type expects, including types Google shows no rich result for, and it works on a pasted snippet before the page is live. Use both - they answer different questions.

Does invalid schema hurt my rankings?

Not directly. Google ignores markup it cannot parse rather than penalising it. What you lose is the enhancement the markup was meant to earn, and any chance of the page being quoted accurately by an AI assistant reading your structured data.

Why does my markup pass here but show no rich result in Search Console?

Two reasons. Passing here means the block is well formed and carries its expected fields; Google applies extra requirements on top of that for each enhancement. And valid markup makes you eligible, not guaranteed - Google decides per query whether to show an enhancement at all, and since 7 May 2026 the FAQ rich result is no longer shown to most sites.

Can I validate markup that is not published yet?

Yes. Switch to paste mode and drop the JSON-LD in directly. Nothing is stored and nothing is sent to Google.

Which schema type should my page use?

One primary type that matches what the page is - Product for a product page, Article for a post, LocalBusiness for a location - plus Organization sitewide. Do not stack types that do not describe the page.

What is @graph and do I need it?

It lets one script tag hold several connected entities - your Organization, your WebSite and the page itself - sharing a single @context and cross-referencing each other by @id. Most modern SEO plugins emit it by default. It is not required, but it is cleaner than several separate blocks.