Comments
Comments can be anchored to specific text ranges in a document, support threading via replies, and can be resolved when addressed.
Comment object
Section titled “Comment object”{ "id": "comment-uuid", "document_id": "doc-uuid", "author_id": "user-uuid", "parent_id": null, "body": "This section needs more detail.", "anchor_text": "Introduction", "anchor_start": 0, "anchor_end": 12, "anchor_context": "# Introduction\n\nThis document covers...", "resolved": false, "resolved_at": null, "resolved_by": null, "created_at": "2026-03-13T12:00:00.000Z", "updated_at": "2026-03-13T12:00:00.000Z", "author": { "id": "user-uuid", "display_name": "Jane Doe", "avatar_url": null }}| Field | Type | Description |
|---|---|---|
id | UUID | Comment identifier |
document_id | UUID | Parent document |
author_id | UUID or null | Comment author (null for anonymous share link users) |
parent_id | UUID or null | Parent comment ID for threaded replies |
body | string | Comment text |
anchor_text | string or null | The highlighted text this comment is anchored to |
anchor_start | int or null | Character offset start in the markdown |
anchor_end | int or null | Character offset end in the markdown |
anchor_context | string or null | Surrounding paragraph for context |
resolved | boolean | Whether the comment has been resolved |
resolved_at | ISO 8601 or null | When it was resolved |
resolved_by | UUID or null | Who resolved it |
author | object | Embedded author profile |
List comments
Section titled “List comments”GET /api/documents/:id/commentsReturns all comments on a document, sorted by created_at ascending.
Request
Section titled “Request”curl https://notebind.com/api/documents/DOC_ID/comments \ -H "Authorization: Bearer nb_sk_YOUR_KEY"const res = await fetch("https://notebind.com/api/documents/DOC_ID/comments", { headers: { "Authorization": "Bearer nb_sk_YOUR_KEY", },});const { data, error } = await res.json();import requests
res = requests.get( "https://notebind.com/api/documents/DOC_ID/comments", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"},)data = res.json()Response 200 OK
Section titled “Response 200 OK”{ "data": [ { "id": "comment-uuid", "body": "Great introduction!", "anchor_text": "Hello World", "anchor_start": 2, "anchor_end": 13, "resolved": false, "parent_id": null, "author": { "display_name": "Jane", "avatar_url": null }, "created_at": "2026-03-13T12:00:00.000Z" } ], "error": null}Share token access
Section titled “Share token access”Any share token (view, comment, or edit) can list comments:
curl "https://notebind.com/api/documents/DOC_ID/comments?share_token=TOKEN"const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments?share_token=TOKEN");const { data, error } = await res.json();import requests
res = requests.get( "https://notebind.com/api/documents/DOC_ID/comments", params={"share_token": "TOKEN"},)data = res.json()Create a comment
Section titled “Create a comment”POST /api/documents/:id/commentsRequest body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | Comment text |
parent_id | UUID | No | Parent comment ID for replies |
anchor_text | string | No | Highlighted text |
anchor_start | int | No | Character offset start |
anchor_end | int | No | Character offset end |
anchor_context | string | No | Surrounding paragraph |
Request
Section titled “Request”curl -X POST https://notebind.com/api/documents/DOC_ID/comments \ -H "Authorization: Bearer nb_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "This paragraph needs more detail about the API.", "anchor_text": "the API", "anchor_start": 45, "anchor_end": 52 }'const res = await fetch("https://notebind.com/api/documents/DOC_ID/comments", { method: "POST", headers: { "Authorization": "Bearer nb_sk_YOUR_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ body: "This paragraph needs more detail about the API.", anchor_text: "the API", anchor_start: 45, anchor_end: 52, }),});const { data, error } = await res.json();import requests
res = requests.post( "https://notebind.com/api/documents/DOC_ID/comments", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"}, json={ "body": "This paragraph needs more detail about the API.", "anchor_text": "the API", "anchor_start": 45, "anchor_end": 52, },)data = res.json()Response 201 Created
Section titled “Response 201 Created”Returns the created comment with embedded author.
Share token access
Section titled “Share token access”Comment and edit share tokens can create comments:
curl -X POST "https://notebind.com/api/documents/DOC_ID/comments?share_token=COMMENT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"body": "This looks good!"}'const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments?share_token=COMMENT_TOKEN", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ body: "This looks good!" }), });const { data, error } = await res.json();import requests
res = requests.post( "https://notebind.com/api/documents/DOC_ID/comments", params={"share_token": "COMMENT_TOKEN"}, json={"body": "This looks good!"},)data = res.json()Creating a reply
Section titled “Creating a reply”To reply to an existing comment, include parent_id:
curl -X POST https://notebind.com/api/documents/DOC_ID/comments \ -H "Authorization: Bearer nb_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"body": "Good point, I will fix this.", "parent_id": "PARENT_COMMENT_ID"}'const res = await fetch("https://notebind.com/api/documents/DOC_ID/comments", { method: "POST", headers: { "Authorization": "Bearer nb_sk_YOUR_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ body: "Good point, I will fix this.", parent_id: "PARENT_COMMENT_ID", }),});const { data, error } = await res.json();import requests
res = requests.post( "https://notebind.com/api/documents/DOC_ID/comments", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"}, json={ "body": "Good point, I will fix this.", "parent_id": "PARENT_COMMENT_ID", },)data = res.json()Get a single comment
Section titled “Get a single comment”GET /api/documents/:id/comments/:cidReturns a single comment. Requires document owner or comment author access.
curl https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID \ -H "Authorization: Bearer nb_sk_YOUR_KEY"const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", { headers: { "Authorization": "Bearer nb_sk_YOUR_KEY" }, });const { data, error } = await res.json();import requests
res = requests.get( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"},)data = res.json()Update a comment
Section titled “Update a comment”PATCH /api/documents/:id/comments/:cidRequest body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
body | string | Updated comment text (author only) |
resolved | boolean | Resolve or unresolve (owner, author, or share users) |
Resolve a comment
Section titled “Resolve a comment”curl -X PATCH https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID \ -H "Authorization: Bearer nb_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"resolved": true}'const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", { method: "PATCH", headers: { "Authorization": "Bearer nb_sk_YOUR_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ resolved: true }), });const { data, error } = await res.json();import requests
res = requests.patch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"}, json={"resolved": True},)data = res.json()Response 200 OK
Section titled “Response 200 OK”{ "data": { "id": "comment-uuid", "body": "...", "resolved": true, "resolved_at": "2026-03-13T12:10:00.000Z", "resolved_by": "user-uuid" }, "error": null}Edit a comment body
Section titled “Edit a comment body”Only the comment author can edit the body:
curl -X PATCH https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID \ -H "Authorization: Bearer nb_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"body": "Updated comment text"}'const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", { method: "PATCH", headers: { "Authorization": "Bearer nb_sk_YOUR_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ body: "Updated comment text" }), });const { data, error } = await res.json();import requests
res = requests.patch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"}, json={"body": "Updated comment text"},)data = res.json()Who can do what
Section titled “Who can do what”| Action | Document owner | Comment author | Share user (comment/edit) |
|---|---|---|---|
| Edit body | No | Yes | No |
| Resolve | Yes | Yes | Yes |
| Unresolve | Yes | Yes | Yes |
Delete a comment
Section titled “Delete a comment”DELETE /api/documents/:id/comments/:cidDeletes a comment and all its replies.
Request
Section titled “Request”curl -X DELETE https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID \ -H "Authorization: Bearer nb_sk_YOUR_KEY"const res = await fetch( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", { method: "DELETE", headers: { "Authorization": "Bearer nb_sk_YOUR_KEY" }, });const { data, error } = await res.json();import requests
res = requests.delete( "https://notebind.com/api/documents/DOC_ID/comments/COMMENT_ID", headers={"Authorization": "Bearer nb_sk_YOUR_KEY"},)data = res.json()Response 200 OK
Section titled “Response 200 OK”{ "data": { "deleted": true }, "error": null}Permissions
Section titled “Permissions”- Document owner can delete any comment
- Comment author can delete their own comments
- Share users can only delete anonymous (null author) comments
Error responses
Section titled “Error responses”| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Missing body field or no valid updates |
401 | UNAUTHORIZED | Missing or invalid credentials |
403 | UNAUTHORIZED | Insufficient permissions |
404 | NOT_FOUND | Comment or document not found |