Threads
Every thread is anchored to a range of document text and carries:- A kind:
commentorsuggestion. - A message history — anyone with comment access can reply.
- A status:
open,resolved(comments), oraccepted/rejected(suggestions).
POST /api/docs/{id}/threads, reply with POST /api/threads/{id}/messages, and resolve or reopen it as the discussion concludes. In the editor, the text highlight itself is the affordance: click a highlighted range to open its thread in the comments panel.
To start a comment from the editor, select the text you want to discuss and either click Comment in the selection toolbar or press Alt+C (Option+C on macOS). A composer opens in the margin — type your comment and press Enter to post it, or dismiss it without commenting by pressing Esc or clicking anywhere outside it.
Anchors that survive edits
Thread anchors are not character offsets or line numbers — they are attached to the text itself. As collaborators insert and delete text around (or inside) a commented range, the anchor keeps following the text it was attached to, even through simultaneous edits and edits made offline. Text typed right after a commented range never bleeds into it.Anchoring by quote (API callers and agents)
The editor computes a thread’s anchor (anchorJson — serialized Yjs relative positions) from the live document, which an API caller has no way to reproduce. So POST /api/docs/{id}/threads accepts a plain quotedText instead: give the exact text you want to comment on and — when anchorJson is omitted — the server locates that text in the live document and computes the anchor for you.
422 quote_not_found and no thread is created — re-read the content and copy the substring verbatim. A thread must be anchored, so every create supplies either anchorJson (the editor) or quotedText (API callers). To suggest a replacement over the quote, add kind: "suggestion" and proposedText.
Suggesting mode
While suggesting mode is on, insertions render as underlined pending text and deletions stay in the document struck through — nothing actually changes until review. Each contiguous editing burst becomes one suggestion, identified by itssid, and suggestions sync and merge exactly like any other edit — several people can suggest at once. Each burst also auto-creates a suggestion thread (its sid field links the two) that shows up in the comments panel with Accept and Reject buttons.
- Accept (
POST /api/threads/{id}/accept) keeps the inserted text and removes the delete-marked text. - Reject (
POST /api/threads/{id}/reject) removes the inserted text and restores the delete-marked text.
clientApplied: true so the server only records the status change. One caveat: undoing an accept restores the suggestion’s marks and text in the document, but the thread itself stays accepted. Exported markdown (GET /api/docs/{id}/content, snapshots, search) always represents the document without pending suggestions applied: insert-marked text is omitted, delete-marked text is kept.
Users with comment access but no write access edit in forced suggesting mode — that is exactly what commenting on a document means for them. One honest caveat: the suggesting-only restriction is enforced by the editor, not the server.
Legacy replacement suggestions
Agents and API callers can still create the older suggestion form: a thread withproposedText (“replace this range with that text”) and no sid. Accepting one splices the replacement over the anchored range in the live document. If the anchored text has been deleted (the anchor no longer resolves, or resolves to an empty range), the API returns a conflict and the thread stays open rather than applying the edit somewhere wrong. Rejecting a legacy suggestion never touches the document.
Sharing model
Access to a document is resolved from three layers:Scope: workspace or private
Scope: workspace or private
Every document (and folder) has a scope. Workspace documents are readable and editable by every member of the organization. Private documents belong to their owner and are invisible to everyone else until shared.
Public read-only links
Public read-only links
Enabling the public link mints an unguessable token; anyone with the URL
scribe.skeptrune.com/share/<token> can read (and only read) the document, no account required. Disable the link at any time to revoke access; enabling it again mints a fresh token, so old URLs stay dead. Only the document owner can manage the public link.viewer who opens a document sees every update as it happens but cannot change a single character. A commenter can edit only in suggesting mode — that is what powers forced suggesting mode — with the suggesting-only restriction enforced by the editor (see the caveat above).