# Review comments and share links

Notes pinned to a moment of a video or a region of a frame, replies and resolve, review links for people without an account, and how agents take part.

Members who are commenters or above can leave comments on a file. On video and audio a comment can be pinned to a moment (`at_ms`, milliseconds) or a range (`until_ms`); on images and frames it can mark a region (`x`, `y`, `w`, `h` as fractions of the frame, 0 to 1). Replies are one level deep: replying to a reply joins the same thread.

## Read and write

| To | Call |
|---|---|
| A file's threads, in timecode order, with replies | `GET /v1/spaces/{sid}/nodes/{nid}/comments` (`?resolved=1` includes resolved ones) |
| Comment or reply | `POST /v1/spaces/{sid}/nodes/{nid}/comments` |
| Edit, resolve or reopen | `PATCH /v1/spaces/{sid}/comments/{cid}` with `body` or `resolved` |
| Delete | `DELETE /v1/spaces/{sid}/comments/{cid}` |

```sh tab=curl
curl -X POST "https://side.example.com/v1/spaces/$SPACE/nodes/$NODE/comments" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
  -d '{"body": "Music too loud under the line", "at_ms": 83500, "region": {"x": 0.1, "y": 0.6, "w": 0.3, "h": 0.2}}'
```

```ts tab=TypeScript
for (const c of await side.comments("Film A", "/Ep01/cut.mp4")) console.log(c.at_ms, c.body, c.replies?.length);
const note = await side.addComment("Film A", "/Ep01/cut.mp4", { body: "Music too loud", at_ms: 83_500 });
await side.resolveComment("Film A", note.id);
```

```python tab=Python
for c in side.comments("Film A", "/Ep01/cut.mp4"):
    print(c["at_ms"], c["body"], len(c.get("replies", [])))
note = side.add_comment("Film A", "/Ep01/cut.mp4", "Music too loud", at_ms=83_500)
side.resolve_comment("Film A", note["id"])
```

```sh tab=CLI
sidespace comments "Film A" Ep01/cut.mp4                       # open threads, by timecode
sidespace comments "Film A" Ep01/cut.mp4 --add "Music too loud" --at 1:23.5
sidespace comments "Film A" Ep01/cut.mp4 --resolve cmt_…
```

- Tokens need `comments:write` to write.
- Only the author edits the text. The author or an editor resolves and reopens. The author or a manager deletes.
- A comment records the version on screen (`version_id`), so notes on version 3 stay readable after version 4 lands.
- The person who saved the version, and the author of a comment being replied to, get a notification.

## Review links

Share a file or folder with people who have no account. With `--comments` (`can_comment: true`), they enter a name and can comment on the share page: the video pauses while they type, comments pin to the current moment, and markers sit under the timeline.

```sh
sidespace share "Film A" Ep01/cut.mp4 --comments
sidespace share "Film A" Ep01/Deliveries --upload --password "…"   # people can upload into the folder
sidespace shares "Film A"                                          # every link of the space
sidespace shares "Film A" --revoke shr_…
```

Over the API: `POST /v1/spaces/{sid}/shares` with `node_id`, `mode` (`view`, `upload` or `request`), `can_comment`, `password` and `expires_at` (the web app offers 1, 7 or 30 days). The answer has the link's `url`. Tokens need `shares:manage`. Each share counts the files people sent through it in `uploads`.

## Request files

Ask people without an account for files (location footage, a voice-over, a client's references) with an upload request. In the web app, pick **Request files…** on a folder.

```sh
sidespace share "Film A" Ep03/Footage --request "Episode 3 footage" --message "MOV or MP4, one folder per camera" --days 7
sidespace shares "Film A"          # how many files each link has received
```

- The link shows the title, the message, who asks and the due date. It never shows what's in the folder, and the folder's files can't be opened through it.
- Senders give their name (email optional). Each person's files land in a subfolder named after them, such as `Ep03/Footage/Mia Chen/a.mov`; clashing names get a number, nothing is overwritten, and each version is recorded under the sender's name.
- The page uploads one file at a time with progress, takes drag and drop, and only the file that failed needs sending again.
- You get a notification for every file, with the sender's name, email and the request's title.
- After the due date (`expires_at`) or when revoked, the link stops taking files. It can have a password.
- Over the API, `mode: "request"` needs a `title` (up to 200 characters) and takes an optional `message` (up to 4,000). The MCP tool `request_files` does the same and makes the folder if needed.

## For agents

The MCP tools `list_comments`, `add_comment` and `resolve_comment` let an agent read review notes, answer them and mark them done when it has made the change. Webhook events `comment.created` and `comment.updated` carry the comment, so a bot can pick up "@agent fix the color here" as it is written.
