---
title: txtfirst spec 0.1
desc: Four requirements that make a site txtfirst compliant. Source of truth in markdown, content negotiation, discovery, and machine-legible figures.
order: 2
---

# txtfirst 0.1

A site is txtfirst compliant when it meets all four requirements below. Compliance is
per origin, not per page. The key words MUST, SHOULD and MAY follow RFC 2119.

## R1. One source, in markdown

Each addressable page MUST be generated from exactly one markdown file. That file is
the canonical document. The HTML MUST be derivable from it. If a fact appears in the
HTML that is not in the markdown, the site is not compliant.

This is the whole spec in one line. The other three requirements only say how to hand
that file to a client.

## R2. Content negotiation

For a page at `/path`, the origin MUST serve the markdown source when either
condition holds:

1. the request carries `Accept: text/markdown`, or
2. the request path is `/path.md`

The response MUST use `Content-Type: text/markdown; charset=utf-8`. The two forms MUST
return byte-identical bodies.

The HTML response MUST advertise the source with both a link header and a link
element:

```
Link: </path.md>; rel="alternate"; type="text/markdown"
<link rel="alternate" type="text/markdown" href="/path.md">
```

Requirement 2 exists because most clients cannot set headers. Requirement 1 exists
because the URL suffix is a hack and the header is the correct mechanism. Ship both.

## R3. Discovery

The origin MUST serve `/.well-known/txtfirst.json` listing every page, its HTML URL,
its markdown URL and its size in bytes. The origin SHOULD also serve `/llms.txt` and
`/llms-full.txt` for clients that already look for them.

```json
{
  "txtfirst": "0.1",
  "negotiation": { "header": "Accept: text/markdown", "suffix": ".md" },
  "index": "https://example.com/llms.txt",
  "pages": [
    { "url": "https://example.com/rates",
      "markdown": "https://example.com/rates.md",
      "title": "Rates", "bytes": 2214 }
  ]
}
```

`robots.txt` MUST NOT block the markdown paths, and SHOULD carry explicit Content
Signals stating whether the content may be used for search, for AI input and for AI
training. Silence is not consent and it is not refusal either. State it.

## R4. Figures that do not require vision

A compliant page MUST NOT put information in a raster image that appears nowhere in
the markdown. In practice:

- Diagrams SHOULD be inline SVG with real `<text>` elements, or ASCII inside a fenced
  code block. Both are text to a parser and both survive a copy and paste.
- Charts MUST be preceded or followed by the table they were drawn from.
- `alt` MUST state the fact, not describe the picture. `alt="Q3 occupancy 71 percent,
  up 4 points from Q2"` and not `alt="bar chart"`.
- Photographs MAY be raster. A photograph carries no facts, so nothing is lost.

R4 is the requirement people skip. It is also the one that makes the other three
worth having, because a page whose numbers live inside a PNG is unreadable no matter
how cleanly you serve it.

## Conformance

An origin claiming txtfirst 0.1 SHOULD publish the result of a self test at
`/.well-known/txtfirst.json`. There is no certifying body and there will not be one.

## Non-goals

txtfirst does not define a markdown flavour, does not require you to drop your
existing site, does not replace schema.org, and does not care what your HTML looks
like. It defines where the truth lives and how to ask for it.

## Changes

- **0.1**, 4 September 2026. First public draft. Open questions: whether R2 should
  require `Vary: Accept`, and whether a compliant origin must serve markdown for
  paginated or personalised pages at all.
