llms.txt file format
The llms.txt format under v2 of the proposal - the one required heading, the order of parts, link lists, files in subpaths, Markdown page versions, and what the proposal does not include
- Edition
- v2, August 10, 2026
- Author
- Jeremy Howard, Answer.AI
- Format
- Markdown
- Required part
- the H1 heading only
What changed since the first edition is on the Changes in v2 page.
How an agent uses the file
Section titled “How an agent uses the file”- Sitepublishes the file at a known address
- GETllms.txt
/llms.txtname, description, lists of links - readsAgentpicks links for its question
- follows a linkMarkdown page
/docs/page.mdclean text without layout - Contextonly what the answer needs
The file does not retell the site. It shows where to go.
A minimal file
Section titled “A minimal file”One line with a heading is enough to conform to the proposal. In practice the minimum looks like this:
# Project name
> One or two sentences: what it is and who it is for
## Documentation
- [Quick start](https://example.com/quickstart.md): first steps in five minutesWhat the file consists of
Section titled “What the file consists of”The parts come in a strict order. Only the first one is required.
- # FastHTML
H1 headingrequired
The name of the project or site. Without it the file does not conform to the proposal. There is one heading.
- > FastHTML is a Python library for> server-rendered web apps built on HTMX.
Descriptionoptional
A blockquote with a short description: what the rest of the file cannot be understood without.
- Important:- the syntax is not compatible with FastAPI- React, Vue and Svelte are not supported
Detailsoptional
Any Markdown blocks except headings: paragraphs, lists, code.
- ## Documentation- [Quick start](https://example.com/quickstart.md): first steps- [API reference](https://example.com/api.md)
Section with linksoptional
An H2 heading and a list. An item is a link and an optional note after a colon.
- ## Optional- [Changelog](https://example.com/changelog.md)
Optional sectionoptional
A convention for secondary links: an agent may skip them when it needs a shorter context.
Links should lead to content that suits a model: Markdown versions of pages first of all. External addresses are fine when they help to understand the material.
Where the file lives
Section titled “Where the file lives”The file can sit in the site root or in any subpath. The second edition defines what that means.
- llms.txt covers the whole site
Directorydocs/
- llms.txt covers everything in /docs/
- guide.html
Directoryapi/
- llms.txt covers everything in /docs/api/
- users.html
Directoryblog/
- post.html
Page/docs/api/users.html
- Three files applyroot, /docs/ and /docs/api/
- The most specific one wins
/docs/api/llms.txt
Page/blog/post.html
- One file applies/blog/ has no file of its own
- The root file is used
/llms.txt
So someone who controls only part of another domain, such as a GitHub Pages project, can take part too.
The author of the proposal rejected a /.well-known/ address: such addresses exist only at the domain root, while llms.txt describes the path it sits in.
Markdown versions of pages
Section titled “Markdown versions of pages”The proposal suggests serving a clean Markdown version of a page next to the regular one. Two address forms are allowed.
| Page | First form | Second form |
|---|---|---|
/page.html | /page.html.md | /page.md |
/docs/ | /docs/index.html.md | /docs/index.md |
How an agent finds the files
Section titled “How an agent finds the files”The second edition recommends two standard relations. The first leads from a page to its Markdown version, the second to the llms.txt that covers the page.
rel="alternate"type text/markdown
- HTML page
/docs/page.html - alternateMarkdown version
/docs/page.html.md
rel="describedby"
- HTML page
/docs/page.html - describedbyllms.txt of the section
/docs/llms.txt
The relations can be sent in the page markup or in a response header. The second way also works for files that are not HTML.
<link rel="alternate" type="text/markdown" href="/docs/page.html.md"><link rel="describedby" href="/docs/llms.txt">Link: </docs/page.html.md>; rel="alternate"; type="text/markdown", </docs/llms.txt>; rel="describedby"location = /docs/page.html { add_header Link '</docs/page.html.md>; rel="alternate"; type="text/markdown", </docs/llms.txt>; rel="describedby"';}What the proposal does not include
Section titled “What the proposal does not include”Many sites publish llms-full.txt and llms-small.txt, and it is a useful practice. But the proposal cannot be cited as its source.
llms.txt
a map: where to go
namedescriptionlinks
- Described in the proposal
- Small: fits into the context as a whole
- The content sits behind the links
llms-full.txt
a corpus: everything in one file
pagepagepage
- Not in the proposal: a practice of docs platforms
- Can be very large: 67 MB at Cloudflare
- Handy when the whole text is needed without hops
| What | Status |
|---|---|
llms-small.txt | not in the proposal; a shortened version of the full text |
llms-ctx.txt, llms-ctx-full.txt | were tied to the llms_txt2ctx tool; removed from the second edition |
| Access control | the file forbids nothing; robots.txt does that |
| Security rules | the proposal text has none; the question is discussed in the repository |
A full example
Section titled “A full example”# FastHTML
> FastHTML is a Python library for server-rendered web apps> built on HTMX.
Important:
- the syntax is not compatible with FastAPI- React, Vue and Svelte are not supported
## Documentation
- [Quick start](https://example.com/quickstart.md): first steps in five minutes- [API reference](https://example.com/api.md): all methods and parameters
## Optional
- [Changelog](https://example.com/changelog.md)- [Contributing](https://example.com/contributing.md)Three places are highlighted, the ones an agent looks at first: the name, the description and the main links.
Parsing the file
Section titled “Parsing the file”The format is made for simple processing: regular expressions are enough.
import re
def parse_llms_txt(content: str) -> dict: result = {'title': '', 'description': '', 'sections': {}}
h1 = re.search(r'^# (.+)$', content, re.MULTILINE) if h1: result['title'] = h1.group(1)
quote = re.search(r'^> (.+)$', content, re.MULTILINE) if quote: result['description'] = quote.group(1)
section = None for line in content.split('\n'): if line.startswith('## '): section = line[3:].strip() result['sections'][section] = [] elif line.startswith('- [') and section: link = re.match(r'- \[(.+?)\]\((.+?)\)(?:: (.+))?', line) if link: result['sections'][section].append({ 'title': link.group(1), 'url': link.group(2), 'notes': link.group(3) or '', })
return resultValidation
Section titled “Validation”- The file opens at its address with status 200 and is served as text, not as an HTML page.
- The first heading is H1, and there is only one.
- There are no headings between the description and the first section.
- Every link opens.
- Links lead to content that suits a model.
A detailed list and typical mistakes are in Best practices.