D Docs · AI Computer Company Open Docs ↗

Review API

The review index, annotations with verdicts (including bulk), comments and threaded replies, and suggestions with accept/reject.

All paths are relative to https://docs.aicomputercompany.com/api. Background: Review markup (RFM).

Review index

GET /docs/:id/review-index

Read everything review-related in one call.

Response — 200:

{
  "source": "live",
  "fileVersion": "rev_…",
  "index": { "items": [ "…all review items with line numbers…" ] },
  "annotations": [
    { "id": "a1", "line": 12, "verdict": "conflict", "refs": ["a7"], "body": "…" }
  ]
}
  • source is "live" or "revision" depending on what was indexed.
  • index.items lists all review items (annotations, comments, suggestions) with line numbers.
  • annotations lists only the items carrying a verdict.

Annotations

Annotations are Layer 1: spec-review verdicts anchored to exact text.

Create an annotation

POST /docs/:id/annotations

Body:

FieldTypeRequiredDescription
anchorTextstringyesExact text in the document to anchor to (outside existing markup).
occurrencenumberno (default 1)Disambiguates repeated anchor text.
verdictstringyes"valid" | "question" | "conflict".
bodystringyesYour explanation.
refsstring[]noIds of conflicting annotations (for conflict).
checkpointbooleanno (default false)Create a revision for this single annotation.
messagestringnoRevision message.

Response — 201: {"id": "a1", "line": 12, "revision": null | {…}} Errors — 409 if anchorText is not found outside existing markup.

Verdict meanings: valid = requirement is clear & consistent · question = needs clarification · conflict = conflicts with another requirement (use refs).

Bulk annotations

POST /docs/:id/annotations/bulk

The primary verb for a review pass. One request, one revision, however many annotations.

Body:

FieldTypeRequiredDescription
annotationsarrayyesSame shape as single-annotation create.
checkpointbooleanno (default true)One revision for the whole pass.
messagestringnoe.g. "AI spec review".

Response — 201:

{
  "created": [{ "id": "a1", "…": "…" }],
  "failed": [{ "input": { "…": "…" }, "error": "…" }],
  "revision": { "…": "…" }
}

Failed anchors do not abort the rest — check failed and retry those with corrected anchors.

curl -X POST https://docs.aicomputercompany.com/api/docs/doc_abc123/annotations/bulk \
  -H 'Content-Type: application/json' -H 'x-actor-id: agent_demo' \
  -d '{"annotations": [
        {"anchorText": "must support offline mode", "verdict": "valid",
         "body": "Confirmed in section 3.2"},
        {"anchorText": "sync every 5 minutes", "verdict": "conflict",
         "body": "Conflicts with the realtime requirement", "refs": ["a1"]}
      ]}'

Resolve / delete an annotation

POST   /docs/:id/annotations/:targetId/resolve    body: {"resolution"?: "…"}
DELETE /docs/:id/annotations/:targetId

Both return {"ok": true, "revision": {…}}. Resolve marks status=resolved in the endmatter; delete removes the markup and the endmatter entry.

Comments & replies

Comments are Layer 2: verdict-less discussion, threaded and resolvable.

Create a comment

POST /docs/:id/comments

Body:

FieldTypeRequiredDescription
bodystringyesComment text.
anchorTextstringnoExact text to anchor to. Omit (with occurrence) for a document-level comment.
occurrencenumbernoDisambiguates repeated anchor text.

Response — 201: {"id": "c1" | null, "revision": {…}}

Reply / resolve

POST /docs/:id/comments/:parentId/replies    body: {"body": "reply text"}
  → 201 {"ok": true, "revision": {…}}        threaded under the parent

POST /docs/:id/comments/:targetId/resolve    body: {"resolution"?: "…"}
  → 200 {"ok": true, "revision": {…}}
curl -X POST https://docs.aicomputercompany.com/api/docs/doc_abc123/comments \
  -H 'Content-Type: application/json' -H 'x-actor-id: agent_demo' \
  -d '{"anchorText": "launch in Q3", "body": "Is this still the target after the slip?"}'

Suggestions

Tracked changes humans accept or reject in the editor, stored as CriticMarkup in the document text: {++added++}, {--deleted--}, {~~old~>new~~}.

Create a suggestion

POST /docs/:id/suggestions

Body:

FieldTypeRequiredDescription
kindstringyes"addition" | "deletion" | "substitution".
anchorTextstringfor additionInsert after this text.
targetTextstringfor deletion / substitutionText to delete or replace.
occurrencenumbernoDisambiguates repeated text.
textstringfor addition / substitutionThe new text.
bodystringnoRationale shown in the review rail.

Response — 201: {"id": "s1", "revision": {…}} Errors — 409 if anchorText/targetText is not found.

curl -X POST https://docs.aicomputercompany.com/api/docs/doc_abc123/suggestions \
  -H 'Content-Type: application/json' \
  -d '{"kind": "substitution", "targetText": "5 minutes",
       "text": "30 seconds", "body": "Match the SLA in section 2"}'

Accept / reject

POST /docs/:id/suggestions/:targetId/accept    → {"ok": true, "revision": {…}}
POST /docs/:id/suggestions/:targetId/reject    → {"ok": true, "revision": {…}}

Accept strips the marker and keeps the new text; reject mirrors that. Anyone with the document id (human or agent) can accept or reject.