BlogFindings

Do AI crawlers see paywalled content? 23 of 35 pages marked not free served 500 words or more

A paywall is the one part of a news site built to be hard to read, and the markup that declares it is read by two crawlers, both of them Google's.

16 min read Lantad

That is not a gotcha, and it matters that the reason is stated before the number is read. Google's own documentation describes this markup as the way a publisher tells it a page is paywalled rather than cloaked, which means supplying the text to the crawler and marking the region a human will not be shown. So the full article reaching a crawler is the design working, not the design failing. The finding here is narrower and it is about who can read the marking. The flag lives in structured data, and across four vendors' published crawler pages the only crawlers documented as reading it are Google's two.

In short

  • Lantad read 246 article pages on 85 news and article-publishing hosts drawn from this repository's two committed corpus seed files on 8 November 2026, every request sent as LantadBot/1.0 with redirects followed and no JavaScript executed, and 35 of those pages declared a page-level isAccessibleForFree of false.
  • Do AI crawlers see paywalled content: on those 35 pages the median main-content word count delivered to the crawler was 789, 23 of the 35 delivered 500 words or more, 16 delivered 1,000 or more, and the largest single page delivered 3,756 words on nzz.ch.
  • 121 of the 192 pages that declared a schema.org Article type on 8 November 2026 carried no page-level isAccessibleForFree at all, so nothing in their markup said whether the article was free or paid either way.
  • Google's paywalled content documentation, carrying Last updated 2026-09-08 UTC, names Googlebot and Googlebot-News, and the crawler documentation OpenAI, Anthropic and Perplexity published, each read at source on 8 November 2026, does not mention paywalls, paywalled content or structured data anywhere.
  • 4 of the 50 paywall cssSelector declarations named a class that appears in no class or id attribute of the delivered HTML, three of them on slate.com, where the named token appears ten times in the bytes and never once as the class of an element.
  • Article pages read, 85 hosts 246 pages HTTP 200 with an HTML content type, no JavaScript executed
  • Declared a schema.org Article type 192 pages Across 69 of the 85 hosts
  • Declared isAccessibleForFree 71 pages Page level, across 26 hosts
  • Declared it false, not free 35 pages Across 13 hosts
  • Of those, delivered 500 words or more 23 pages Main-content words reaching LantadBot/1.0
  • Of those, delivered 1,000 words or more 16 pages Median across all 35 was 789 words
  • Of those, delivered no main content 2 pages Both on cnbc.com
The 246 article pages Lantad read on 85 news and article-publishing hosts on 8 November 2026, narrowed step by step to the pages whose own markup declared they were not free and still handed the crawler the article. Main-content words are the main-weighted extraction in core/src/extract.ts, not the total word count of the page.

What Lantad asked for, and what came back

The corpus is the 1,419 hostnames in this repository's two committed seed files, the same sampling frame behind the AI visibility work published on the research pages. The run has two stages, because paywall markup does not live where a site's front door is.

Stage one asked every one of the 1,419 hosts for robots.txt as LantadBot/1.0. 1,107 answers parsed into at least one user-agent group, 221 returned a 4xx, which RFC 9309 says leaves the site unrestricted, 61 returned a 5xx, which the same specification says a crawler should read as a complete disallow, and 30 failed at the transport. The site root was then resolved for the LantadBot token against every parsed file using the matcher shipped in core/src/robots.ts, which closed 73 home pages. 1,056 hosts answered the home page with HTTP 200 and an HTML content type, and 625 of those carried at least one JSON-LD block that parsed. Eleven of the 1,056 carried the property isAccessibleForFree anywhere in that markup, which is the first thing worth saying: on a home page the flag is close to absent, and that is expected, because a home page is not the thing behind the wall.

Stage two went looking for the article pages. The candidate set was 95 hosts: the news stratum, the local media platform stratum, and any host whose home page markup named a schema.org Article type. Same-host links were taken from each home page and ranked by shape, preferring a path carrying a four digit year or a long hyphenated slug and penalising the archive furniture that an internal link graph is mostly made of. Each candidate path was then checked against that host's own robots.txt for the LantadBot token before it was requested, which is why no page in this measurement was fetched against a rule telling the crawler not to.

257 article URLs were requested, at most three readable pages per host. None was skipped by a robots rule, none failed at the transport, and 11 did not answer with both HTTP 200 and an HTML content type. That leaves 246 pages on 85 hosts, and 192 of those 246 declared a schema.org Article type, spread across 69 hosts. Every figure below is drawn from that set of 246, read once each on 8 November 2026. The scanner's own request policy is published at the bot page.

The two stage run, 8 November 2026. Every article path was evaluated against its own host's robots.txt for the LantadBot token before it was requested.

Do AI crawlers see paywalled content?

71 of the 246 pages, spread over 26 hosts, declared a page-level isAccessibleForFree. 35 of those declared it false, on 13 hosts, and 36 declared it true, on 14 hosts. The 35 that said false are the population this question is about, because they are the pages that assert in machine-readable form that what they hold is not free.

Those 35 pages delivered 35,987 words of main content to an anonymous crawler between them. The median was 789 words, 23 of the 35 cleared 500 words, 16 cleared 1,000, and the single largest was 3,756 words on an nzz.ch politics article. At the other end, 11 of the 35 delivered under 200 words and two delivered none at all, both on cnbc.com, where the markup declares the page not free and the bytes carry no main content for the crawler to take.

The contrast with the 36 pages that declared themselves free is smaller than the framing of the question suggests. Their median main-content delivery was 1,046 words against 789 for the not-free pages. A difference of roughly 250 median words is not the difference between an open article and a closed one, and nobody reading only the markup would guess which group was which from what reached the crawler.

Three hosts are worth separating out because they show the two honest implementations sitting side by side. On scmp.com all three pages read delivered between 160 and 171 words of main content, so the main article region genuinely was withheld, and yet the JSON-LD on those same pages carried an articleBody property of 773, 583 and 797 words whose opening text was present in the delivered bytes. The body was supplied to the crawler through the markup rather than through the page. On nzz.ch and inquirer.com the body simply arrived in the HTML, thousands of words of it, with the markup naming the region a reader would be stopped at. Both are consistent with what Google's paywall markup documentation asks for. Neither is detectable by a crawler that does not read the flag.

This is a different measurement from the login walls counted in the gated content run, which found 2 of 66 password pages tripping the condition this scanner uses to withhold a grade. A password form is a wall a crawler can see. A metered paywall declared in JSON-LD is a wall a crawler is told about, and only if it is reading the right property. 18 of the 246 pages here showed a password input, which is the overlap between the two populations and a small one.

HostPages not freeMost main words deliveredhasPart nodeSelector on the page
nzz.ch33,756YesYes
inquirer.com32,778YesYes
hollywoodreporter.com32,358YesYes
statnews.com32,181YesYes
spectator.co.uk31,268YesYes
scientificamerican.com31,204NoNone declared
thejakartapost.com21,081YesYes
bostonglobe.com2956YesYes
cnn.com3789Yes1 of 3 absent
greenpointers.com3174YesYes
scmp.com3171YesYes
aftenposten.no2120YesYes
cnbc.com20YesYes
Every host with at least one article page declaring a page-level isAccessibleForFree of false, 8 November 2026. Pages column counts the pages read on that host that declared it. The words column is the highest main-content delivery among those pages. hasPart is Google's recommended region block.

Which crawlers document reading the flag

The property is not a Google invention. schema.org defines isAccessibleForFree as a flag to signal that the item, event or place is accessible for free, expects a Boolean, lists CreativeWork, Event and Place as the types that carry it, and records that it supersedes an earlier property called free. That page also carries a usage band from Google's monthly web index aggregation, dated August 2026, putting the property on between 100,000 and one million domains. For scale, the same published dataset puts only sixteen schema.org types above ten million domains, so this is a property in use but not a common one.

Google's paywalled content documentation, read at source on 8 November 2026 and carrying Last updated 2026-09-08 UTC, requires isAccessibleForFree and recommends three more: a hasPart block whose type is WebPageElement, that block's own isAccessibleForFree, and a cssSelector naming the class of the region behind the wall. It applies the markup to CreativeWork or to the subtypes Article, NewsArticle, Blog, Comment, Course, HowTo, Message, Review and WebPage. It names two crawlers, Googlebot and Googlebot-News. And it states the purpose in one clause: the markup helps Google differentiate paywalled content from the practice of cloaking, which violates spam policies.

Read that clause again, because it decides how the numbers above should be taken. The markup exists so that handing a crawler the full text of a paid article is not treated as deception. A publisher doing exactly what the documentation asks will therefore serve the words and declare the wall, and the words will reach anything else that asks politely.

So the question becomes which other crawlers read the declaration, and the answer on 8 November 2026 is none of the three largest AI vendors, at least not in anything they publish. OpenAI's crawler overview documents four tokens, GPTBot, OAI-SearchBot, ChatGPT-User and OAI-AdsBot, and mentions paywalls, paywalled content, subscriptions, isAccessibleForFree and structured data nowhere on the page. Anthropic's crawler page documents ClaudeBot, Claude-User and Claude-SearchBot, and does the same. Perplexity's bots page documents PerplexityBot and Perplexity-User, and does the same. These are statements about what four published pages say, not about what any crawler does in private, and the difference is the whole caveat.

  • Googlebot and Googlebot-News Named Google's paywalled content page, Last updated 2026-09-08 UTC, names both and requires isAccessibleForFree.
  • GPTBot, OAI-SearchBot, ChatGPT-User, OAI-AdsBot Not mentioned OpenAI's crawler overview documents four tokens and says nothing about paywalls or structured data.
  • ClaudeBot, Claude-User, Claude-SearchBot Not mentioned Anthropic's crawler page documents three tokens and says nothing about paywalls or structured data.
  • PerplexityBot, Perplexity-User Not mentioned Perplexity's bots page documents two tokens and says nothing about paywalls or structured data.
What each vendor's published crawler documentation says about paywalled content, read at source on 8 November 2026. A page that does not mention the markup is not evidence that the crawler ignores it.

121 of 192 article pages said nothing either way

The larger group is the silent one. 192 of the 246 pages declared a schema.org Article type, and 121 of those 192 carried no page-level isAccessibleForFree at all. Their markup asserts that the page is an article, who wrote it and when it was published, and says nothing about whether reading it costs money.

For a free article that is harmless, and most of the 121 are presumably free. The cost lands on the paid ones, because a missing Boolean is not a default. Nothing in the markup distinguishes an open article that never needed the flag from a metered article whose publisher never added it, and the crawler sees the same thing in both cases, which is prose it is free to take. This is the same shape as the gap measured in the structured data run on home pages, where absence rather than error was the dominant finding.

The recommended region block is rarer still. 56 of the 246 pages, on 21 hosts, carried a hasPart node typed as WebPageElement. Of the 35 pages declaring themselves not free, 32 carried one and 3 did not, and all three of those were scientificamerican.com, where the page-level flag says false with no region named at all. Under Google's documentation a page-level false with no hasPart block is a claim about the whole page, which on those three pages sat above 1,027, 1,170 and 1,204 words of delivered main content.

Seven pages ran the arrangement in reverse, carrying a region block that declares a part not free while the page level says nothing, on slate.com, irishtimes.com and thenationalnews.com. Thirteen hasPart nodes declared their region free rather than paid, and seven carried no cssSelector, so there was no class for a reader of the markup to resolve. Defects of this kind are the same family as the ones counted in the schema markup validator run and the headline mismatches in the Article schema run: the markup parses, the vocabulary is real, and what it asserts is not quite what the page does. Whether any of it changes an answer engine's behaviour is a separate question this run cannot reach, and the methodology page is explicit about which claims the scanner is entitled to make.

  • isAccessibleForFree at page level, required Declared on 71 of 246 pages across 26 hosts. 35 said false, 36 said true. 121 of the 192 pages declaring an Article type carried it nowhere.
  • hasPart typed as WebPageElement, recommended Present on 56 of 246 pages across 21 hosts. Carried by 32 of the 35 pages declaring themselves not free; absent on 3, all scientificamerican.com.
  • hasPart.cssSelector, recommended 50 declarations across 18 hosts, naming 18 distinct class strings. 7 hasPart nodes carried no selector at all.
  • hasPart.isAccessibleForFree, recommended Declared false on the region in most cases, and declared true on 13 nodes, which marks the named region as the free part rather than the paid one.
The four properties Google's paywalled content documentation asks for, against the 246 article pages read on 8 November 2026. One property is required and three are recommended.

Four selectors named a class that is not on the page

A cssSelector is the one property in this block that can be checked against the page it describes, because it names a class and the class is either in the delivered HTML or it is not. Of the 50 paywall selector declarations, 46 named a token that appears in a class or id attribute of the bytes the crawler received. Four did not.

Three of the four are slate.com, and they are worth setting out in full because the combination is unusual. Each of the three pages carries a hasPart node typed WebPageElement whose isAccessibleForFree is false and whose cssSelector is .slate-blur, and none of the three carries a page-level isAccessibleForFree. The token slate-blur appears ten times in the delivered HTML of the article read most closely, and not once as the class or id of an element: it occurs inside inline JSON rather than on the markup it is meant to select. Those three pages handed the crawler 1,455, 2,345 and 2,598 words of main content. The markup names a paywalled region, the region is not in the document under that name, and the article text is.

The fourth is a cnn.com page on an election forecast path, which declares not free and names .article__content, a class that is present on the other two cnn.com pages read and absent on that one. That reads like one template among several rather than a systematic error, which is why it is reported as one page and not as a property of the host.

A selector pointing at nothing is a familiar failure in this vocabulary. The speakable schema run found 5 of 12 resolvable selectors pointing at no readable text, and the mechanism is identical: a class name written into JSON-LD by a template that does not know what the renderer emitted. Worth noting for anyone grepping their own markup, cssSelector is used by more than one property. 19 declarations on 11 of these 246 pages sit inside a speakable block rather than a hasPart block, which is an unrelated purpose, and counting the two kinds together inflates the paywall figure. cnbc.com writes the same class string, .xyz-data, into both blocks on the same page, which is what made the conflation easy to miss on a first pass of this measurement.

What the JSON-LD declares

  • hasPart type WebPageElement
  • hasPart.isAccessibleForFree is false
  • hasPart.cssSelector is .slate-blur
  • No page-level isAccessibleForFree

What the crawler received

  • slate-blur appears 10 times in the HTML
  • 0 of those are a class or id attribute
  • 2,598 words of main content delivered
  • No password input on the page
One slate.com article read on 8 November 2026, markup against delivered bytes. The class named by the paywall selector is in the document as JSON text and on no element.

What this measurement does not show

Four limits, and the first is the one that would change the headline if it were different. Every request was sent as LantadBot/1.0, an honest token with a URL in it that no vendor has an agreement with. No request impersonated GPTBot, ClaudeBot or Googlebot, because a scanner that lies about who it is cannot report on who is trusted. So this run shows what a publisher serves to an unknown and well-behaved crawler, which is the relevant case for most of the AI fleet and is not the case for Googlebot, whose access many of these publishers have negotiated or configured deliberately.

Second, three pages per host at most, and 246 pages in total. That is enough to say what these publishers' templates do and not enough to put a percentage on the news industry. The strata behind the sample are described on the research pages, and the industry split measured in the blocking run is the better guide to how differently news sites behave from the rest of the corpus.

Third, metered paywalls move. A reader's third article of the month is not the reader's first, and a crawler is nobody's third anything. A page that served 2,000 words to LantadBot on 8 November 2026 may serve a human a form, and nothing here measures what a subscriber or a logged-out browser would see. The one firm statement is about the bytes: on these pages, on that date, those words were in the initial HTML, which is the same quantity measured across the corpus in the answer-bearing facts run and the same thing prose parity scores.

Fourth, nothing here measures citation. Whether text a crawler received ends up quoted in an answer is a different pipeline, and the gates in front of it were counted in the ChatGPT citation run. A publisher who wants the open half of this story rather than the paid half can see what a crawler gets from any single page with the GPTBot view tool, and the reason this site declines to grade a page it could not read is set out in why we withhold a grade.

LantadBot/1.0 against one news host

  • GET /robots.txt 200, parsed into user-agent groups
  • evaluateRobots(LantadBot, /) allowed
  • GET / (home page) 200, text/html
  • rank same-host links by path shape article candidates
  • evaluateRobots(LantadBot, /article-path) allowed
  • GET /article-path, no JavaScript executed 200, text/html
  • parse JSON-LD, read isAccessibleForFree false
  • count main-content words delivered above 500 on 23 of 35 pages
The request sequence behind one row of the measurement, 8 November 2026. Every article path was checked against the host's own robots.txt before it was requested.

Written by

Lantad

Published .

A paywall is the one piece of a news site that is built to be hard to read, so whether AI crawlers see paywalled content has a plain answer on any given page: either the words arrived in the HTML or they did not. Lantad put that question to 246 article pages on 85 news and article-publishing hosts on 8 November 2026, sending every request as LantadBot/1.0 with redirects followed and no JavaScript executed. On the 35 pages whose own markup declared they were not free, the median page handed the crawler 789 words of main content, and 23 of the 35 handed it 500 words or more.

Common questions

Do AI crawlers see paywalled content?

On the pages Lantad read on 8 November 2026, frequently yes. 35 of 246 news and article pages declared a page-level isAccessibleForFree of false, and 23 of those 35 still delivered 500 or more words of main content to LantadBot/1.0 with no JavaScript executed. The median across the 35 was 789 words and the largest single page delivered 3,756. This is what the markup is designed to allow: Google documents it as the way a publisher distinguishes paywalled content from cloaking, which means supplying the text and declaring the wall.

What is isAccessibleForFree and who reads it?

It is a schema.org Boolean property, defined as a flag to signal that the item, event or place is accessible for free, carried by CreativeWork, Event and Place. Google's paywalled content documentation requires it and names two crawlers that read it, Googlebot and Googlebot-News. Read at source on 8 November 2026, the published crawler documentation from OpenAI, Anthropic and Perplexity does not mention paywalls, paywalled content or structured data at all, which says what those pages state rather than what those crawlers do.

Does declaring a paywall stop an AI crawler taking the article?

Nothing measured here suggests it does. The property is a description of the page, not an access rule, and the access rules live elsewhere: robots.txt for whether a crawler may fetch at all, and the server for what it returns. Of the 35 pages declaring themselves not free, 32 also named the paywalled region with a cssSelector, and the article text was still in the bytes on most of them.

How can I check what my own article pages hand a crawler?

Fetch the page with no JavaScript and read what came back, then compare it with what a reader sees. Lantad does this for a single URL and reports the gap with the evidence. On the 246 pages in this run the useful comparison was between the page-level isAccessibleForFree, the hasPart cssSelector and the main-content words actually delivered, and four of the 50 selectors named a class that was in no class or id attribute of the document.

See what AI can read on your site

Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.