LeafPage API

Publish a self-contained HTML report and receive a permanent URL. Reports are immutable snapshots, served from a cookieless content host.

The API lives on the application host https://leafpage.cc; published reports are served from https://leafpage.link. All requests and responses are JSON. The machine-readable spec is at /openapi.json.

For AI agents

There's a ready-to-install Agent Skill for this API — point your AI coding agent at it and it learns to publish reports, read them back, and later update itself. Machine-readable manifest: /.well-known/skills/index.json.

Create a personal access token first, in the portal (https://leafpage.cc) under the account menu → API Tokens. Already have the skill installed? Just tell your agent “update the LeafPage skill” — it checks the fixed manifest URL, verifies file integrity, and asks for your OK before installing anything.

Authentication

Requests authenticate with an Authorization: Bearer lp_… header. Personal access tokens are created in the portal under the account menu → API Tokens; the plaintext value is shown once at creation.

Scopes: reports:read (list, and read your own reports' content), reports:write (upload/modify, implies read), reports:delete. A token lacking the required scope returns 403.

Reading reports

Owners can also fetch a report's raw HTML back with a token, without a browser session: resolve the version's code via /api/config (content host base URL) and /api/group (current_code, or an entry from versions), then request {content}/{code}/ with the same Authorization: Bearer header — page assets fetch the same way. The live links /{name}/ and /@owner/{name}/ serve a platform shell, not the report itself, so always resolve to a pinned /{code}/ first. Full flow and edge cases: llms.txt.

Errors

Errors return { "error": "…" } with the status below. A target owned by another account is reported as 404, indistinguishable from one that does not exist.

StatusMeaning
400Malformed request — invalid JSON, missing index.html, bad name/encoding, or invalid field.
401Authentication required or not recognized.
403The token lacks the required scope.
404The target does not exist or is owned by another account.
409Name owned by another account, or rename collision.
413A file exceeds the per-file size limit.
429Rate limited — see the Retry-After header.
507A storage quota is full.