Problem
Developer documentation usually describes an API and stops. The reader gets a token,
leaves for a terminal, types a call with placeholder values, and comes back to compare
the answer with the page. Each of those steps loses people, and the placeholders
(string, 0) teach nothing: a reader who has never seen an account id does not know
what one looks like until a call fails.
Our reference had the parts and not the whole. A signed-in reader could make a test
token in one click and the playground sent it, but the fields started as string,
only reads were allowed from the docs, and a streaming route failed after ten seconds
because the library's "Send" waits for an answer to end and a stream never does.
Proposal
The reference is an API client that acts as the reader, with the reader's token and nothing else. Four rules.
The token is the only credential
Every call the pages make to the API carries the selected token in the Authorization
header and never a session. The API answers the docs origin alone, with credentials
disallowed, so a page on any other origin gets no answer and a call from the docs can do
exactly what the token may do, decided by the gateway and the service as for any other
client. Tokens live in the reader's browser only; the platform keeps none for the docs.
The one exception is making a test token, which is the signed-in reader's own write on their own account, allowed from the docs' pages alone: every read scope, seven days, listed and revocable in the console.
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
Every field the page can know is filled
A parameter's name says what it is, and the token says whose. Where the reader's own value is known, it is offered in the field, filled in where there is one right value, and anything else can still be typed:
| Field | From |
|---|---|
the account (org_id, account_id, as a parameter or a body field) |
the token's account, the reader's other accounts listed; a foreign account warns before the call |
| a webhook endpoint, inbox or delivery | the account's own, asked with the token |
| event types | the catalogue |
| an audit action, person or event id | what the account's last fifty audit entries hold |
| a delivery's status, a series' grouping, a statistics window | the fixed sets, per route |
| a digest | the latest published |
| a date range or a week | this month, last month, the last thirty days |
| any enumerated schema | its values |
Each lookup is one read with the token, once per token for the page's life, only on the page whose field asks for it. A token without the scope gets an empty list, never an error. A new route gets all of this by naming its parameters as the rest of the API does and by its OpenAPI document; nothing is registered by hand.
Every method, and streams
The docs may send every method a route has, so a webhook endpoint can be created, tested, rotated and deleted from its pages. A route that answers a stream of events gets Run and Stop instead of Send: Run opens the stream from the browser with the token and the fields' values, each event is shown as it arrives with its name, number and time, the last two hundred are kept, an error event ends it, Stop closes it, and so does leaving the page or changing the token.
The answer is shown as it came
The first call on the front page and in the quickstart, every playground answer, every stream event and every refusal are shown as the API sent them, pretty-printed and highlighted by their content type, with the status and the time taken. Nothing is reshaped, and nothing is shown that was not received.
Alternatives considered
A server-side proxy on the docs host. The docs would call the API with the reader's session and the page would never hold a token. That makes the docs a confused deputy: any page that can be made to issue a request acts as the reader. A token the reader chose, scoped and expiring, is the smaller surface.
A separate explorer application. One more place to sign in, keep in step with the reference and explain. The reference already lists every public route from the live OpenAPI document; it is the explorer.
Collections for a desktop API client. Useful to some readers and offered later; they do not know the reader's accounts or endpoints, and they put the first call outside the page that explains it.
Reads only from the docs. The state before this RFC. A reader could list endpoints and not make one, and left for a terminal at the moment the docs mattered most.
Decision
Decided 2026-10-07. Built as proposed and in use on the developer docs; the status log records what shipped. Feedback is folded in as entries below.
Publication
The developer docs: the front page and the quickstart run the first call; every reference page fills its fields from the reader's data and sends every method; the stream route has Run and Stop; the server-sent events guide says so; the changelog carries the entry. No new API routes.
Status log
- 2026-10-03: opened, with the work live on the docs.
- 2026-10-04: the samples beside each reference operation lead with our SDK. A switcher
offers the call made with the SDK in Rust, TypeScript, Python, Go, C# and Java (each
labelled SDK, TypeScript by default) and the raw request for curl, fetch, Python httpx
and requests, and Go net/http. The SDK snippets come from the generator (
iohr sdk examples), not from hand: every one is built against its runtime in the SDK repository's compile tests, and the docs build reads them from a file committed next to the API document, so the build runs no generator and fetches nothing. The raw samples are written from the playground's values and carry the reader's selected token, which stays in the browser. The choice persists across pages and follows the site's other code tabs. The build fails when a public operation lacks a sample in any SDK language or a curl sample. - 2026-10-07: Decided: built and live. The SDK-first samples and their fixes (#258, #259, #260) run in docs-ui at 3a40912a.