---
name: versions
description: Version history, line diffs, and one-click restore for shares.
---

# Version history

Every approved write to a share's content is captured as an immutable row in the version history. The history covers content edited via:

- `anchorify <file>` updates (CLI).
- `POST /` updates (API).
- Edits from the dashboard's in-browser editor.
- Restores (rolling back to an older version appends a new `rollback` row — the restore itself is versioned).
- Approved suggestions (see [Suggestions](/docs/suggestions)).
- Agent-edit calls (`/api/v1/agent-edit`).

Every version stores the full content as it was at write time. Restoring an older version copies its content into the live share; the previous live content remains in history.

## Accessing the history

### Web

From the dashboard, open a share's actions menu (`⋯`) → **Version history**. The page lists every approved version newest-first, with author, timestamp, source (publish / rollback / suggestion / agent_edit), and byte count. Click any row to:

- **View** the version's full body (read-only).
- **Diff against the current version** — a line-by-line comparison.
- **Restore** — make the older version the live content.

### API

The full surface lives under `/api/v1/shares/:id/versions/*`:

- [`GET /api/v1/shares/:id/versions`](/docs/api#get-apiv1sharesidversions--list-a-shares-versions) — paginated list, newest first.
- [`GET /api/v1/shares/:id/versions/:vid`](/docs/api#get-apiv1sharesidversionsvid--fetch-a-single-version) — fetch one version with its body.
- [`GET /api/v1/shares/:id/versions/:a/diff/:b`](/docs/api#get-apiv1sharesidversionsadiffb--line-diff) — line diff between two versions.
- [`POST /api/v1/shares/:id/versions/:vid/restore`](/docs/api#post-apiv1sharesidversionsvidrestore--restore-a-version) — restore.

All four require cookie-session auth as an admin of the share's owner org. Per-user CLI tokens don't yet expose the version surface (this is a follow-up).

## Diff format

The diff endpoint returns a flat list of line-keyed entries:

```json
{
  "from": {"id": "...", "created_at": 1717400000000},
  "to":   {"id": "...", "created_at": 1717449600000},
  "lines": [
    {"kind": "equal",  "text": "# Q1 report"},
    {"kind": "remove", "text": "Looks great."},
    {"kind": "add",    "text": "Looks great. Updated 5/15."}
  ]
}
```

Lines are computed with a longest-common-subsequence diff. For very large or binary content, the diff falls back to `{"truncated": true, "lines": []}` with a `reason` field — the dashboard surface shows a "view both versions side by side" link in that case instead of attempting to render the diff.

## Restore semantics

Restoring version `V_old` does NOT delete any newer versions. The flow is:

1. The current `shares.content` is copied into `V_old.content` (this is a no-op since `V_old` is what we're restoring to).
2. A new version row is appended to history with `source='rollback'` and the same content as `V_old`. The rollback itself is versioned.
3. `shares.content` (and `filename`, `content_type`) flip to `V_old`'s values.
4. A `share.restore` audit event lands on the owner org's [audit feed](/docs/audit).

The previously-live version stays in history — you can restore back to it just like any other.

## Version status

Each version has a `status` of `approved`, `suggested`, or `rejected`:

- `approved` — the version is or once was the live content. Includes all `publish`/`update`/`rollback`/`agent_edit` sources, plus suggestions that were approved.
- `suggested` — an open proposed change. Not reflected in `shares.content` until an admin approves.
- `rejected` — a proposed change that was turned down. Kept in history for audit.

The dashboard list collapses `rejected` rows by default; pass `?status=approved` to the list endpoint to hide suggestions entirely.

## What's not in here

- **Branching / multiple parallel versions** — there's one linear history per share.
- **Per-line annotations** — comments attach to the whole share, not to a diff line.
- **History deletion** — there's no way to scrub an old version from history. If a version contains material that must be deleted, contact the operator.
