api.md
176 lines · skills/ce-proof/references/api.md at 3449230
Proof web API reference
Required read before any Proof HTTP call. Endpoints, operation tables, error handling, and lifecycle; the skill body carries the identity, credential, and safety boundaries.
Raw lines 1 to 4Web API
On Claude Code, each new curl pattern prompts for permission. Suggest the allowlist rule "Bash(curl * https://www.proofeditor.ai/*)" under permissions.allow if the user wants a quieter session; do not add it silently.
Auth on document surfaces (preferred first):
Authorization: Bearer <accessToken>x-share-token: <accessToken>?token=<accessToken>on the request URL
Canonical agent read/write (v3 only — do not invent other agent mutation paths):
- Read:
GET /api/agent/<slug>/v3/document - Write:
POST /api/agent/<slug>/v3/edit
Create a Shared Document
No authentication required on the public create route. Returns a shareable URL with tokens.
curl -sS -X POST https://www.proofeditor.ai/share/markdown \
-H "Content-Type: application/json" \
-d '{"title":"My Doc","markdown":"# Hello\n\nContent here."}'Response fields to keep:
{
"slug": "abc123",
"tokenUrl": "https://www.proofeditor.ai/d/abc123?token=xxx",
"accessToken": "xxx",
"ownerSecret": "yyy",
"shareUrl": "https://www.proofeditor.ai/d/abc123",
"_links": {
"read": "https://www.proofeditor.ai/api/agent/abc123/v3/document",
"edit": { "method": "POST", "href": "/api/agent/abc123/v3/edit" },
"delete": { "method": "DELETE", "href": "/api/documents/abc123" }
}
}Use tokenUrl as the shareable link. Extract slug, accessToken, and ownerSecret immediately — ownerSecret is required for cleanup while the doc is still unclaimed.
Read a Shared Document
If you already have a shared Proof URL, fetch with content negotiation or v3:
curl -sS -H "Accept: application/json" "https://www.proofeditor.ai/d/{slug}?token=<token>"
curl -sS -H "Accept: text/markdown" "https://www.proofeditor.ai/d/{slug}?token=<token>"
curl -sS "https://www.proofeditor.ai/api/agent/{slug}/v3/document" \
-H "Authorization: Bearer <token>" \
-H "X-Agent-Id: ai:compound-engineering"
# -> { ok, revision, title, markdown, comments[], suggestions[], mutationReady? }ACTIVE docs can be read tokenlessly via v3/document. Mutations, presence, and events need a tokenized credential. Tokenless GET /d/<slug> JSON reports role: null and no mutation links — that is truthful capability reporting, not a browser lock.
comments[] and suggestions[] on the v3 read are the source of review state. Use a comment's id for reply / resolve / unresolve. Use a suggestion's id for accept / reject. v3 supports resolving and unresolving comments; it does not support deleting comments. A comment with orphaned: true and an empty quote has lost its anchor — its thread is still readable and replyable, but do not treat its old target text as a live anchor.
When mutationReady is false, revision may be null — omit baseRevision and re-read shortly.
Edit a Shared Document
Send { by, baseRevision?, operations: [...] } to POST /api/agent/{slug}/v3/edit. Targets are visible text in markdown (not raw markdown syntax, not block refs). There is no base token. baseRevision (integer from the last read) is an optional conflict guard — omit it to apply at head. Idempotency-Key is optional; use one for important writes and retries.
curl -sS -X POST "https://www.proofeditor.ai/api/agent/{slug}/v3/edit" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-H "X-Agent-Id: ai:compound-engineering" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"by":"ai:compound-engineering",
"operations":[
{"op":"replace","find":"old visible text","with":"new text"},
{"op":"comment","on":"text to anchor on","body":"Is this still accurate?"}
]
}'Content operations:
| op | body |
|---|---|
replace | find, with (optional occurrence / before / after) |
insert | after or before + markdown (anchor: quote, heading:Title, section:Title, "start", or "end") |
delete | find |
set_document | markdown (whole-doc replace as a minimal diff; safe with live collaborators) |
Review operations:
| op | body | ||
|---|---|---|---|
comment | on, body (optional occurrence) | ||
reply | comment (id), body, optional resolve: true | ||
resolve / unresolve | comment (id) | ||
suggest | `kind: "insert"\ | "delete"\ | "replace", find, with? (with` required for insert/replace) |
accept / reject | suggestion (id) | ||
modify_suggestion | suggestion (id), with — replace the proposed text of a pending plain insert/replace suggestion |
suggest also accepts typed structural forms (command: "table.*", "format.*", "node.update", and atom target: {node: "image"|"hr"|...}); see https://www.proofeditor.ai/agent-docs before using them. A request holds at most 100 operations; set_document accepts at most 2 MiB of markdown.
Edit Strategy
Prefer the narrowest op:
- Literal or scoped prose change →
replace/insert/delete - Visible track-changes desired →
suggest(thenaccept/rejectas needed) - Whole-doc replacement →
set_documentonly when the user asks for full replacement or the change cannot be expressed narrowly
If a find/anchor matches more than once, the server rejects with TARGET_AMBIGUOUS and error.candidates — nothing is changed. Disambiguate with occurrence ("first", "last", or 0-based index) or before/after. Never assume silent first-match.
Content ops in one request apply atomically; review ops then apply in order. If a review op fails after content committed, the response is ok: false with partial: true — re-read and retry only the failed op (same Idempotency-Key safely replays).
Errors use { ok:false, error:{ code, message, retryable, opIndex?, target?, candidates?, current? } }. Codes: AUTH, NOT_FOUND, INVALID_REQUEST, TARGET_NOT_FOUND, TARGET_AMBIGUOUS, CONFLICT, TOO_LARGE, BUSY, PENDING, INTERNAL.
retryable: false— fix the request; do not blind-retryretryable: truewitherror.current— re-resolve targets againstcurrentand retry onceTARGET_AMBIGUOUS— addoccurrence/before/afterfromcandidatesBUSY— brief backoff and retry- Retryable
CONFLICTon a structural suggestion — a connected editor is on an older suggestion reader; retry after it reconnects. Non-retryableCONFLICT— the op crosses frontmatter, raw HTML, or unknown content; use a whole-block op or leave it acceptthat keeps failing withSUGGESTION_OWNERSHIP_MISSINGafter a fresh read — the suggestion is wedged;rejectit (always allowed) and recreate instead of retryingaccept- Settled
200withok:true— inspect returnedrevision/ document; chain without an extra read when the body is complete 202/PENDING— write may have committed; re-readv3/documentbefore chaining or reporting success
After every successful edit: confirm ok:true, confirm the intended text/comment/suggestion, then report the Proof link with a short summary.
Presence
curl -sS -X POST "https://www.proofeditor.ai/api/agent/{slug}/presence" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-H "X-Agent-Id: ai:compound-engineering" \
-d '{"name":"Compound Engineering","status":"reading","summary":"Joining the doc"}'Common statuses: reading, thinking, acting, waiting, completed, error.
Title
curl -sS -X PUT "https://www.proofeditor.ai/api/documents/{slug}/title" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{"title":"Updated document title"}'Raw lines 147 to 155Delete
Only owner credentials can delete:
curl -sS -X DELETE "https://www.proofeditor.ai/api/documents/{slug}" \
-H "Authorization: Bearer <ownerSecret>"Viewer, commenter, and editor accessToken values cannot delete. Success returns shareState: "DELETED"; later reads return deleted-document responses (410 on many routes).
Lifecycle: Do not auto-delete after every publish handoff — review docs must linger. Persist ownerSecret for the session. Delete when the user asks to remove/clean up, or when finishing an explicitly ephemeral scratch doc the user is done with.
Marks and privacy
Emptying the markdown (including set_document to blank/minimal content) does not scrub comment marks. Quote and commentary fields can remain readable via v3/document to anyone with the share credential. Without owner delete authority, content wipe is not a privacy cleanup — delete the document with ownerSecret (while unclaimed) or ask the owner after claim.
When the loop breaks
If a mutation keeps failing after a fresh read and one safe retry, call POST https://www.proofeditor.ai/api/bridge/report_bug with the failing request ID, slug, and raw response. The server enriches and files an issue. Ask before including the user's name/email.