Source material

When every page is the same shape, nothing stands out to a matcher

An API reference is usually the most complete documentation a company owns and the least useful once it is indexed. Completeness is achieved through generation, generation produces uniformity, and uniformity is the one property that makes retrieval hopeless. Ninety pages that differ only in the middle third all look equally relevant to a question about any of them.

Why this one is harder than it looks

Generated reference pages share a skeleton. The same section headings, the same preamble about authentication, the same rate limit note, the same response envelope description, the same error table. Only a small band in the middle is actually about this endpoint. When such a page is split into passages, several of those passages are pure boilerplate, identical to the boilerplate on every other page, and they compete against each other on every question. The passage that gets picked may well be the shared furniture from the wrong endpoint.

Parameter tables have a specific structural fault. Converted into a Markdown table, the rows are preserved, but the meaning of a cell depends on its column and its row header, and a passage boundary or a truncation can arrive mid-table. A type column reading string, integer, boolean, string is meaningless without the name column beside it. A description column full of Optional. Defaults to null is worse than meaningless, because it looks like content.

Examples are the part people actually want, and they are usually the part treated as decoration. The real question behind most reference lookups is what does a working call look like, not what are the permitted types of the fourth parameter. A reference where the example is a single generic snippet at the top, reused across every endpoint, has removed its best answer and left the part nobody was asking about.

Versioning turns a partly wrong answer into an actively harmful one. If two versions of the reference are indexed together, a question about a parameter can be answered from the version the customer is not on, and the answer will look completely authoritative because it is completely correct about the other version. An assistant that says it does not know is a minor disappointment. An assistant that confidently describes a path that was removed sends somebody debugging their own correct code.

What it has to contain

Structure rather than wording. A passage pulled out of this document has to stand on its own, because that is the only form in which it will ever be read.

Structural requirements
An opening sentence unique to the endpointOne line saying what this call does and when you would reach for it, phrased in words that appear nowhere else in the reference. This is the passage that has to distinguish the page from the other eighty-nine.
Parameters as prose lines, not only as a gridEach parameter written as a sentence carrying its own name, type, requirement and default in one place. The grid can stay for scanning. The sentence is what stays true when it is read alone.
A complete request and a complete response per endpointReal values, every required field present, and the actual shape that comes back including the fields people ask about. Not a generic template with placeholders reused across the reference.
Authentication restated in one line per pageThe full explanation lives on its own page. Every endpoint page carries a single sentence naming what has to be sent, so a passage about this endpoint is not silently missing the thing every call needs.
The version stated in the page and in the wordingThe version appears in the opening sentence and beside every path, so a passage extracted from it declares which version it is describing without relying on a heading or a URL that did not come along.

The rewrite, in order

Cut the boilerplate down to one line per page

Identify every block that is identical across endpoints: the authentication preamble, the rate limit paragraph, the error code table, the pagination explanation, the response envelope description. Each of these currently exists once per endpoint and is producing near-identical passages across the whole reference.

Move each to a single page of its own and replace it on the endpoint pages with one sentence that states the essential fact and links onward. Authentication becomes a line naming what must be sent. Errors become a line naming the two or three failures specific to this call, with the general table elsewhere.

The result is that most of the text on an endpoint page is now about that endpoint. That is the whole objective. A page whose passages are mostly unique to it will win the questions that are about it and lose the questions that are not, which is the behaviour you want and the opposite of what generated uniformity produces.

Repeat every parameter as a sentence

Under or beside the table, write one line per parameter that carries everything: the name, whether it is required, the type, what it does, and the default. Something like customer_id is required and is the identifier returned when the customer was created; sending an unknown one produces a not found response.

This looks like duplication and it is, deliberately. A table row is meaningful only in the context of its header, and that context is exactly what does not survive a passage boundary or a truncation. A sentence carries its own context in every word of it.

Take the same care with tables whose meaning depends on something a converter cannot keep: a merged header spanning two columns, a colour indicating deprecation, a dagger pointing at a footnote. All three become nothing. Whatever those devices were expressing has to be written into the cells themselves or into the prose beside them.

Treat the example as the answer, not the illustration

Give every endpoint its own worked example with real-looking values rather than placeholder tokens, showing every required field. Then show the response it actually produces, in full, including the fields people ask about most and not only the two that are interesting.

Add a second example for the common variation: the paginated case, the filtered case, the one with the optional parameter that everybody eventually needs. Two concrete examples answer more questions than a complete parameter table does, because most reference questions are really requests for a template to copy.

Write a sentence above each example saying what it does. That sentence is what a matcher has to work with, since code alone gives a meaning-based matcher very little to hold on to. Show me how to list customers created this month is answered by prose that says this lists customers created within a date range, sitting immediately above the code that does it.

Index one version and make the others unreachable

Decide which version the assistant is allowed to answer from, and index only that. If the reference is crawled, keep the crawl inside the current version's paths. If it is uploaded, upload one version's material. Two versions in one index is a machine for producing confidently wrong answers.

Where older versions have to remain answerable because customers are still on them, the version has to be in the wording of the text and not only in the path. State it in the opening sentence and beside every path in the body, so a passage extracted from the old reference announces that it is the old reference. A version that exists only in a URL segment is a version that vanishes the moment the passage is quoted.

For a deprecated version, the most valuable page is not the reference at all. It is one page saying this version is deprecated, here is the date it stops working, here is the current equivalent of each call. That page answers the question the customer actually has, which is what do I do now.

What happens if you skip it

The authoritative answer from the wrong endpoint

The characteristic failure here is a fluent, well-formatted answer assembled from boilerplate belonging to a different call. Somebody asks what the rate limit is for one endpoint, and the passage retrieved is the shared rate limit paragraph as it appears on another page. It is cited correctly. It may even be right. Nothing in the answer indicates which endpoint it came from.

The version of this that costs real money is the parameter answer. A question about required fields is answered from a table fragment, the name column having been left behind, and the reply lists types and requirements that cannot be checked against anything. The developer builds against it, gets a validation error, and concludes the documentation is wrong.

Worse still is the correct answer about the wrong version. It is specific, it is confident, and it describes a path that was removed two releases ago. The developer trusts it, because reference documentation is the one place they expect precision, and spends an afternoon establishing that their own code was fine all along.

Check it against this

Before you index it

  • Shared boilerplate exists once and is one line on each endpoint page
  • Every parameter is written as a sentence as well as a table row
  • No table relies on a merged header, a colour or a footnote marker
  • Every endpoint has its own request and response example with real values
  • A sentence above each example says in words what the example does
  • Authentication is named in one line on every page
  • Only one version is indexed, and the version is stated in the text

Questions

My reference is generated. Can I still do this?
Mostly, and in the generator rather than by hand. The per-parameter sentence, the unique opening line and the version statement are all things a template can emit from the same source that produces the table. The one thing worth writing by hand is the example, because a generated example is a placeholder and placeholders are what makes examples worthless.
Should I upload the machine-readable specification instead?
It can be uploaded as a structured text file, but it is a poor source on its own, because a specification is dense, highly repetitive and written for a code generator rather than a reader. If you use it, pair it with prose pages. The specification supplies precision, the prose supplies the words a question can match against.
How do I keep the old version answerable without poisoning the new one?
Give the old version its own assistant with its own material, or index only a single migration page for it rather than the whole old reference. Mixing two complete references into one index is the arrangement most likely to produce an answer that is exactly right about the wrong thing.

Keep reading

Try it on your own material

Upload a document or point it at your site, paste one line of HTML, then ask it something only your business could answer.