Format & Spec · October 2026

llms.txt for Versioned Documentation

Documentation is the one site type where llms.txt already works — and the one where the version prefix undoes it. We fetched /llms.txt from 15 documentation hosts on October 21, 2026, then probed 9 version-pinned paths such as /v17/llms.txt and /docs/12.x/llms.txt. Eight hosts serve a real file at the root. Of the nine version-scoped paths, exactly one returns one.

What 15 Documentation Hosts Serve at the Root

Requested with a normal desktop user agent, redirects followed, bodies parsed for Markdown links. Eight hosts answered with a plain-text or Markdown body, seven did not — and the seven failures are not all 404s, which matters for the check further down.

Host Status Type Bytes Links
docs.aws.amazon.com200text/plain418,2902,247
docs.nestjs.com200text/plain28,440149
nodejs.org200text/plain15,01070
react.dev200text/plain14,571180
vuejs.org200text/plain7,4150 absolute
angular.dev200text/plain6,74588
docs.docker.com200text/markdown5,65437
svelte.dev200text/plain1,6767
fastapi.tiangolo.com404text/html91,075—
tailwindcss.com404text/html133,679—
kubernetes.io404text/html32,890—
go.dev404text/html26,974—
laravel.com404text/html86,133—
docs.python.org404text/html146—
docs.djangoproject.com200text/html54,135—

The last row is the interesting one. docs.djangoproject.com/llms.txt answers 200 and hands back 54,135 bytes of HTML — the version landing page at /en/6.1/. A checker that only reads the status code calls that a pass. It is not a file at all. Python's 146-byte 404 and Kubernetes' 32,890-byte 404 are the honest version of the same answer.

The Spec Rule That Makes Per-Version Files Legal

llms.txt has no version field. What it has is path scoping: a file covers the URLs beneath its own path, and when several files apply, the most specific one wins. That single rule is what makes /docs/12.x/llms.txt a legitimate address — it describes one version's subtree, and the root file describes everything else. The same mechanic is what makes per-language files work on multilingual sites.

The catch is discovery. Nothing probes /docs/12.x/llms.txt unless the root file points at it, and the only readers who will ever see a version file are the ones you tell about it. That asymmetry decides the split: the root file is your front door, and a version file is a room.

What 9 Version-Pinned Paths Actually Return

We requested a version-scoped path from each host that has versioned docs. One returned a real file. Two returned 200 with HTML. Six returned 404 — one of them only after a redirect had appended a trailing slash, and one after the path moved to a different prefix entirely.

Path probed Status Result
docs.aws.amazon.com/cdk/v2/guide/llms.txt200text/plain, 20,840 bytes
angular.dev/v17/llms.txt200text/html, 102,737 bytes
docs.nestjs.com/v10/llms.txt200text/html, 15,148 bytes
docs.docker.com/engine/llms.txt404text/html, 800,169 bytes
laravel.com/docs/12.x/llms.txt404redirect to /framework/docs/12.x/, HTML
docs.djangoproject.com/en/5.2/llms.txt404after a trailing-slash redirect
docs.python.org/3/llms.txt404text/html, 9,548 bytes
nodejs.org/docs/v20.x/llms.txt404text/plain, 14 bytes
nodejs.org/docs/latest/api/llms.txt404text/plain, 14 bytes

Node's 14-byte body is the cleanest failure in the set: an empty text/plain response is unambiguous, costs nothing, and tells a parser to stop. Docker's 800,169-byte HTML 404 is the opposite — roughly 141 times the size of its real 5,654-byte root file, spent to say “no”.

Four Patterns in Production

Unversioned root only — React, Docker and Angular each serve one file with no version segment anywhere in it. React's 14,571 bytes contain zero version mentions and 180 links; the site simply does not expose older majors. Cheapest to maintain, and the file never breaks on release day.

The latest alias — Node lists all 70 links under /docs/latest/api/. The alias moves with each release, so the index is written once and stays correct for years. What it does not give an agent is any way to reach v20 docs, which is consistent with the docs site retiring old majors.

Version inside the path, file scoped to it — the AWS CDK v2 guide is the only probe that returned a real file, 20,840 bytes of text/plain. AWS can afford this because its generator already emits a per-service .md twin and a per-service llms.txt; the version is just another path segment. The cost shows up in the root file: 2,247 links and 418,290 bytes in a single section, which is past any reasonable token budget — see size limits.

Tiers instead of versions — Svelte's 1,676-byte index does not list pages at all. It lists llms-small.txt (52,700 bytes), llms-medium.txt, llms-full.txt, plus four package-scoped subpath files, one of which is 481,379 bytes. Svelte never had to solve the version problem because there is only one current version, and the split is by depth rather than by release.

The Rules That Keep a Versioned Index Correct

The Five-Command Version Check

This runs in about a minute and catches the failure the status code hides. It is a narrower version of the general delivery check, aimed at the paths a release changes.

# 1. every supported major — status AND content type
for v in 10.x 11.x 12.x; do
  curl -sS -o /dev/null -w "$v %{http_code} %{content_type} %{size_download}\n" \
    "https://example.com/docs/$v/llms.txt"
done

# 2. the root file, first 8 lines — does it name its version?
curl -s https://example.com/llms.txt | head -8

# 3. what the links pin: latest alias or a fixed major?
curl -s https://example.com/llms.txt | grep -oE 'https?://[^)]+' \
  | grep -oE '/(v|docs/)[0-9]+[^/]*/' | sort | uniq -c | sort -rn

# 4. the 200-with-HTML trap: a catch-all answers the path with the wrong body
curl -sI https://example.com/docs/12.x/llms.txt | grep -iE '^(HTTP|content-type)'

# 5. same probe through the docs host, not just the marketing host
curl -sS -o /dev/null -w "%{http_code} %{content_type}\n" \
  https://docs.example.com/docs/12.x/llms.txt

Command 1 is the one to run on release day, and command 4 is the one that explains a green dashboard with a broken file: Angular's v17 path and Nest's v10 path both answer 200, and both answer in HTML. Run the checker against the body it returns and you get a structural failure rather than a status failure — which is the truth. Generating the files from the same route list the docs build already has, as the generator does from a sitemap, is what keeps the per-version set from drifting apart after two or three releases.

Versioned documentation is the strongest case llms.txt has: the audience is technical, the pages are already Markdown, and the wrong version is actively harmful. That is exactly why the API docs pattern and a version check belong together — the structure is easy, and the routing is where it dies.