Suggest changes
Suggestions are the "I'd like to propose an edit" flow. The recipient of a share submits a full proposed new version; the owner approves (and the suggestion becomes the live content) or rejects (and the proposal is archived in version history).
It's the same mental model as Google Docs' "Suggesting" mode, but the unit of proposal is a whole-content version rather than per-line diffs. The diff is computed on the fly when the owner reviews.
Who can suggest
A user can submit a suggestion against a share if they satisfy any of:
- Org admin of the share's owner org. (Admins can also edit directly — they go through the suggest flow when reviewing a recipient's work as if they were a recipient.)
- Project member (viewer or editor) on the share's project.
- Share editor (granted via
share_members— see Doc-level roles). - Org viewer (cross-project read access — see Doc-level roles).
- Anyone with the URL, if the share has
link_permission='can_suggest'(see Link permissions).
Anonymous suggestions (no Anchorify account, link permission can_suggest) are explicitly deferred — they require captcha + rate-limit hardening (V4 #20). Today the suggester must be signed in.
Recipient flow
- Open the share. The renderer shows a Suggest changes button under the body when the caller satisfies
suggestion.create. - Click it. The page opens an editor pre-filled with the current content.
- Make edits, click Submit suggestion. The proposal lands as a
suggestedversion on the share's history. - The share's owner gets a
suggestion.submittednotification. You get asuggestion.approvedorsuggestion.rejectednotification when they decide.
Track all your open suggestions across every share at /dashboard/suggestions — or via GET /api/v1/me/suggestions.
Owner flow
The owner sees pending suggestions in two places:
- Bell notification — clicking a
suggestion.submittednotification opens the suggestion review page. - Inbox —
/dashboard/inboxlists every pending decision across the org (access requests + suggestions). - Per-share — the share's version history (
/dashboard/shares/:id/versions) shows suggestions inline with the approved versions, markedsuggested.
Open a suggestion to see:
- A diff of the suggested content against the current live content.
- The suggester's username + timestamp.
- The full proposed body (collapsible).
- Approve and Reject buttons.
Approving
Approving copies the suggested content into shares.content, flips the version row to status='approved', and emits a suggestion.approved notification to the suggester. The audit log records the approval (share.suggestion.approve).
The approved version becomes the new live content; older approved versions are still in history. Restoring rolls back to any prior version, including the one that was live before the approval.
Rejecting
Rejecting flips the version row to status='rejected' (no content copy) and emits suggestion.rejected to the suggester. The rejected version stays in history for audit. A rejected suggestion cannot be re-approved — the suggester must submit a new one.
API
POST /api/v1/shares/:id/suggestions— submit.POST /api/v1/shares/:id/suggestions/:vid/approve— approve.POST /api/v1/shares/:id/suggestions/:vid/reject— reject.GET /api/v1/me/suggestions— your submitted suggestions across every share.GET /api/v1/shares/:id/versions?status=suggested— pending suggestions on a specific share you own.
What's not in here
- Per-line suggestions — proposals are whole-content. Per-line markup is a follow-up.
- Inline reply threads on a suggestion — comment on the share itself for discussion; the suggestion is a single submit-then-decide event.
- Withdrawing a suggestion — a suggester can't currently retract a pending suggestion. Workaround: ask the owner to reject it.
- Anonymous suggestions — gated behind V4 #20 (captcha + rate-limit hardening).