> ## Documentation Index
> Fetch the complete documentation index at: https://velt-mintlify-e6426361.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Add comments (v2)

> Add a new comment or reply to an existing comment annotation thread using the Velt v2 REST API, with support for rich content, mentions, and attachments.

Use this API to add comments within a specific CommentAnnotation.

# Endpoint

`POST https://api.velt.dev/v2/commentannotations/comments/add`

# Headers

<ParamField header="x-velt-api-key" type="string" required>
  Your API key.
</ParamField>

<ParamField header="x-velt-auth-token" type="string" required>
  Your [Auth Token](/security/auth-tokens).
</ParamField>

# Body

#### Params

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="organizationId" type="string" required>
      Organization ID
    </ParamField>

    <ParamField body="createOrganization" type="boolean">
      If set to true, a new organization will be created (if it doesn't exist) before the comment is added.
    </ParamField>

    <ParamField body="documentId" type="string" required>
      Document ID
    </ParamField>

    <ParamField body="createDocument" type="boolean">
      If set to true, a new document will be created (if it doesn't exist) before the comment is added.
    </ParamField>

    <ParamField body="annotationId" type="string" required>
      Comment Annotation ID
    </ParamField>

    <ParamField body="verifyUserPermissions" type="boolean">
      When enabled, verifies the user has access to the document before adding comments.
      This ensures comments respect document access permissions configured via Access Control or Permission Provider.

      Default: `false`
    </ParamField>

    <ParamField body="commentData" type="Comment[]" required>
      Array of Comment Data

      <Expandable title="properties">
        <ParamField body="commentId" type="number">
          Custom Comment ID. If not provided, Velt will generate a unique ID for the comment.
        </ParamField>

        <ParamField body="commentText" type="string">
          Comment content in plain text string
        </ParamField>

        <ParamField body="commentHtml" type="string">
          Comment content in HTML string
        </ParamField>

        <ParamField body="context" type="object">
          Custom key/value metadata object. This is used to store any additional information about the comment.
        </ParamField>

        <ParamField body="isCommentResolverUsed" type="boolean">
          Use this for self-hosting comments data. Set this as true if you are comments resolver data provider in the SDK.
        </ParamField>

        <ParamField body="isCommentTextAvailable" type="boolean">
          Use this for self-hosting comments data. Set this as true if this comment will have text content. Sometimes, comments might only have attachments and in that case, set this as false.
        </ParamField>

        <ParamField body="from" type="User" required>
          User object from whom the comment is added
        </ParamField>

        <ParamField body="createdAt" type="number">
          Created At timestamp (in milliseconds since epoch).
        </ParamField>

        <ParamField body="lastUpdated" type="number">
          Last Updated timestamp (in milliseconds since epoch).
        </ParamField>

        <ParamField body="taggedUserContacts" type="object[]">
          Array of tagged user contacts

          <Expandable title="properties">
            <ParamField body="text" type="string" required>
              Display text of the tagged user (e.g. "@Username")
            </ParamField>

            <ParamField body="userId" type="string" required>
              User ID of the tagged user
            </ParamField>

            <ParamField body="contact" type="object" required>
              <Expandable title="properties">
                <ParamField body="email" type="string" required>
                  Email of the tagged user
                </ParamField>

                <ParamField body="name" type="string" required>
                  Name of the tagged user
                </ParamField>

                <ParamField body="userId" type="string" required>
                  User ID of the tagged user
                </ParamField>
              </Expandable>
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="attachments" type="object[]">
          Array of attachments to include with the comment. See [Attachment](/api-reference/sdk/models/data-models#attachment) for full schema details.

          <Expandable title="properties">
            <ParamField body="attachmentId" type="number" required>
              Unique identifier for the attachment
            </ParamField>

            <ParamField body="name" type="string">
              File name of the attachment
            </ParamField>

            <ParamField body="bucketPath" type="string">
              Path to the file in storage bucket
            </ParamField>

            <ParamField body="size" type="number">
              File size in bytes
            </ParamField>

            <ParamField body="type" type="string">
              File type (e.g., "image", "video", "document")
            </ParamField>

            <ParamField body="url" type="string">
              Download URL of the attachment
            </ParamField>

            <ParamField body="thumbnail" type="string">
              Thumbnail URL of the attachment
            </ParamField>

            <ParamField body="mimeType" type="string">
              MIME type of the attachment (e.g., "image/png", "video/mp4")
            </ParamField>

            <ParamField body="metadata" type="object">
              Custom metadata for the attachment (e.g., dimensions, timestamps, etc.)
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="agent" type="object">
          Marks this comment as an agent-authored reply. V2 only. When set, the server stamps `sourceType: "agent"` on the comment. Discriminated on `agentSource`.

          <Expandable title="properties">
            <ParamField body="agentSource" type="string" required>
              Origin of the agent. Must be one of: `velt` or `external`.
            </ParamField>

            <ParamField body="agentId" type="string">
              Agent ID. Required when `agentSource` is `velt` (a built-in agent like `spell-check`, or a custom agent ID that is verified server-side). Optional and opaque (never validated) when `agentSource` is `external`.
            </ParamField>

            <ParamField body="executionId" type="string">
              Execution / run ID for this agent invocation.
            </ParamField>

            <ParamField body="agentName" type="string">
              Display name for the agent. **Required when `agentSource` is `external`** (the only source of truth for an external agent's name). Not used for `velt` agents (their name is resolved server-side).
            </ParamField>

            <ParamField body="url" type="string">
              Page URL associated with the finding.
            </ParamField>

            <ParamField body="reason" type="object" required>
              Finding details produced by the agent. Additional custom fields are preserved.

              <Expandable title="properties">
                <ParamField body="title" type="string" required>
                  Short finding title.
                </ParamField>

                <ParamField body="description" type="string" required>
                  Finding description.
                </ParamField>

                <ParamField body="severity" type="string" required>
                  Severity of the finding. Must be one of: `critical`, `high`, `medium`, `low`, or `info`.
                </ParamField>

                <ParamField body="findingId" type="string">
                  Unique identifier for the finding.
                </ParamField>

                <ParamField body="findingType" type="string">
                  Type of finding. Must be one of: `text`, `pin`, or `page`.
                </ParamField>

                <ParamField body="issueType" type="string">
                  Custom issue classification.
                </ParamField>

                <ParamField body="confidence" type="number">
                  Confidence score for the finding. Integer between 0 and 100.
                </ParamField>

                <ParamField body="suggestion" type="string">
                  Suggested change in plain text.
                </ParamField>

                <ParamField body="suggestedFix" type="string">
                  Suggested fix for the finding.
                </ParamField>

                <ParamField body="htmlSnippet" type="string">
                  Relevant HTML snippet for the finding.
                </ParamField>

                <ParamField body="htmlSelector" type="string">
                  CSS/HTML selector pointing to the finding location.
                </ParamField>

                <ParamField body="source" type="string">
                  Provenance of the rule that triggered the finding. Must be one of: `instructions` or `knowledge`.
                </ParamField>

                <ParamField body="knowledgeSection" type="string">
                  Knowledge section that triggered the finding.
                </ParamField>
              </Expandable>
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

## **Example Requests**

<Note>
  This endpoint adds comments (including agent replies) to an existing CommentAnnotation. Annotation-level fields such as `type` (`comment` / `suggestion`) and `visibility` are set when the annotation is created or updated via the [Add Comment Annotations](/api-reference/rest-apis/v2/comments-feature/comment-annotations/add-comment-annotations) and Update Comment Annotations APIs — they are not accepted on this endpoint.
</Note>

#### 1. Add comment in a CommentAnnotation by organizationId, documentId, and annotationId

```JSON theme={null}
{
  "data": {
    "organizationId": "yourOrganizationId",
    "documentId": "yourDocumentId",
    "annotationId": "yourAnnotationId",
    "commentData": [
      {
        "commentText": "Sample Comment",
        "commentHtml": "<div>Hello</div>",
        "from": {
          "userId": "yourUserId"
        }
      }
    ]
  }
}
```

#### 2. Add comment with permission verification

```JSON theme={null}
{
  "data": {
    "organizationId": "yourOrganizationId",
    "documentId": "yourDocumentId",
    "annotationId": "yourAnnotationId",
    "verifyUserPermissions": true,
    "commentData": [
      {
        "commentText": "Sample Comment",
        "commentHtml": "<div>Hello</div>",
        "from": {
          "userId": "yourUserId"
        }
      }
    ]
  }
}
```

<Note>
  When `verifyUserPermissions` is enabled, the API verifies the user has access to the document before adding the comment. If verification fails, the request will be rejected.
</Note>

#### 3. Add comment with attachments

```JSON theme={null}
{
  "data": {
    "organizationId": "yourOrganizationId",
    "createOrganization": true,
    "documentId": "yourDocumentId",
    "createDocument": true,
    "annotationId": "yourAnnotationId",
    "commentData": [
      {
        "commentId": 123,
        "commentText": "Please review this screenshot",
        "commentHtml": "<div>Please review this screenshot</div>",
        "context": {},
        "attachments": [
          {
            "attachmentId": 100001,
            "name": "screenshot.png",
            "bucketPath": "attachments/org-123/doc-456/screenshot.png",
            "size": 1024000,
            "type": "image",
            "url": "https://storage.googleapis.com/bucket/screenshot.png",
            "thumbnail": "https://storage.googleapis.com/bucket/screenshot_thumb.png",
            "mimeType": "image/png",
            "metadata": {
              "width": 1920,
              "height": 1080,
              "uploadedAt": 1696118400000
            }
          }
        ],
        "from": {
          "userId": "yourUserId"
        }
      }
    ]
  }
}
```

#### 4. Add an agent reply

Attach an `agent` block to mark the comment as agent-authored. The server stamps `sourceType: "agent"` on the comment.

```JSON theme={null}
{
  "data": {
    "organizationId": "yourOrganizationId",
    "documentId": "yourDocumentId",
    "annotationId": "yourAnnotationId",
    "commentData": [
      {
        "commentText": "I fixed the spelling. Please re-review.",
        "from": {
          "userId": "spell-check",
          "name": "Spell Check Agent"
        },
        "agent": {
          "agentSource": "velt",
          "agentId": "spell-check",
          "executionId": "exec_124",
          "reason": {
            "title": "Spelling corrected",
            "description": "Updated 'Welcom' to 'Welcome'.",
            "severity": "info",
            "findingType": "text"
          }
        }
      }
    ]
  }
}
```

# Response

#### Success Response

```JSON theme={null}
{
  "result": {
    "status": "success",
    "message": "Comment(s) added successfully.",
    "data": [
      778115
    ]
  }
}
```

#### Failure Response

```JSON theme={null}
{
  "error": {
    "message": "ERROR_MESSAGE",
    "status": "INVALID_ARGUMENT"
  }
}
```

<ResponseExample>
  ```js theme={null}
  {
    "result": {
      "status": "success",
      "message": "Comment(s) added successfully.",
      "data": [
        778115
      ]
    }
  }
  ```
</ResponseExample>
