API reference pages
An endpoint page is an ordinary Markdown file. The apidocs.php partial reads
its front matter and replaces the rendered body with a reference layout:
method + path header, parameter tables, response list, auto-generated
cURL/JavaScript/PHP samples, and a live "Try it" console.
Wiring
- Drop
apidocs.phpinSepoEngine/App/views/layouts/docsComponents/apidocs/. - Include it in
docs.phpalongside the other partials, before the membership gate (same position aspolls.php). - No routes and no store. "Try it" calls the documented endpoint directly with the page's CSRF token and the visitor's session cookie.
Recognising a page
A page renders as an endpoint when either is true:
- front matter has
api: true - the page lives under an
api/directory
A page with api_dir: <dir> renders the searchable index of every endpoint
in that directory, appended below its own body — the same pattern as
polls_dir and forms_dir.
Front matter
Rows are pipe-separated, fields within a row are colon-separated. This is the same convention the forms and polls modules use, and it sidesteps the docs renderer's inability to handle pipes inside Markdown table cells.
method— GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Defaults to GET.path(orendpoint) — required, e.g./api/v2/polls/vote. Use{name}for path placeholders.baseUrl— only when the API is on a different host. Otherwise the samples resolve against the current app base.auth—none/session/admin/apikey. Drives the badge only; real enforcement stays in the route.summary— one line under the header.tags— pipe-separated, searchable on the index.deprecated: true— adds a badge.tryIt: false— hides the console for destructive endpoints.
Parameter groups, each name:type:required:description:
params(orpathParams) —{name}placeholders in the pathquery(orqueryParams)headersbody(orbodyParams)
The description is the remainder of the row, so it may contain colons. Mark a
parameter required with required, true, yes or 1; anything else reads
as optional.
responses is status:description per row and sorts numerically.
Examples
Write them in the body as fenced code under a heading named Request or
Response <status>. The partial lifts those blocks into the sticky panel and
removes them from the prose, so a page reads sensibly whether or not the
partial runs.
Request
{ "poll": "polls/which-feature-next", "option": 2 }
Response 200
{ "status": "ok" }
Multiple ## Response <status> blocks become tabs. Syntax highlighting from
the docs renderer is preserved.
The authored request example is also the payload used for the generated
samples and prefilled in the console. Without one, a skeleton is built from the
declared body parameters.
A single-line exampleRequest: front-matter value works as a fallback, but the
fenced block is better — it's multi-line and highlighted.
What the partial builds for you
- Samples — cURL,
fetch, and PHP cURL, each with the right headers, the payload, and a copy button. - Try it — one input per declared path and query parameter plus a JSON body
box. It substitutes
{name}placeholders, appends the query string, attachesX-CSRF-Tokenfromwindow.SepoDocsConfig, sends withcredentials: 'same-origin', and prints the status, elapsed time and pretty-printed body. It hits the real endpoint as the signed-in user, so settryIt: falseon anything destructive. - Parameter tables — built as HTML, so descriptions can contain pipes and colons freely.
Index page
---
title: API reference
api_dir: api
---
Every endpoint the platform exposes.
Each card shows the verb, path, summary and auth badge, and the search box matches path, title, summary, method and tags.