For AI agents: markdown of this page — /docs-content-en/entities/task-comments/list.md documentation index — /llms.txt

List comments

GET /v1/tasks/:taskId/comments

Returns the comments of a specific task. On the new task card the list is read from the chat, system messages are filtered out. On the old one — from the comments block inside the card.

Parameters

Parameter Type Required Default Description
taskId (path) number yes Parent task ID
limit (query) number 50 Page size (up to 200)
offset (query) number 0 How many matching comments to skip before returning results. Honoured on every new-card read path; a request without filter and with a sort by ID used to ignore it and answer the same page at any offset
sort (query) string id:desc Sorting: field ID, AUTHOR_ID or POST_DATE and direction asc or desc?sort=post_date:desc. The field name is case-insensitive; the camelCase names id, authorId, authorName, createdAt, authorEmail are accepted too. Sorting by AUTHOR_NAME and AUTHOR_EMAIL is accepted on the old card only, on the new one it returns 400 UNSUPPORTED_SORT_FIELD
filter (query) object Filter by the fields ID, AUTHOR_ID, POST_DATE. The camelCase names id, authorId, authorName, createdAt are accepted too. Passed as JSON: ?filter={"AUTHOR_ID":1}. The field name may carry a !, >, >=, < or <= prefix — ?filter={">=POST_DATE":"2026-05-01T00:00:00Z"}. The value for POST_DATE is an ISO 8601 date in UTC, several fields are combined with "and". Filtering by AUTHOR_NAME is accepted on the old card only, on the new one it returns 400 UNSUPPORTED_FILTER_FIELD ⚠️ Pass the WHOLE filter in a single form — either bracket notation or one JSON object. A mixed envelope (?filter[NAME]=x&filter=) and a bracket condition deeper than two levels are rejected with 400 INVALID_FILTER: half of the conditions are irrecoverably lost while the query string is parsed. An empty ?filter= means "no filter".

Examples

curl — personal key

Terminal
curl "https://vibecode.bitrix24.com/v1/tasks/289/comments?limit=20&sort=id:desc" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth app

Terminal
curl "https://vibecode.bitrix24.com/v1/tasks/289/comments?limit=20&sort=id:desc" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const url = 'https://vibecode.bitrix24.com/v1/tasks/289/comments?limit=20&sort=id:desc'
const res = await fetch(url, {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { success, data, meta } = await res.json()
console.log(`Received ${data.length} comments`)

JavaScript — OAuth app

javascript
const url = 'https://vibecode.bitrix24.com/v1/tasks/289/comments?limit=20&sort=id:desc'
const res = await fetch(url, {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { success, data, meta } = await res.json()

Response fields

Field Type Description
success boolean Always true on success
data array Array of comments
data[].id number Comment identifier
data[].taskId number Parent task ID
data[].authorId number Author. Profile: GET /v1/users/:authorId
data[].message string Comment text (supports BB-code)
data[].createdAt datetime Creation date (UTC ISO 8601)
meta.total number Number of comments. On the new card for a request with filter, a sort other than ID, or a non-zero offset — the exact count of the matches within the scanned window. Without those — the exact count when meta.hasMore is false; on a full page of comments, an "at least" estimate equal to data.length + 1
meta.hasMore boolean Whether there are more comments beyond limit
meta.truncated boolean Comes with the value true only, and only on the new card for a request with filter or a sort other than ID: the scan window was exhausted, and some comments stayed beyond its edge

Response example

JSON
{
  "success": true,
  "data": [
    {
      "id": 36559,
      "taskId": 289,
      "authorId": 1,
      "message": "Added a draft of the report to the comments — please take a look.",
      "createdAt": "2026-05-13T12:30:58.000Z"
    },
    {
      "id": 36557,
      "taskId": 289,
      "authorId": 79,
      "message": "[USER=99]Alex[/USER], done, thanks.",
      "createdAt": "2026-05-12T15:11:04.000Z"
    }
  ],
  "meta": {
    "total": 2,
    "hasMore": false
  }
}

Error response example

400 — taskId is not a positive integer:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "taskId must be a positive integer"
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS taskId is invalid (not a positive integer)
400 INVALID_SORT_FIELD Sort by an unsupported field or direction. Supported: ID, AUTHOR_ID, AUTHOR_NAME, AUTHOR_EMAIL, POST_DATE and their camelCase names, with direction asc or desc. On the new card AUTHOR_NAME and AUTHOR_EMAIL answer with UNSUPPORTED_SORT_FIELD
400 UNSUPPORTED_SORT_FIELD New card only: sort by AUTHOR_NAME or AUTHOR_EMAIL. Sort by ID, AUTHOR_ID or POST_DATE instead
400 INVALID_FILTER The filter parameter is not valid JSON, or it names one field twice in different spellings of the name or of the equality sign, for example {"AUTHOR_ID":1,"authorId":2} or {"AUTHOR_ID":1,"=authorId":2}. New card only: filter is a scalar or an empty array instead of an object (0, false, "", []); the value of ID or AUTHOR_ID is not a number; the value of POST_DATE does not parse as a date; or a field value is an object or an array instead of a scalar. A non-empty array or a non-empty string in filter yields UNKNOWN_FILTER_FIELD — its indexes are read as field names. An ambiguous envelope is rejected as well: the bracket form and JSON in one request (in either order), or a bracket condition deeper than two levels — half of the conditions are irrecoverably lost during parsing, so the request is refused rather than half-applied.
400 UNKNOWN_FILTER_FIELD Filter by an unsupported field. Supported: ID, AUTHOR_ID, AUTHOR_NAME, POST_DATE and their camelCase names. On the new card AUTHOR_NAME answers with UNSUPPORTED_FILTER_FIELD
400 UNSUPPORTED_FILTER_FIELD New card only: filter by AUTHOR_NAME. Filter by ID, AUTHOR_ID or POST_DATE instead, an employee identifier by name — GET /v1/users
403 SCOPE_DENIED The API key does not have the task scope
401 TOKEN_MISSING The API key has no configured tokens

Full list of common API errors — Errors.

Known specifics

Scan window on filtering. On the new card a request with filter or a sort other than ID scans up to 2000 of the newest task chat messages, system notifications included, and picks the matching comments out of them. If the task history is longer, or is limited by the Bitrix24 account plan, meta.truncated: true arrives: comments that are not in the response stayed beyond the window edge, and meta.total counts only the ones inside it. This is not a sign of a next page — offset does not move the window. Narrow the selection with a POST_DATE or AUTHOR_ID filter. For the same reason ?sort=post_date:asc on such a task returns the oldest comments within the window, not the oldest comments of the task.

Filter and sort by author — via AUTHOR_ID. The fields AUTHOR_NAME and AUTHOR_EMAIL are accepted on the old card and return 400 on the new one, so a request by author name does not work on every Bitrix24 account. To make the selection independent of how the Bitrix24 account is configured, find the employee via GET /v1/users and filter or sort by AUTHOR_ID.

System notifications and the end of the list. System notifications about task creation, deadline change and assignee change are filtered out on the API side. When a slice consists only of them, the service reads further into the task history instead of answering an empty page that invites more paging: meta.hasMore: false with meta.total: 0 means there really are no comments. Such a task used to answer {"data": [], "total": 1, "hasMore": true} at every offset, so a while (hasMore) offset += limit loop never ended. Paginate by meta.hasMore and the contents of data.

See also