Skip to content
Barkhausen AI

DataBA-D-2026-03

Structured-data census 2026 (JSON-LD / Microdata / RDFa, four sectors)

One row per domain for 2,000 domains across four documented frames — universities, news, e-commerce, and U.S. federal government (500 each) — recording the structured-data signals found in each homepage's raw, server-delivered HTML: JSON-LD presence and block counts, the top-level schema.org types declared, per-type presence flags, and Microdata/RDFa presence.

Collection window: 2026-07-10 (news, e-commerce, government homepages); universities reuse 2026-07-09 homepage bytes · License: CC-BY-4.0 · Published with BA-D-2026-03: Structured data on the homepage: a JSON-LD census of 2,000 domains across four sectors

Download

CC-BY-4.0 · cite as a dataset with the parent report.

Schema

ColumnTypeDescription
domainstringThe registrable domain (eTLD+1) that was fetched, as listed in the sector frame; lowercased, computed with the Public Suffix List. The (sector, domain) pair matches the crawler-access-2026 dataset row-for-row.
sectorstring (enum)The frame the domain belongs to: universities, news, ecommerce, or government. Frames are disjoint; 2,000 rows, 2,000 distinct domains.
countrystring (ISO 3166-1 alpha-2) or emptyCountry code carried by the frame source. Empty where the source supplies none (e.g. gTLD e-commerce domains, whose country is not inferable from the ccTLD).
http_statusinteger or emptyHTTP status of the homepage (GET /) response, read from the stored response headers. Empty when the fetch produced no response (fetch_error is set).
fetch_errorstring (enum) or emptyTransport-level failure class when no HTTP response was received: dns, timeout, tls, or other. Empty when a response was received (http_status is populated).
analyzablebooleantrue when the stored response is HTTP 200 with a non-empty body — the rule that governs whether the structured-data fields below are populated. false rows (non-200, empty body, or fetch_error) carry fetch status only.
page_bytesintegerByte length of the stored response body. On a non-analyzable domain this is the bytes of whatever was received (0 when there was no response, or e.g. the bytes of a 403 challenge page).
has_jsonldboolean or emptytrue when the raw HTML carries at least one <script> block whose lower-cased type attribute contains 'ld+json' (HTML character references in the attribute are decoded, so 'application/ld&#x2B;json' counts). A block-presence test; it does not require the block to be valid JSON. Empty when the domain is non-analyzable. JSON-LD injected by client-side JavaScript is not present in the raw HTML and is not counted.
block_countinteger or emptyNumber of JSON-LD <script> blocks found in the raw HTML. 0 on an analyzable homepage with no JSON-LD; empty when non-analyzable.
invalid_block_countinteger or emptyNumber of those blocks whose inner text does not parse with a standard JSON parser as-is, with no repair (e.g. a CMS that HTML-escaped the quotes inside the script). A deliberate lower bound on validity — the state a raw JSON-LD consumer encounters. Empty when non-analyzable.
distinct_typesstring (semicolon-separated) or emptyThe sorted set of normalized top-level @type values declared across all valid JSON-LD blocks on the homepage, joined by ';'. Normalization strips a schema.org URL or compact-IRI prefix and preserves case (https://schema.org/Organization -> Organization). Only top-level and @graph-level nodes are counted, not types nested inside another entity; each type appears once per domain. Empty when non-analyzable, and also empty on an analyzable homepage that declares no JSON-LD types.
has_microdataboolean or emptytrue when an itemscope attribute appears on any start tag in the raw HTML (Microdata presence). Presence only — no item is extracted, no itemtype parsed, no validity judged. Empty when non-analyzable.
has_rdfaboolean or emptytrue when a typeof attribute appears on any start tag in the raw HTML (RDFa presence). Presence only. Empty when non-analyzable.
has_searchaction_sitelinksboolean or emptyThe one deep-scan flag: true when a SearchAction @type appears anywhere in a parsed JSON-LD block (the Google sitelinks-searchbox construct, always nested under WebSite.potentialAction, never at top level). Empty when non-analyzable.
has_potential_actionboolean or emptytrue when a potentialAction key appears anywhere in a parsed JSON-LD block. A superset context for has_searchaction_sitelinks. Empty when non-analyzable.
has_organizationboolean or emptytrue when 'Organization' is among the normalized top-level types. Exact normalized-name match; a subtype (e.g. Corporation, NewsMediaOrganization) does not set it. Same convention for every has_* type flag below. Empty when non-analyzable.
has_websiteboolean or emptytrue when 'WebSite' is a normalized top-level type.
has_webpageboolean or emptytrue when 'WebPage' is a normalized top-level type.
has_breadcrumblistboolean or emptytrue when 'BreadcrumbList' is a normalized top-level type.
has_article_or_newsarticleboolean or emptytrue when 'Article' OR 'NewsArticle' is a normalized top-level type. A subtype such as BlogPosting does not set it.
has_productboolean or emptytrue when 'Product' is a normalized top-level type. Product markup is typically on product detail pages, not the homepage this census reads.
has_offerboolean or emptytrue when 'Offer' is a normalized top-level type (an Offer nested inside a Product is not counted unless it is also top-level).
has_faqpageboolean or emptytrue when 'FAQPage' is a normalized top-level type.
has_collegeoruniversityboolean or emptytrue when 'CollegeOrUniversity' is a normalized top-level type (a university's self-declaration of kind).
has_governmentorganizationboolean or emptytrue when 'GovernmentOrganization' is a normalized top-level type.
has_localbusinessboolean or emptytrue when 'LocalBusiness' is a normalized top-level type. A subtype such as Store does not set it.
final_urlstring or emptyThe final URL after redirects for the homepage request. Empty when there was no response.
content_typestring or emptyThe Content-Type response header of the homepage, read from the stored headers.
analyzed_atstring (ISO 8601 timestamp)UTC timestamp at which the structured-data analysis row was produced. Note this is the analysis time, not the homepage fetch time; the fetch windows are 2026-07-09 (universities) and 2026-07-10 (the other three sectors), stated in collectionWindow.

Known limitations

FAQ

Why are some structured-data columns empty?
The row is non-analyzable — the homepage request returned a non-200 status, an empty body, or a transport error (DNS, timeout, TLS), so no HTML could be read. Those rows are kept as a first-class 'undeterminable' result but their has_jsonld, distinct_types, block counts, and has_* fields are left empty rather than guessed. Only analyzable rows (HTTP 200 with a body) carry populated structured-data fields.
What does has_jsonld = false mean, exactly?
No JSON-LD <script> block was present in the raw, server-delivered HTML. It is not a claim that the site has no JSON-LD: markup injected by client-side JavaScript (a tag manager, a React hydration payload, a setAttribute call) is invisible to this measurement by design, because the research question is what a non-rendering crawler can read. The direction of the resulting undercount is known and one-sided.
Does a JSON-LD row mean the site is more visible in AI assistants?
No. This dataset records deployment — whether markup is present in the homepage HTML — and nothing about consumption or visibility. The documented state, reviewed in BA-W-2026-03, is that schema.org markup is consumed by traditional search (for understanding and rich results) but is a documented negative for AI features: Google's AI-features documentation states no special structured data is needed for AI Overviews or AI Mode, and OpenAI's crawler documentation is silent on structured data. Presence here is not evidence of AI visibility.
How is distinct_types delimited and deduplicated?
It is a ';'-separated (semicolon) sorted set of the normalized top-level @type values a domain declares across all its valid JSON-LD blocks. Each type appears at most once per domain, and only top-level or @graph-level nodes are counted — a type nested deep inside another entity is not listed. No schema.org type name contains a semicolon or comma, so the delimiter is unambiguous.
Can I compare sectors directly?
The measurement method is identical across sectors, so the columns mean the same thing everywhere. But the four frames are built from different sources and orderings, and the university column was collected one day earlier (2026-07-09) than the other three (2026-07-10). Compare method-to-method over each frame's stated analyzable denominator (universities 429, news 413, e-commerce 267, government 329), not as sector-wide rates over 500.
What is the license, and how should this be cited?
The dataset is released under CC-BY-4.0. Cite the parent census BA-D-2026-03 and this datasheet, and state the collection windows (2026-07-09 for universities, 2026-07-10 for the other three sectors), since the data is a near-single-day snapshot.

Changelog

How to cite

Barkhausen AI (2026). Structured-data census 2026 (JSON-LD / Microdata / RDFa, four sectors) (dataset). https://barkhausen.ai/data/structured-data-2026/

BibTeX
@techreport{BA-D-2026-03,
  author       = {{Barkhausen AI}},
  title        = {Structured-data census 2026 (JSON-LD / Microdata / RDFa, four sectors) (dataset)},
  institution  = {Barkhausen AI},
  year         = {2026},
  url          = {https://barkhausen.ai/data/structured-data-2026/}
}

Published under the Creative Commons Attribution 4.0 International (CC-BY-4.0).