D Docs · AI Computer Company Open Docs ↗

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):

FieldTypeDescription
markdownstringInitial document content.
titlestringDocument 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:

FieldTypeRequiredDescription
old_stringstringyesExact text currently in the document, including whitespace.
new_stringstringyesReplacement text. Must differ from old_string.
replace_allbooleanno (default false)Replace every occurrence instead of requiring uniqueness.

Outcomes:

ConditionStatusBody
Success200{"applied": true, "occurrences": n, "revisionHint": "rev_…"?}
old_string not found409{"error": "old_string not found in document"}
Found more than once without replace_all409{"error": "old_string is not unique; provide more context or set replace_all"}
old_string === new_string400error

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:

FieldTypeRequiredDescription
markdownstringyesThe entire new document.
checkpointbooleanno (default true)Save a revision for this push.
messagestringnoRevision 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'