Documents API
Create, read, edit (str_replace), push, and export documents.
All paths are relative to https://docs.aicomputercompany.com/api.
Create a document
POST /docs
Body (all fields optional):
| Field | Type | Description |
|---|---|---|
markdown | string | Initial document content. |
title | string | Document title. |
Response — 201:
{
"document": { "id": "doc_…", "…": "…" },
"latestRevision": { "…": "…" },
"actor": { "…": "…" },
"shareUrl": "https://docs.aicomputercompany.com/doc_…",
"yjsWsUrl": "wss://…"
}
Give shareUrl to humans; use document.id for all API calls.
curl -X POST https://docs.aicomputercompany.com/api/docs \
-H 'Content-Type: application/json' \
-H 'x-actor-id: agent_demo' -H 'x-actor-name: Demo Agent' \
-d '{"markdown": "# Plan\n\nDraft.\n", "title": "Plan"}'
Get document metadata
GET /docs/:id
Response — 200: {"document": {…}, "latestRevision": {…}}
curl https://docs.aicomputercompany.com/api/docs/doc_abc123
Read raw markdown
GET /docs/:id/raw
GET /docs/:id/raw?numbered=1
Returns the current markdown as text/plain. With numbered=1 the output is cat -n style: a 6-character right-aligned line number, a tab, then the line content — designed for read-before-edit workflows.
curl 'https://docs.aicomputercompany.com/api/docs/doc_abc123/raw?numbered=1'
Always read immediately before editing. Humans may have changed the document since you last looked.
Edit (str_replace)
POST /docs/:id/edit
The preferred way to make changes. Semantics are identical to the local-file Edit tool agents already use.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
old_string | string | yes | Exact text currently in the document, including whitespace. |
new_string | string | yes | Replacement text. Must differ from old_string. |
replace_all | boolean | no (default false) | Replace every occurrence instead of requiring uniqueness. |
Outcomes:
| Condition | Status | Body |
|---|---|---|
| Success | 200 | {"applied": true, "occurrences": n, "revisionHint": "rev_…"?} |
old_string not found | 409 | {"error": "old_string not found in document"} |
Found more than once without replace_all | 409 | {"error": "old_string is not unique; provide more context or set replace_all"} |
old_string === new_string | 400 | error |
On the not-unique error, either include more surrounding context in old_string or set "replace_all": true.
The edit is applied to the live document as a minimal diff — collaborators see it instantly and their cursors are preserved.
curl -X POST https://docs.aicomputercompany.com/api/docs/doc_abc123/edit \
-H 'Content-Type: application/json' \
-H 'x-actor-id: agent_demo' \
-d '{"old_string": "## Old heading", "new_string": "## New heading"}'
Push full markdown
PUT /docs/:id/markdown
Full-document replace, for wholesale rewrites.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
markdown | string | yes | The entire new document. |
checkpoint | boolean | no (default true) | Save a revision for this push. |
message | string | no | Revision message. |
Response — 200: {"document": {…}, "revision": {…}}
Server-side the new content is diff-applied into the live document (never a full delete+insert), so collaborator cursors survive even a full push.
curl -X PUT https://docs.aicomputercompany.com/api/docs/doc_abc123/markdown \
-H 'Content-Type: application/json' \
-d '{"markdown": "# Rewritten\n\nAll new.\n", "message": "Full rewrite"}'
Export
GET /docs/:id/export.md # markdown download (latest saved revision)
GET /docs/:id/export.md?clean=1 # publishing export: strips all review markup
GET /docs/:id/export.clean.md # clean export of the LIVE document content
Clean export unwraps annotations and comments, rejects pending suggestions, and removes the endmatter block. Note the source difference: export.md exports the latest saved revision, while export.clean.md cleans the live content.
curl 'https://docs.aicomputercompany.com/api/docs/doc_abc123/export.md?clean=1'