## Add a comment

`POST /v1/feedback/:id/comments`

Adds a comment to a ticket. Requires the `vibe:feedback` scope. Attachments can be added to a comment.

## Parameters

| Parameter | Type | Required | Description |
|-----------|------|:--------:|-------------|
| `id` (path) | string | yes | Ticket UUID |

## Request fields (body)

| Field | Type | Required | Description |
|-------|------|:--------:|-------------|
| `body` | string | yes | Comment text, 2–20000 characters |
| `status` | string | no | New ticket status, applied together with the comment. Values as in [update](./update.md) |
| `attachmentIds` | array | no | Up to 5 IDs of pre-uploaded attachments. How to upload — [Upload an attachment](./attachments.md) |

## Examples

### curl — personal key

```bash
curl -X POST https://vibecode.bitrix24.com/v1/feedback/a1b2c3d4-1111-2222-3333-444455556666/comments \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Reproduced on an empty filter, attached the request log." }'
```

### curl — OAuth application

```bash
curl -X POST https://vibecode.bitrix24.com/v1/feedback/a1b2c3d4-1111-2222-3333-444455556666/comments \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Reproduced on an empty filter, attached the request log." }'
```

### JavaScript — personal key

```javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/feedback/a1b2c3d4-1111-2222-3333-444455556666/comments',
  {
    method: 'POST',
    headers: { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({ body: 'Reproduced on an empty filter, attached the request log.' }),
  },
)
const { data } = await res.json()
```

### JavaScript — OAuth application

```javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/feedback/a1b2c3d4-1111-2222-3333-444455556666/comments',
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ body: 'Reproduced on an empty filter, attached the request log.' }),
  },
)
const { data } = await res.json()
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `success` | boolean | Always `true` on success |
| `data.id` | string | Comment UUID |
| `data.authorType` | string | Who left the comment: `USER` or `PLATFORM` |
| `data.body` | string | Comment text |
| `data.createdAt` | string | Creation date (ISO 8601) |
| `data.feedbackStatus` | string | Ticket status after the comment |
| `data.previousStatus` | string | Ticket status before the comment |

## Response example

```json
{
  "success": true,
  "data": {
    "id": "61ae2a00-a7ac-416f-85cc-99873c767d3b",
    "authorType": "USER",
    "body": "Reproduced on an empty filter, attached the request log.",
    "createdAt": "2026-04-19T11:00:00.000Z",
    "feedbackStatus": "AWAITING_USER",
    "previousStatus": "NEW"
  }
}
```

## Error response example

403 — comment without the `vibe:feedback` scope:

```json
{
  "success": false,
  "error": {
    "code": "FEEDBACK_SCOPE_REQUIRED",
    "message": "Requires management key or vibe:feedback scope"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|------|-------------|
| 400 | `VALIDATION_ERROR` | `body` shorter than 2 or longer than 20000 characters, or `attachmentIds` longer than 5 |
| 403 | `FEEDBACK_SCOPE_REQUIRED` | Comment on someone else's ticket without the `vibe:feedback` scope. The ticket author passes without the scope — see "Known specifics" |
| 404 | `NOT_FOUND` | The ticket does not exist or is not accessible to the key |
| 409 | `FEEDBACK_CLOSED` | An author comment on an already closed ticket |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not passed |

For the full list of common API errors, see [Errors](/docs/errors).

## Known specifics

**A comment can change the status.** By default a comment moves the ticket to `AWAITING_USER`. To set a different status, pass `status` in the body — values as in [update](./update.md). The `feedbackStatus` and `previousStatus` fields in the response show the status after and before the comment.

**The author comments on their own ticket without the scope.** If the request uses the same key that created the ticket, the comment passes without the `vibe:feedback` scope: the author check runs before the scope check. The scope is only needed for comments on other people's tickets.

## See also

- [Get a ticket](/docs/feedback/get)
- [Update a ticket](/docs/feedback/update)
- [Upload an attachment](/docs/feedback/attachments)
- [Feedback](/docs/feedback)
