Schema Markup 4 min read

Schema Markup and SERP Rich Results: Check Eligibility

Separate JSON-LD validation, Google rich-result eligibility and observed presentation. Use current supported types and source evidence without CTR promises.

(Updated: ) • 636 words

Schema markup work has three separate questions: is the JSON-LD valid, does the page meet a currently supported Google feature’s rules, and did Google actually show that feature? Validate all three independently. A SERP observation cannot tell you the page’s schema implementation, and valid markup does not guarantee display.

Start with currently supported result types

Google’s May 2026 update says FAQ rich results stopped appearing on May 7, 2026; the documentation was removed on June 15. Do not plan FAQ markup as a route to an FAQ search enhancement. Visible questions and answers can still help readers. Check the current supported-feature gallery before choosing another type.

Featured snippets, People Also Ask and other SERP features should not be treated as schema types you can enable by copying a competitor. Use Google’s structured-data policies and the specific feature requirements, with matching visible content.

Collect implementation evidence from HTML

Use the original HTML, or a rendered DOM when scripts inject the markup. Reader Markdown is useful for checking content readability but is not a guaranteed source of script tags or a schemas field. The parser below finds JSON-LD blocks in initial HTML and reports JSON validity without calling that result Google eligibility.

import json
from html.parser import HTMLParser

class JsonLdReader(HTMLParser):
    def __init__(self):
        super().__init__(convert_charrefs=False)
        self.active = False
        self.buffer = []
        self.raw_blocks = []
    def handle_starttag(self, tag, attrs):
        if tag.lower()=="script" and dict(attrs).get("type", "").lower()=="application/ld+json":
            self.active, self.buffer = True, []
    def handle_data(self, value):
        if self.active:
            self.buffer.append(value)
    def handle_endtag(self, tag):
        if tag.lower()=="script" and self.active:
            self.raw_blocks.append("".join(self.buffer))
            self.active = False

def inspect_jsonld(raw_html):
    parser = JsonLdReader()
    parser.feed(raw_html)
    rows = []
    for index, raw in enumerate(parser.raw_blocks):
        try:
            value = json.loads(raw)
            nodes = value if isinstance(value, list) else [value]
            types = []
            for node in nodes:
                if isinstance(node, dict):
                    types.append(node.get("@type"))
                    types += [n.get("@type") for n in node.get("@graph", []) if isinstance(n, dict)]
            rows.append({"block":index, "json_valid":True, "types":[t for t in types if t]})
        except json.JSONDecodeError:
            rows.append({"block":index, "json_valid":False, "types":[]})
    return {"blocks":rows, "eligibility":"not_tested", "visible_content_match":"manual_check_required",
        "limitation":"initial HTML only; render JavaScript separately when schema is injected"}

Build a verification record

Evidence What it establishes
Raw or rendered HTML The actual JSON-LD present at the sampled time
Visible page content Whether names, dates, offers and other statements agree
Vocabulary and required-property checks Whether the selected supported feature is implemented correctly
Rich Results Test Google’s test output for the exact sampled page
Search Console and repeat observations Actual processing and observed appearances, with aggregation limits

Test a synthetic page with one valid JSON-LD block and one malformed block. The parser should distinguish them and leave eligibility as not_tested. A page can pass that parser while violating feature requirements. A rich result can also be absent on a valid eligible page; do not turn either situation into a fabricated CTR gain.

Observe presentation without claiming causation

Use a Google SERP sample to record a query, market, timestamp and visible feature. Keep that observation separate from markup extraction. Track the appropriate GSC search appearance where available, and avoid summing different page and property aggregations. A before/after movement alone does not prove schema caused the change.

For implementation use the JSON-LD validation workflow. the rich-result monitoring workflow and the change ledger handle observations. This article owns eligibility and evidence selection; it does not replace those operational checks.

Tags:

Schema Markup Structured Data SERP Optimization Rich Snippets
SearchCans Team

SearchCans Team

SERP API & Reader API Experts

The SearchCans engineering team builds high-performance search APIs serving developers worldwide. We share practical tutorials, best practices, and insights on SERP data, web scraping, RAG pipelines, and AI integration.

Ready to build with SearchCans?

Test SERP API and Reader API with 100 free credits. No credit card required.