---
updatedAt: 2026-08-19T21:51:38.000Z
agentTools:
  projectIndex: https://developers.dovetail.com/llms.txt
---

# Comments

Manage comments on docs and insights.

Comments let you add threaded conversations to docs. Each doc has a single comment thread that can be resolved and reopened as needed. Comments are available under `/docs/:doc_id/comments`.

> The same endpoints exist under `/insights/:insight_id/comments`, but the `/insights` paths are deprecated. Use `/docs` for all new integrations.

## Endpoints

| Method   | Path                                 | Description                  |
| -------- | ------------------------------------ | ---------------------------- |
| `GET`    | `/docs/:doc_id/comments`             | List all comments on a doc   |
| `GET`    | `/docs/:doc_id/comments/:comment_id` | Get a single comment         |
| `POST`   | `/docs/:doc_id/comments`             | Create a comment             |
| `PATCH`  | `/docs/:doc_id/comments/:comment_id` | Update a comment             |
| `DELETE` | `/docs/:doc_id/comments/:comment_id` | Delete a comment             |
| `POST`   | `/docs/:doc_id/comments/resolve`     | Resolve the comment thread   |
| `POST`   | `/docs/:doc_id/comments/unresolve`   | Unresolve the comment thread |

## Listing comments

Retrieve all comments on a doc. Comments are returned in chronological order by default.

```http
GET https://dovetail.com/api/v1/docs/<DOC_ID>/comments
Authorization: Bearer <DOVETAIL_API_TOKEN>
```

```json
{
  "data": [
    {
      "id": "<COMMENT_ID>",
      "body": "<p>Great insight! We should follow up on this.</p>",
      "author": {
        "id": "<USER_ID>",
        "name": "Jane Smith"
      },
      "created_at": "2026-01-15T10:30:00.000Z",
      "updated_at": "2026-01-15T10:30:00.000Z"
    }
  ],
  "page": {
    "total_count": 1,
    "has_more": false,
    "next_cursor": null
  },
  "thread": {
    "resolved": false,
    "resolved_at": null,
    "resolved_by": null
  }
}
```

The `thread` field is `null` if no comments have been posted on the doc yet. Once at least one comment exists, it returns the resolution status.

You can control sort order with the `sort` query parameter: `created_at:asc` (default) or `created_at:desc`. See [Pagination](/docs/pagination) for paging through results.

## Getting a single comment

```http
GET https://dovetail.com/api/v1/docs/<DOC_ID>/comments/<COMMENT_ID>
Authorization: Bearer <DOVETAIL_API_TOKEN>
```

```json
{
  "data": {
    "id": "<COMMENT_ID>",
    "body": "<p>Great insight! We should follow up on this.</p>",
    "author": {
      "id": "<USER_ID>",
      "name": "Jane Smith"
    },
    "created_at": "2026-01-15T10:30:00.000Z",
    "updated_at": "2026-01-15T10:30:00.000Z"
  }
}
```

## Creating a comment

```http
POST https://dovetail.com/api/v1/docs/<DOC_ID>/comments
Authorization: Bearer <DOVETAIL_API_TOKEN>
Content-Type: application/json

{
  "body": "Great insight! We should follow up on this.",
  "body_type": "text"
}
```

If no comment thread exists on the doc, one is created automatically. By default the comment is attributed to the authenticated user — i.e. the user that owns the API token.

### Content format

The `body_type` field controls how the `body` input is interpreted:

| Value  | Description                                                            |
| ------ | ---------------------------------------------------------------------- |
| `text` | Plain text (default). Line breaks are preserved.                       |
| `html` | HTML content. Tags like `<strong>`, `<em>`, `<a>`, etc. are supported. |

Regardless of the input format, the `body` field in responses is always returned as HTML.

The maximum comment length is 10,000 characters.

### Attributing a comment to another user (admin)

Workspace admins can pass an optional `author_id` when creating a comment to attribute it to a different workspace user. This is useful when importing existing comments from another tool — without it, every imported comment would appear to be authored by the API token's owner.

```http
POST https://dovetail.com/api/v1/docs/<DOC_ID>/comments
Authorization: Bearer <DOVETAIL_API_TOKEN>
Content-Type: application/json

{
  "body": "Comment imported from Linear",
  "author_id": "<USER_ID>"
}
```

```json
{
  "data": {
    "id": "<COMMENT_ID>",
    "body": "<p>Comment imported from Linear</p>",
    "author": {
      "id": "<USER_ID>",
      "name": "Jane Smith"
    },
    "created_at": "2026-01-15T10:30:00.000Z",
    "updated_at": "2026-01-15T10:30:00.000Z"
  }
}
```

Rules:

* The API token's owner must be a **workspace admin**. Non-admin tokens that include `author_id` get `403 Forbidden`. Tokens without `author_id` continue to work as before.
* The target user (`author_id`) must be an active member of the same workspace. Missing, deleted, or out-of-workspace users get `400 Bad Request`.
* Once set, the comment is owned by `author_id` for permission purposes — only that user (not the original API caller) can edit or delete it via the API. The override is recorded in the workspace audit log as `comment.author_id.updated`.
* `author_id` is only honoured at creation time. The `PATCH` endpoint cannot change a comment's author.

## Updating a comment

```http
PATCH https://dovetail.com/api/v1/docs/<DOC_ID>/comments/<COMMENT_ID>
Authorization: Bearer <DOVETAIL_API_TOKEN>
Content-Type: application/json

{
  "body": "Updated comment text.",
  "body_type": "text"
}
```

Only the original author of a comment can update it. Attempting to update another user's comment will return a `403 Forbidden` error.

## Deleting a comment

```http
DELETE https://dovetail.com/api/v1/docs/<DOC_ID>/comments/<COMMENT_ID>
Authorization: Bearer <DOVETAIL_API_TOKEN>
```

Only the original author of a comment can delete it. The deleted comment is returned in the response. Deleted comments can be restored for up to 30 days.

## Resolving and unresolving threads

Each doc has a single comment thread. You can resolve the thread to indicate the conversation is complete, or unresolve it to reopen discussion.

### Resolve

```http
POST https://dovetail.com/api/v1/docs/<DOC_ID>/comments/resolve
Authorization: Bearer <DOVETAIL_API_TOKEN>
```

```json
{
  "data": {
    "resolved": true,
    "resolved_at": "2026-01-15T12:00:00.000Z",
    "resolved_by": {
      "id": "<USER_ID>",
      "name": "Jane Smith"
    }
  }
}
```

### Unresolve

```http
POST https://dovetail.com/api/v1/docs/<DOC_ID>/comments/unresolve
Authorization: Bearer <DOVETAIL_API_TOKEN>
```

```json
{
  "data": {
    "resolved": false,
    "resolved_at": null,
    "resolved_by": null
  }
}
```