RESOURCES · FIELD GUIDE

How to Write an llms.txt for Your API (with Examples)

The llms.txt format explained against the spec, a worked example for an API, the size discipline that matters, and real failure modes from live scans.

Read
8 min
Updated
2026-08-06
supabase.com/llms.txtmore examples
# Supabase Docs

For the complete documentation in a single file, see [Full Documentation](https://supabase.com/llms-full.txt).

## Documentation

- [Supabase - AI & Vectors](https://supabase.com/docs/guides/ai.md)
- [Supabase - AI Tools](https://supabase.com/docs/guides/ai-tools.md)

An llms.txt is the single cheapest discovery artifact an API team can ship, and it is also the one teams most often ship without checking whether an AI agent can actually use it. Across the Discry Index corpus, 64% of scanned APIs serve an llms.txt that passes a mechanical quality lint — present, structured with headings, and carrying described links under the size budget. The rest either have no file at all or have one that fails in ways the team never sees, because no human ever reads it. This guide covers the format as specified, a worked example you can adapt, the size discipline that separates a useful file from a useless one, and the failure modes we observe in live scans.

What llms.txt is for

llms.txt is a curated map of your documentation, written in Markdown, served at the root of your docs domain at /llms.txt. The spec was proposed by Jeremy Howard of Answer.AI in September 2024, and the problem it solves is stated plainly in the proposal: language models rely on website content, but their context windows are too small to ingest most sites whole, and converting JavaScript-heavy HTML into model-readable text is lossy and expensive.

For an API, the stakes are concrete. When a coding agent scaffolds an integration against your API, it fetches your public docs the way most agents do — plain HTTP, no JavaScript execution. A good llms.txt hands that agent your three canonical pages instead of leaving it to guess among four hundred. That is discoverability: whether agents can find and understand your API from its public surface, which is the piece of agent-readiness you can fix in an afternoon.

A sitemap already lists your pages, so it is worth being precise about the difference. The spec addresses this directly: a sitemap enumerates every indexable page, most of which an agent does not need, in aggregate far too large for a context window, with no external links and usually no model-readable versions. llms.txt curates. It says: start here, in this order, and here is what each link contains.

The format, straight from the spec

The llmstxt.org spec defines a specific structure, in a specific order. A conforming file contains:

  1. An H1 with the project or site name. This is the only required section.
  2. A blockquote with a short summary containing the key information needed to understand everything that follows.
  3. Zero or more plain Markdown sections (paragraphs, lists — anything except headings) with more detail about the project and how to read the linked files.
  4. Zero or more H2-delimited sections containing "file lists" — Markdown lists where each entry is a required hyperlink [name](url), optionally followed by a : and notes about the file.

One H2 name is reserved: a section titled Optional marks links that can be skipped when an agent needs a shorter context. Put secondary material there — changelogs, SDK pages, background reading.

The spec makes a second proposal that matters just as much for APIs: pages worth reading should also be published as clean Markdown at the same URL with .md appended. The two proposals work together. Your llms.txt is the index; the .md mirrors are what its links should point to. In our corpus, Ably ships a parallel .md version of every docs page with llms.txt linking straight to them, and Intercom does the same via a .md suffix — an agent can traverse either doc set without parsing a single rendered HTML page.

A worked example

Here is a complete llms.txt for a fictional but realistic payments API. It follows the spec exactly and adds the details an integrating agent actually needs — base URL, auth model, and pagination rules up front, links ordered by integration sequence:

# Ledgerline API

> Ledgerline is a payments API for invoicing and payouts. Base URL
> https://api.ledgerline.example/v1, Bearer-token auth, JSON request and
> response bodies. Rate limit: 120 requests/minute per key. Every doc
> linked below is served as clean markdown.

Sandbox keys are self-serve at the signup page. All list endpoints use
cursor pagination via `starting_after`. Amounts are integer minor units.

## Start here

- [Quickstart](https://ledgerline.example/docs/quickstart.md): Get a key and
  send your first invoice in five calls
- [Authentication](https://ledgerline.example/docs/auth.md): Bearer tokens,
  scopes, key rotation
- [Errors](https://ledgerline.example/docs/errors.md): Error envelope,
  retryable vs. terminal codes, backoff rules

## API reference

- [OpenAPI spec](https://api.ledgerline.example/openapi.json): OpenAPI 3.1,
  every endpoint, regenerated on deploy
- [Invoices](https://ledgerline.example/docs/invoices.md): Create, send,
  void; full state machine
- [Payouts](https://ledgerline.example/docs/payouts.md): Batch payouts,
  reconciliation, webhook events
- [Webhooks](https://ledgerline.example/docs/webhooks.md): Signature
  verification, retry schedule, event catalog

## Optional

- [Changelog](https://ledgerline.example/docs/changelog.md): Dated API changes
- [SDKs](https://ledgerline.example/docs/sdks.md): Python, TypeScript, Go

Two choices in this example do the most work. The blockquote carries the facts an agent needs before it follows any link — auth model, base URL, rate limit, pagination — so even an agent that reads nothing else leaves oriented. And the file links the OpenAPI spec directly: in Discry scans, a spec URL inside llms.txt is one of the first places our discovery probe looks for your machine-readable contract, and the same is true of agents in the wild.

For real implementations rather than a fiction, browse the llms.txt examples gallery. Some corpus standouts, cited for what their files do: 1Password publishes a curated index with per-link descriptions, workflow decision guides, and .md versions of every page. Render includes usage permissions, naming conventions, citation format, and priority guidance for agents. Paddle splits its index into per-section files to dodge truncation limits and pairs it with a .md sibling for every docs URL. And the FastHTML llms.txt is the file the spec itself uses as its worked example.

Size discipline: a map, a territory

The most common quality failure in the corpus has nothing to do with structure. Teams generate llms.txt automatically from their site index and ship a file that is technically valid and practically unusable. Ably's llms.txt is genuinely API-focused, with roughly 35 structured, described sections — at ~445KB, roughly ten times what an agent can comfortably load as an index. ClickHouse serves a 92KB file where an agent burns roughly 23,000 tokens on legal pages, blog newsletters, and campaign links before reaching documentation.

Discry's lint flags any llms.txt over 50KB, and the reasoning is mechanical: this file's whole value is that it fits easily in context alongside the docs it points to. A 500KB index defeats its own purpose. The division of labor the spec intends is: llms.txt stays small and curated; llms-full.txt is the separate, optional file that concatenates your full docs corpus for agents that want everything in one fetch. Publish both, and let each do its job. Verbosity has a measurable cost for every doc an agent reads, and the index is the worst possible place to spend tokens — the argument in full is in Token-Efficient API Docs.

Failure modes we observe in live scans

These come from keyFindings in Discry scan artifacts — patterns that recur across the corpus, cited at the check level.

The file covers the product, not the API. Slack's llms.txt exists and is well-structured, but it covers pricing, features, and customer stories rather than the developer platform — for an agent integrating with the API, it indexes the wrong site. AdButler's is product-focused and never routes agents to its actual API reference. If your company site and docs site share a domain, write the file for the integration reader.

Link targets an agent cannot read. An llms.txt that points at JavaScript-rendered pages hands the agent a map to rooms it cannot enter. Splunk's developer portal renders entirely via JavaScript, so its llms.txt path returns HTML and script rather than plain text. Attio's secondary docs alias serves a 352KB SPA shell for /llms.txt unless the agent negotiates content type — the real, complete file lives on the canonical docs domain. Fetch every link target with a plain HTTP client before you ship.

Dead pointers. One corpus API advertises its OpenAPI spec URL inside llms.txt, and that URL — along with every fallback path — returns 404. An agent that trusts your index and hits a dead link is worse off than one that never found the file. Stale links accumulate silently after docs migrations; regenerate or re-verify the file whenever URLs change.

The file exists, but in the wrong place. Twelve Data maintains a high-quality llms.txt at /docs/llms.txt, while the root path returns 404 — an agent following the root convention misses it entirely. The spec's location is the root path of the domain agents will probe.

No file at all. HubSpot's developer surface returns 404 for /llms.txt, and it has plenty of company among large, popular APIs. Adoption is high enough that absence now reads as a signal. The live pass rate, updated as the corpus rescans, is on the llms.txt signal page.

How to test yours

Test it the way an agent will encounter it — plain fetch, no JavaScript, no headers a generic client would not send:

curl -s https://yourdomain.com/llms.txt | head -50

Then check four things Discry's lint checks mechanically: the file has headings; it contains at least one absolute web URL in Markdown link form; at least one link carries a description after a : or dash; and the whole file is under 50KB. Then go one step past the lint: fetch every linked URL with the same plain client and confirm each returns readable text rather than an HTML shell or a 404.

llms.txt is one discovery signal among several — agents also probe your robots.txt for AI crawlers, look for an AGENTS.md in your repos (covered in our AGENTS.md guide), and try to fetch your spec directly. How all of these combine, and how we test comprehension behaviorally on top, is documented in the Discry methodology. The fastest way to see the whole picture for your own API is to run the scan.

What grade does an AI agent give your API? Discry your API — free — 60 seconds, no signup.

See where your API stands.

Drop your docs URL. The scan probes the same signals this guide describes — in about a minute, free.

Discry your API — free