---
title: "GEO: optimize docs for AI search and answer engines"
description: Structure docs so ChatGPT, Claude, Perplexity and AI Overviews can read, trust and cite them; what Reed emits.
---

A developer who asks an AI tool how to authenticate against your API usually gets an
answer, not a list of links. The answer cites a source. Whether that source is your
documentation or someone's three-year-old forum post depends less on your search ranking
than on whether your page can be read, excerpted and quoted without losing its meaning.

Generative Engine Optimization (GEO) is the practice of writing and structuring content so
AI systems can understand it, trust it and cite it accurately. Most of it is ordinary good
technical writing, applied with a bit more discipline.

## How is GEO different from SEO?

SEO targets search engines that rank pages and send users to click through. GEO targets
systems that read pages, summarize them and cite them inside a generated answer.

|                   | SEO                                   | GEO                                      |
| ----------------- | ------------------------------------- | ---------------------------------------- |
| Goal              | Rank in search results                | Be cited in AI-generated answers         |
| Key signals       | Links, keywords, page authority       | Accuracy, structure, directness          |
| What the user does | Clicks a link                        | Reads an answer that quotes you          |
| Content that wins | Any well-structured page              | Scannable pages that answer a question   |

The overlap is large. A page that is accurate, well organized and quick to the point
does well in both. GEO is not a bag of tricks; it is clarity, measured by a reader that
cannot ask you a follow-up question. For the search side, see
[How to improve documentation SEO](/docs/guides/seo).

## How do AI systems decide what to cite?

Four properties matter most.

**Directness.** A page that answers in its first sentence gets quoted. A page that answers
after three paragraphs of background often gets skipped for one that does not make the
reader wait.

**Accuracy.** Answer engines favor sources that look reliable, and for documentation
reliability means one thing: the page describes what the product actually does today. A
stale example is worse than a missing one, because it gets quoted with confidence.

**Structure.** Meaningful headings, lists and labelled code blocks make it easy to lift
the right excerpt. An undifferentiated wall of prose forces the system to guess where one
idea ends and the next begins.

**Specificity.** "The API is flexible and scales with you" gives a model nothing to quote.
"The endpoint returns `429` once a key exceeds 100 requests per minute" is a citable fact.

## Write content an AI can cite

### Lead with the answer

Put the most important information first in every section. No preamble, no motivation,
no caveats before the point. This heading is answered in its first line:

````mdx
## How to authenticate API requests

Send your API key as a bearer token in the `Authorization` header:

```sh
curl -H "Authorization: Bearer $API_KEY" https://api.example.com/v1/events
```
````

This one makes the reader — human or model — dig for it:

```mdx
## Authentication

Authentication is an important part of working with any API. Before making requests,
it helps to understand how our authentication system is designed. Our API uses...
```

### Write headings as the questions people ask

AI systems match a user's query against heading text when choosing what to surface. A
heading phrased like the question wins over a heading phrased like a menu label.

```mdx
## How do I rotate my API keys?
```

is a stronger target than:

```mdx
## API key management
```

You do not need to turn every heading into a question. Do it where a real user would
type that question.

### Be exact about numbers, limits and behavior

Vague statements are not quoted. For every option, parameter or behavior you document:

- State the exact value or range.
- Say what happens at the boundary — the error, the fallback, the default.
- Show a concrete example.

"Requests are rate-limited" is a sentence an AI will paraphrase into something wrong.
"100 requests per minute per key; the 101st returns `429` with a `Retry-After` header" is
a sentence it will quote.

### Use one name per concept

A model builds its picture of a page from the whole page. If you call one thing an "API
key", an "access token" and an "API token" in consecutive paragraphs, the summary may use
the wrong term — or conclude there are three different things. Pick a name and keep it.
[Style and tone](/docs/guides/style-and-tone) covers terminology in more depth.

## Format for machine parsing

### Never skip a heading level

A heading hierarchy tells a parser how topics nest. Going from `##` straight to `####`
breaks that. Reed treats it as an error, not a style preference: a skipped level, or an
H1 written in the body, is `DS-A02` and fails [`reed check`](/docs/reference/cli/check).
Your frontmatter `title` is the page's H1; body headings start at `##`.

### Label every code block

Declare the language on every fence. It tells a model what it is reading, and lets it
surface the example that matches the user's stack.

````mdx
```python
import requests

response = requests.get(url, headers={"Authorization": f"Bearer {api_key}"})
```
````

When you show the same operation in several languages, put the fences in a `CodeGroup`,
one tab per language, and give each fence a `title` naming its language. Adjacent fences
in different languages without one raise `DS-D03`, which suggests `CodeGroup`. See
[Format code](/docs/authoring/formatting/code).

### Describe images in text

AI systems do not see your diagrams. If a diagram is the main explanation of a concept,
the same information needs to exist in words — in the alt text, the surrounding prose, or
both. "Architecture diagram" as alt text tells a model nothing; "Requests pass through the
edge cache, then the API gateway, then one of three regional workers" tells it the
architecture. An image with no alt text at all is `DS-A01`, an error. See
[Media](/docs/guides/media) and [Accessibility](/docs/guides/accessibility).

### Name things instead of pointing at them

Write "the API key", not "it" or "this value". Answer engines excerpt a paragraph and
drop its neighbors. A noun survives being cut out of context; a pronoun does not.

## What Reed emits for AI systems

Reed does its part at build time. There is nothing to enable, and nothing to host.

### Page title and description

Frontmatter is the strongest signal you control. Write the `title` as what the page
helps someone do, and the `description` as the one-sentence answer:

```mdx
---
title: How to authenticate API requests
description: Send your API key as a bearer token in the Authorization header. Examples in JavaScript, Python and curl.
---
```

The `description` does more work on a Reed site than it appears to. It becomes the
page's meta description, the `description` of the page's automatically generated
`TechArticle` structured data (when `site` is set), and the page's line in `llms.txt`. A page without one
contributes a bare link to `llms.txt` — so the model reading your index learns the page
exists and nothing about what it says. See [Pages](/docs/authoring/pages) and
[Structured data](/docs/site/structured-data).

### `llms.txt` and markdown mirrors

Every `reed build` writes an `llms.txt` at the output root — each page's title, URL and
description, grouped by your navigation — and a `.md` copy of every page at its own path,
so a client can fetch clean markdown instead of parsing rendered HTML. Neither needs
configuration. There is no `llms-full.txt`.

`reed dev` serves the `.md` mirrors, but writes no `llms.txt`, so check the index against
the output of `reed build`. Details are in [llms.txt and markdown mirrors](/docs/derived/llms-txt).

### Discovery

Every built page carries a `<link rel="alternate" type="text/plain">` pointing at
`llms.txt`, and a footer link to it. When `site` is set in `docs.json`, `robots.txt`
carries a comment line naming it as well. Reed also emits a `_headers` file so that
Cloudflare Pages, Cloudflare Workers static assets and Netlify serve `.md` as
`text/markdown` and `llms.txt` as `text/plain` instead of a download. See [Discovery](/docs/site/discovery) and
[Response headers](/docs/ship/headers).

### `robots.txt` and AI crawlers

If a `robots.txt` blocks AI user agents — `GPTBot`, `OAI-SearchBot`, `ChatGPT-User`,
`ClaudeBot`, `Claude-User`, `PerplexityBot`, `Google-Extended` — those tools cannot read
your documentation, and cannot cite it.

On Reed this is decided by one switch. `robots.txt` is written only when `site` is set,
and it contains a single rule for every user agent:

```txt
User-agent: *
Allow: /

Sitemap: https://docs.example.com/sitemap-index.xml
# llms.txt: https://docs.example.com/llms.txt
```

AI crawlers are therefore allowed by default. The only way to turn them away is
`seo.robots.index: false`, which changes the rule to `Disallow: /` and adds `noindex` to
every page's robots meta tag:

```json
{
  "site": "https://docs.example.com",
  "seo": { "robots": { "index": false } }
}
```

That blocks everyone — search engines included — not just AI crawlers. Reed has no
per-bot rules, no Content-Signal directives and no way to supply your own `robots.txt`.
If you need to admit Googlebot while refusing a specific AI crawler, Reed cannot express
it today; that decision has to happen at your host or CDN.

## Test how AI tools describe your product

Do this on a schedule, not once. Ask ChatGPT, Claude and Perplexity specific questions
about your product:

- "How do I authenticate API requests with [product]?"
- "What happens when I exceed the rate limit in [product]?"
- "Show me how to handle errors from [product]'s API."

Then check:

- Is your documentation cited at all?
- Is the cited content quoted accurately?
- Do the code examples work?
- Is the recommended approach the one you would recommend?

When an AI tool gets your product wrong, the usual cause is not the model. It is a page
that is ambiguous, missing, or contradicted by another page. Treat a wrong answer as a bug
report against your docs, and fix the page. [Improving your docs](/docs/guides/improving-docs)
covers turning feedback like this into changes.

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Does GEO replace SEO?">
    No. Search still sends a large share of documentation traffic, and many readers would
    rather open the page than trust a summary. The two are complementary: accurate,
    well-structured pages that answer questions directly do well in both, and work on one
    reinforces the other.
  </Accordion>
  <Accordion title="How long do GEO improvements take to show up?">
    Often faster than SEO work. Answer engines refresh their view of the web more often
    than traditional indexes, so clearer content can appear in answers within days or
    weeks. Authority and inbound links still count, and those take longer to build.
  </Accordion>
  <Accordion title="Do Google AI Overviews need anything special?">
    Not beyond the basics. AI Overviews draw on the same signals as Google Search, with
    extra weight on content that answers the specific query. A page that already ranks for
    a query is more likely to be used for it. Lead with the answer, be specific, keep the
    structure clean.
  </Accordion>
  <Accordion title="Should I write differently for AI than for people?">
    No. Clear and direct for a person is clear and direct for a model. Writing for the
    model at the expense of the reader produces pages that are unpleasant to read and not
    cited any more often. Write for your users; GEO follows.
  </Accordion>
  <Accordion title="Do I need to configure llms.txt on Reed?">
    No. Every reed build writes it, with a line per page built from your titles and
    descriptions. The one thing you control is the quality of those descriptions, so write
    one on every page. The dev server does not write it; inspect a real build.
  </Accordion>
</AccordionGroup>
