API (plain HTTP; the forms above are the browser path)
Agent habit: use curl -i when a request creates, updates, or reveals bearer URLs/tokens. Treat status codes and Location or HX-Redirect headers as authoritative before reading the body.
GET /create
HTML editor form. POST it to create a document.
POST /create
Content-Type: application/x-www-form-urlencoded. Fields: title (optional, 256 chars), html (required, 5MB). Browser response: 303 to the edit URL with an HTML link list body. Link header: edit, canonical view, describedby meta. Agent response: send Accept: application/json for {id, edit_url, view_url, meta_url}. Generic Accept: */* response: plain text with the same fields.
POST /upload
Content-Type: multipart/form-data. Fields: file (required, .html or .htm), title (optional). Browser response: 303 to the edit URL with an HTML link list body. Link header: edit, canonical view, describedby meta. Agent response: send Accept: application/json for {id, edit_url, view_url, meta_url}.
Document endpoints
GET https://{id}.edit.bdf.pub/{edit_token} — edit page.
POST https://{id}.edit.bdf.pub/{edit_token} — update (fields: title, html).
GET https://{id}.edit.bdf.pub/{edit_token}/discover — authenticated agent discovery with state, ops, live WebSocket, publish, and comment workflow instructions.
Required continuous watch session: after creating a document, return edit_url and view_url to the developer. Then fetch edit_url + "/discover" and immediately start a background WebSocket watch session. Do not wait for a comment, requested change, or second prompt. Open the discovered live WebSocket URL, send {"type":"hello","actor":"agent:watcher"}, keep it open until the user stops or the work is finished, reconnect and send hello again if it closes, and watch state_snapshot, draft_replaced, text_updated, comment_added, comment_updated, requested_change_claimed, agent_run_renewed, and agent_run_finished so the agent continuously sees what the user is doing on the page.
When state.requested_changes contains a ready item, claim it with claim_requested_change using requested_change kind and id. Keep the returned agent_run_token private.
During an agent run, fix the draft with replace_document using base_version plus agent_run_id and agent_run_token, resolve addressed comments with resolve_comment and agent run credentials, renew long-running leases with renew_agent_run, and finish with finish_agent_run status done or open. The agent must not publish; publishing is a separate user action.
Agent-facing comments appear in requested_changes as ready work. Human-facing comments remain conversation and are not agent work.
DELETE https://{id}.edit.bdf.pub/{edit_token} — delete.
POST https://{id}.edit.bdf.pub/{edit_token}/regenerate — rotate the view token.
GET https://{id}.view.bdf.pub/{view_token} — published document.
GET /{id}/meta — document metadata.
Other
GET /sitemap.xml
GET /robots.txt
better than .pdf
.bdf
Self-contained HTML, with a stable URL. Two URLs per document: one to edit, one to share. No accounts, no databases, just the web.