llms.txt for Paywalled and Gated Content
Subscription businesses have the most valuable corpus on the web and the least obvious llms.txt file. Publish the locked URLs as if they were open and every fetch is a dead end. Publish nothing and an agent quietly fills the gap with a competitor's free summary. The middle path is a file that maps the whole library honestly — tier by tier — and gives agents a readable route into each one.
The Mistake Is Treating Access as Binary
Most gated sites approach this question as open versus paid, then pick one answer for the entire domain. But a subscription product rarely has two states. There is the marketing site, the free tier, the metered tier, the archive that unlocks after a year, the sample chapters, the public dataset behind the chart, and the members-only library. Each behaves differently to an unauthenticated fetcher, and each deserves a different line in the file.
The reason the distinction matters is mechanical rather than philosophical. An agent reading
/llms.txt is choosing which URLs to spend a fetch on. A URL that returns a login wall wastes
that fetch silently — no error, no recovery, and in the worst case a confident answer synthesised from a
three-sentence teaser. What you want is for the file to do the triage before the fetch happens.
Four Access Tiers Worth Encoding
| Tier | What a no-cookie fetcher gets | What belongs in llms.txt |
|---|---|---|
| Open | Full page, no wall | Normal entries, Markdown twin if you have one |
| Teaser | Stable summary page, full text locked | Listed, with the gate named in the description |
| Metered | Full page on first request, wall later | Listed once, with the meter explained; no duplicate entries |
| Locked | 401, 403 or a redirect to sign-in | Outside the index, or a single aggregate line with no per-article links |
The test that assigns a tier is simple: fetch the URL with no cookies and look at what returns. Not what
returns in your browser after the session cookie loads — what a bare curl sees. That is the
view every agent has of your site unless it is explicitly logged in, and most are not.
llms.txt Cannot Grant Access
This is the part worth being blunt about. The llms.txt proposal defines a Markdown file that helps models
navigate a site at inference time. It has no vocabulary for permissions, no authentication handshake and
no enforcement point. Access is decided by your server and by robots.txt; the split is the
same one covered in
llms.txt versus robots.txt and in the crawl-level view of
robots.txt for AI crawlers.
So if a page must not be read without a license, the lock has to live in the request path, not in the
index. A file that says "members only" above a URL that returns the full article to anyone with
curl is worse than no policy at all, because it documents an intention the server does not
enforce.
# robots.txt — enforcement layer, honoured by compliant crawlers
User-agent: GPTBot
Disallow: /members/
Disallow: /api/v1/reports/
# llms.txt — navigation layer, no permissions implied
## Members Library
- [Quarterly pricing index](/members/pricing-index): subscriber-only dataset, abstract public
- [Full methodology](/members/methodology): requires account The Teaser-First Pattern
For content you want cited but cannot give away, publish a real teaser page and point the index at it. A teaser is not a paywall screen with the words left out; it is a short, permanent, canonical page — the abstract, the method, the key number, two or three findings — that stands on its own and links onward to the locked body.
This gives an agent something honest to quote and something accurate to attribute. It also means the description in your index can state the limit plainly: public abstract, full dataset behind a subscription. An agent that knows it has read the abstract will hedge; an agent that thinks a three-line teaser was the article will not.
What Agents Actually Receive Behind a Gate
- Soft paywall, 200 status. The most common and least useful case. Headline, standfirst, a few paragraphs of body, then a subscribe prompt. Status says success; content says partial. Nothing in the response tells a fetcher that 90% of the document is missing.
- 401 or 403. The honest version. A fetcher can distinguish "not allowed" from "short", log it and move on instead of treating the wall as the page.
- Redirect to sign-in. Works, but it burns the hop and can land an agent on an
/account/login?next=…URL that then appears in its citation list. Redirect locked URLs to the teaser instead, and let the teaser carry the call to action. - Metered page on first visit. Full text for one request, wall afterwards. This is the one tier where an agent's experience is genuinely unstable — the same URL yields different content for different fetchers, in different orders, on different days.
You can watch this from the outside in one command per URL. Run it on a sample of ten gated pages and note which of the four shapes above each one produces:
for u in $(grep -oE 'https://[^)]+' llms.txt | head -10); do
echo "== $u"
curl -sSL -o /tmp/body.html -w '%{http_code} %{content_type} %{size_download} %{url_effective}\n' "$u"
wc -w /tmp/body.html
done A 200 whose body is a few hundred words and whose final URL is the same page is a soft paywall. A body under a hundred words with a sign-in URL is a redirect. Both are fixable, but only after you have seen them listed side by side.
Checklist Before You Ship
- Fetch every URL in the index with no cookies. Assign each one a tier from the table above.
- Drop locked URLs from the per-article lists; keep at most one aggregate line pointing at the pricing or access page.
- Make sure each gated entry that stays has a public teaser with its own canonical URL, and name the gate in the description.
- Put the enforcement in
robots.txtand the server, never only in the file's prose. - Do not list the same article twice — once as teaser, once as member URL — unless the two URLs serve genuinely different bodies.
- Re-run the validator after edits, then regenerate from source if the file is hand-maintained.
The broader question of what should never appear in the file at all — internal paths, staging hosts, personal data, draft URLs — is covered in what not to include in llms.txt. For gated sites the rule compounds: everything you cannot serve to a bare request should be absent from the index or explicitly marked as out of reach. Start from the llms.txt generator if you are building the file from scratch, and keep the per-tier descriptions short — one line each is enough to tell an agent what it is walking into.