For AI agents: markdown of this page — /docs-content-en/entities/task-comments/comments-batch.md documentation index — /llms.txt
Batch comment operations
POST /v1/tasks/:taskId/comments/batch
Bulk create, update, or delete comments on a single task. Up to 50 items per call. Each item is processed independently — a failure in one item does not cancel the rest.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId (path) |
number | yes | Task ID |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
action |
string | ★ | Operation type: create, update or delete |
items |
array | for create / update |
List of items (up to 50). For create: [{ message: string }]. For update: [{ id: number, message: string }] |
ids |
number[] | for delete |
Comment identifiers to delete (up to 50) |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/289/comments/batch" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "create",
"items": [
{ "message": "Step 1: prepared the draft." },
{ "message": "Step 2: sent it for review." }
]
}'
curl — OAuth app
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/289/comments/batch" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "create",
"items": [
{ "message": "Step 1: prepared the draft." },
{ "message": "Step 2: sent it for review." }
]
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/289/comments/batch', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'create',
items: [
{ message: 'Step 1: prepared the draft.' },
{ message: 'Step 2: sent it for review.' },
],
}),
})
const { success, data } = await res.json()
data.forEach((item) => {
if (item.success) console.log(`#${item.index} → id=${item.id}`)
else console.log(`#${item.index} → error: ${item.error}`)
})
JavaScript — OAuth app
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/289/comments/batch', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'create',
items: [
{ message: 'Step 1: prepared the draft.' },
{ message: 'Step 2: sent it for review.' },
],
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true — even if every item failed, the top level still reports success. Check each item's status in data[i] |
data |
array | Array of results in the same order as the request items / ids |
data[].index |
number | Item index (0-based) |
data[].success |
boolean | Result of the specific operation |
data[].id |
number | null | Comment ID on create / update. Occasionally null with success: true — the comment was created but its ID wasn't recovered (see POST /v1/tasks/:taskId/comments "Known specifics"). If Bitrix24 didn't create the comment at all (task doesn't exist/isn't accessible) that's a different case — success: false + error: TASK_NOT_FOUND, no ID is returned |
data[].error |
string | Error code for a failed item (GONE, READONLY_FIELD, BATCH_ITEM_VALIDATION, BITRIX_ERROR, INVALID_PARAMS, TASK_NOT_FOUND) |
data[].message |
string | Error text for a failed item |
Response example
action: create on the new card — both records went into the task chat:
{
"success": true,
"data": [
{ "index": 0, "success": true, "id": 36571 },
{ "index": 1, "success": true, "id": 36573 }
]
}
action: update on the new card — every update attempt turns into GONE (method unavailable):
{
"success": true,
"data": [
{
"index": 0,
"success": false,
"error": "GONE",
"message": "Bitrix24 disabled update/delete for task comments in the new task card. To remove a comment, delete the source task or ask a portal admin to remove the message via the chat UI."
}
]
}
Error response example
400 — invalid action value:
{
"success": false,
"error": {
"code": "INVALID_BATCH_ACTION",
"message": "Action must be one of: create, update, delete"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
taskId is not a positive integer |
| 400 | INVALID_BATCH_ACTION |
action is not create, update or delete |
| 400 | BATCH_ITEM_VALIDATION |
items (or ids for delete) is empty or not an array |
| 400 | BATCH_LIMIT_EXCEEDED |
More than 50 items passed in a single request |
| 403 | SCOPE_DENIED |
The API key does not have the task scope |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
Errors for individual items are returned inside data[i].error:
| Code | Description |
|---|---|
GONE |
Only for update / delete on the new card — the operation is unavailable on the Bitrix24 side |
READONLY_FIELD |
An update item contains a read-only field (ID, taskId, authorId, createdAt, or an alias); that item is not sent to Bitrix24 |
BATCH_ITEM_VALIDATION |
The item failed validation (for example, no id or message, wrong type) |
INVALID_PARAMS |
message is missing or exceeds the length limit |
BITRIX_ERROR |
Bitrix24 returned an error for the specific item (text in message) |
TASK_NOT_FOUND |
Only for create — task taskId doesn't exist or isn't accessible to the key, so the comment is not created |
Full list of common API errors — Errors.
Known specifics
The top-level success is always true if the request passed validation. Failed items inside the batch do not turn the whole response into an error — this is intentional so the client can handle a partial result. Before using the result, always check data[i].success for each item.
READONLY_FIELD arrives separately for each item. The batch keeps HTTP 200
and top-level success: true: the forbidden item gets success: false, is not
sent to Bitrix24, and valid sibling items are still processed. Lowercase id remains the
comment selector; for example, an additional ID in the same item is treated
as a forbidden data field.
GONE arrives separately for each item. On the new card, update / delete of each item returns GONE, but the overall response stays 200 success — the whole batch is not rejected. In mixed scenarios, some items on the old card go through, others on the new card return GONE.
create distinguishes "not created" from "created, id unknown". If the task doesn't exist/isn't accessible, the item fails with TASK_NOT_FOUND (success: false, no id). If the comment was genuinely created (it went to the task's chat) but the system couldn't confirm its id via a search over recent messages, the item stays success: true with id: null — retrying will create a duplicate, not recover the original id.