For AI agents: markdown of this page — /docs-content-en/entities/tasks/checklist-actions.md documentation index — /llms.txt
Checklist actions and task file
These methods save a task checklist in one call, mark an item complete together with its sub-items, reorder items, and add members and files. Task checklist reads and changes the same items one at a time, but its responses have a different shape.
Bitrix24 API: tasks.task.checklist.*, tasks.task.files.attach
Scope: task
Save a task checklist
POST /v1/tasks/:taskId/checklist/tree
Saves a task's entire checklist in one call: the flat array of items you pass replaces the current checklist. Item field names are in upper case.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ParametertaskId (path) |
Typenumber | Requiredyes | DescriptionTask ID, a positive integer. List: GET /v1/tasks |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
Fielditems |
Typearray | Requiredyes | DescriptionAll checklist items in one flat array. An item missing from the array is deleted. An empty array deletes the whole checklist. The order of items with the same parent in the array sets their sortIndex |
Fielditems[].ID |
Typenumber | Requiredno | DescriptionID of an existing item. List: GET /v1/tasks/:taskId/checklist. With ID, the item is saved under its existing ID. Without it, the item is re-created with a new ID, and the old item is deleted |
Fielditems[].NODE_ID |
Typestring | Requiredno | DescriptionItem key within the request, for example root-1. Sub-items reference it in PARENT_NODE_ID, and the item comes back under it in the response. Give each item its own NODE_ID: if several new items lack one, only the last of them is saved, and the rest are lost without an error |
Fielditems[].PARENT_NODE_ID |
Typestring | number | Requiredno | DescriptionNODE_ID of the parent item. 0 or omitted — a top-level item, and its TITLE becomes the checklist name |
Fielditems[].TITLE |
Typestring | Requiredyes | DescriptionItem text. Required for every item, including an item with ID |
Fielditems[].IS_COMPLETE |
Typeboolean | Requiredno | Descriptiontrue — the item is complete. Without the field, a new item is saved as incomplete. The string "Y" instead of true saves the item as incomplete, with no error |
Fielditems[].IS_IMPORTANT |
Typeboolean | Requiredno | Descriptiontrue — the item is important. Defaults to false: an item with ID loses its previous importance flag |
Fieldparameters |
Typeobject | Requiredno | DescriptionAdditional save parameters. They do not affect the result |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/4218/checklist/tree" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "NODE_ID": "root-1", "PARENT_NODE_ID": 0, "TITLE": "Launch preparation", "IS_COMPLETE": false, "IS_IMPORTANT": false },
{ "NODE_ID": "child-1", "PARENT_NODE_ID": "root-1", "TITLE": "Check the build", "IS_COMPLETE": false, "IS_IMPORTANT": true },
{ "NODE_ID": "child-2", "PARENT_NODE_ID": "root-1", "TITLE": "Update the description", "IS_COMPLETE": false, "IS_IMPORTANT": false }
]
}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/tasks/4218/checklist/tree" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "NODE_ID": "root-1", "PARENT_NODE_ID": 0, "TITLE": "Launch preparation", "IS_COMPLETE": false, "IS_IMPORTANT": false },
{ "NODE_ID": "child-1", "PARENT_NODE_ID": "root-1", "TITLE": "Check the build", "IS_COMPLETE": false, "IS_IMPORTANT": true },
{ "NODE_ID": "child-2", "PARENT_NODE_ID": "root-1", "TITLE": "Update the description", "IS_COMPLETE": false, "IS_IMPORTANT": false }
]
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/4218/checklist/tree', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{ NODE_ID: 'root-1', PARENT_NODE_ID: 0, TITLE: 'Launch preparation', IS_COMPLETE: false, IS_IMPORTANT: false },
{ NODE_ID: 'child-1', PARENT_NODE_ID: 'root-1', TITLE: 'Check the build', IS_COMPLETE: false, IS_IMPORTANT: true },
{ NODE_ID: 'child-2', PARENT_NODE_ID: 'root-1', TITLE: 'Update the description', IS_COMPLETE: false, IS_IMPORTANT: false },
],
}),
})
const { data } = await res.json()
const saved = data?.checkListItem?.traversedItems ?? {}
for (const [nodeId, item] of Object.entries(saved)) {
console.log(nodeId, '→ item ID', item.id)
}
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/tasks/4218/checklist/tree', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{ NODE_ID: 'root-1', PARENT_NODE_ID: 0, TITLE: 'Launch preparation', IS_COMPLETE: false, IS_IMPORTANT: false },
{ NODE_ID: 'child-1', PARENT_NODE_ID: 'root-1', TITLE: 'Check the build', IS_COMPLETE: false, IS_IMPORTANT: true },
{ NODE_ID: 'child-2', PARENT_NODE_ID: 'root-1', TITLE: 'Update the description', IS_COMPLETE: false, IS_IMPORTANT: false },
],
}),
})
const { data } = await res.json()
const saved = data?.checkListItem?.traversedItems ?? {}
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue if the request succeeded |
Fielddata.checkListItem |
Typeobject | null | DescriptionThe saved checklist. null if an empty items array was passed |
Fielddata.checkListItem.traversedItems |
Typeobject | DescriptionSaved items. The key is the item's NODE_ID from the request; for an item without NODE_ID it is "0" |
Fielddata.checkListItem.traversedItems.<NODE_ID>.id |
Typenumber | DescriptionItem ID. An item without ID in the request gets a new ID |
Fielddata.checkListItem.traversedItems.<NODE_ID>.copiedId |
Typenumber | null | DescriptionID of the original item if the item was copied. The method returns null |
Fielddata.checkListItem.traversedItems.<NODE_ID>.entityId |
Typenumber | DescriptionTask ID from the path |
Fielddata.checkListItem.traversedItems.<NODE_ID>.userId |
Typenumber | DescriptionID of the employee on whose behalf the call is made |
Fielddata.checkListItem.traversedItems.<NODE_ID>.createdBy |
Typenumber | null | DescriptionID of the item author. For an item saved by ID it is null; the author of such an item is returned by GET /v1/tasks/:taskId/checklist |
Fielddata.checkListItem.traversedItems.<NODE_ID>.parentId |
Typenumber | DescriptionID of the parent item. 0 — a top-level item |
Fielddata.checkListItem.traversedItems.<NODE_ID>.title |
Typestring | DescriptionItem text |
Fielddata.checkListItem.traversedItems.<NODE_ID>.sortIndex |
Typenumber | DescriptionThe item's position among items with the same parent: the smaller the number, the higher the item |
Fielddata.checkListItem.traversedItems.<NODE_ID>.displaySortIndex |
Typestring | DescriptionItem number for display. The method returns an empty string |
Fielddata.checkListItem.traversedItems.<NODE_ID>.isComplete |
Typeboolean | DescriptionWhether the item is complete |
Fielddata.checkListItem.traversedItems.<NODE_ID>.isImportant |
Typeboolean | DescriptionWhether the item is important |
Fielddata.checkListItem.traversedItems.<NODE_ID>.completedCount |
Typenumber | DescriptionNumber of completed sub-items. The method returns 0 even when a sub-item is complete |
Fielddata.checkListItem.traversedItems.<NODE_ID>.members |
Typearray | DescriptionItem members. An empty array if there are none |
Fielddata.checkListItem.traversedItems.<NODE_ID>.attachments |
Typearray | object | DescriptionItem attachments. An empty array if there are none |
Fielddata.checkListItem.traversedItems.<NODE_ID>.nodeId |
Typestring | null | DescriptionThe item's NODE_ID from the request. For an item without NODE_ID it is null |
Fielddata.checkListItem.taskId |
Typenull | DescriptionAlways null. The task ID is in the items' entityId |
Response example
Checklist saved:
{
"success": true,
"data": {
"checkListItem": {
"traversedItems": {
"root-1": {
"id": 268,
"copiedId": null,
"entityId": 4218,
"userId": 1295,
"createdBy": 1295,
"parentId": 0,
"title": "Launch preparation",
"sortIndex": 0,
"displaySortIndex": "",
"isComplete": false,
"isImportant": false,
"completedCount": 0,
"members": [],
"attachments": [],
"nodeId": "root-1"
},
"child-1": {
"id": 270,
"copiedId": null,
"entityId": 4218,
"userId": 1295,
"createdBy": 1295,
"parentId": 268,
"title": "Check the build",
"sortIndex": 0,
"displaySortIndex": "",
"isComplete": false,
"isImportant": true,
"completedCount": 0,
"members": [],
"attachments": [],
"nodeId": "child-1"
},
"child-2": {
"id": 272,
"copiedId": null,
"entityId": 4218,
"userId": 1295,
"createdBy": 1295,
"parentId": 268,
"title": "Update the description",
"sortIndex": 1,
"displaySortIndex": "",
"isComplete": false,
"isImportant": false,
"completedCount": 0,
"members": [],
"attachments": [],
"nodeId": "child-2"
}
},
"taskId": null
}
}
}
An empty items array was passed, and the task checklist was deleted:
{
"success": true,
"data": {
"checkListItem": null
}
}
Error response example
422 — a new item has no TITLE:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "Incorrect value [] specified for field [TITLE] in item [, ]",
"b24Code": "0"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
DescriptiontaskId is not a positive integer. Message taskId must be a positive integer |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe body is not a JSON object, for example an array. Message JSON object body is required |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe items field is missing, or items is not an array. Message items must be an array |
| HTTP400 | CodeINVALID_PARAMS |
Descriptionparameters is not an object. Message parameters must be an object |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionX-Api-Key is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe key has no Bitrix24 tokens |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key has no task scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is in read-only mode. error.details.switchUrl contains the URL of the section where the mode is changed |
| HTTP415 | CodeFST_ERR_CTP_INVALID_MEDIA_TYPE |
DescriptionA body with a Content-Type the API does not parse, for example application/xml |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionAn item has no TITLE, including an item with ID. The message is in the Bitrix24 account language and refers to the item as [283, ], where 283 is the item's ID. For a new item the ID slot in the message is empty: [, ] |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionThe employee on whose behalf the call is made has no access to the task. This employee gets the same response for the taskId of a nonexistent task. The message is in the Bitrix24 account language; on an English-language account it is Access to task was denied. The API specification declares 404 TASK_NOT_FOUND for this case, but the Bitrix24 accounts we tested return this response instead |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRequest rate exceeded. The effective cap is in the x-ratelimit-limit header |
Full list of common API errors — Errors.
Known specifics
An error does not roll back what is already saved. A 422 response does not mean the checklist stayed as it was. A request that renames an item with ID and adds a new item without TITLE returns 422, but the item is renamed anyway. Items missing from the request are not deleted in this case. After an error, check the result with GET /v1/tasks/:taskId/checklist.
A nonexistent taskId does not always return an error. The response depends on the employee on whose behalf the call is made: one gets 422 BITRIX_ERROR, another gets 200. In the second case the items are saved with entityId equal to the passed taskId and are not visible in any task. Before saving, check the task with GET /v1/tasks/:id.