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

# Add Comments

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>
