[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Ftasks\u002Fchecklist-actions\u002Ftree":3,"docs-tabs-entities\u002Ftasks\u002Fchecklist-actions\u002Ftree":6},{"content":4,"lastmod":5},"## Save a task checklist\n\n`POST \u002Fv1\u002Ftasks\u002F:taskId\u002Fchecklist\u002Ftree`\n\nSaves 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.\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|----------|-----|:-----:|----------|\n| `taskId` (path) | number | yes | Task ID, a positive integer. List: [`GET \u002Fv1\u002Ftasks`](\u002Fdocs\u002Fentities\u002Ftasks\u002Flist) |\n\n## Request fields (body)\n\n| Field | Type | Required | Description |\n|------|-----|:-----:|----------|\n| `items` | array | yes | All 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` |\n| `items[].ID` | number | no | ID of an existing item. List: [`GET \u002Fv1\u002Ftasks\u002F:taskId\u002Fchecklist`](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Flist). 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 |\n| `items[].NODE_ID` | string | no | Item 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 a unique, nonempty `NODE_ID`. If Bitrix24 accepts several new items without `NODE_ID`, only the last one is saved, and the rest are lost without an error — the response is still `200`. If Bitrix24 rejects the field value with an unnamed access denial, the API returns `404 TASK_NOT_FOUND` |\n| `items[].PARENT_NODE_ID` | string \\| number | no | `NODE_ID` of the parent item. `0` or omitted — a top-level item, and its `TITLE` becomes the checklist name |\n| `items[].TITLE` | string | yes | Item text. Required for every item, including an item with `ID` |\n| `items[].IS_COMPLETE` | boolean | no | `true` — 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 |\n| `items[].IS_IMPORTANT` | boolean | no | `true` — the item is important. Defaults to `false`: an item with `ID` loses its previous importance flag |\n| `parameters` | object | no | Additional save parameters. They do not affect the result |\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftasks\u002F4218\u002Fchecklist\u002Ftree\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"items\": [\n      { \"NODE_ID\": \"root-1\", \"PARENT_NODE_ID\": 0, \"TITLE\": \"Launch preparation\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": false },\n      { \"NODE_ID\": \"child-1\", \"PARENT_NODE_ID\": \"root-1\", \"TITLE\": \"Check the build\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": true },\n      { \"NODE_ID\": \"child-2\", \"PARENT_NODE_ID\": \"root-1\", \"TITLE\": \"Update the description\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": false }\n    ]\n  }'\n```\n\n### curl — OAuth application\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftasks\u002F4218\u002Fchecklist\u002Ftree\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"items\": [\n      { \"NODE_ID\": \"root-1\", \"PARENT_NODE_ID\": 0, \"TITLE\": \"Launch preparation\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": false },\n      { \"NODE_ID\": \"child-1\", \"PARENT_NODE_ID\": \"root-1\", \"TITLE\": \"Check the build\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": true },\n      { \"NODE_ID\": \"child-2\", \"PARENT_NODE_ID\": \"root-1\", \"TITLE\": \"Update the description\", \"IS_COMPLETE\": false, \"IS_IMPORTANT\": false }\n    ]\n  }'\n```\n\n### JavaScript — personal key\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftasks\u002F4218\u002Fchecklist\u002Ftree', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    items: [\n      { NODE_ID: 'root-1', PARENT_NODE_ID: 0, TITLE: 'Launch preparation', IS_COMPLETE: false, IS_IMPORTANT: false },\n      { NODE_ID: 'child-1', PARENT_NODE_ID: 'root-1', TITLE: 'Check the build', IS_COMPLETE: false, IS_IMPORTANT: true },\n      { NODE_ID: 'child-2', PARENT_NODE_ID: 'root-1', TITLE: 'Update the description', IS_COMPLETE: false, IS_IMPORTANT: false },\n    ],\n  }),\n})\n\nconst { data } = await res.json()\nconst saved = data?.checkListItem?.traversedItems ?? {}\nfor (const [nodeId, item] of Object.entries(saved)) {\n  console.log(nodeId, '→ item ID', item.id)\n}\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftasks\u002F4218\u002Fchecklist\u002Ftree', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    items: [\n      { NODE_ID: 'root-1', PARENT_NODE_ID: 0, TITLE: 'Launch preparation', IS_COMPLETE: false, IS_IMPORTANT: false },\n      { NODE_ID: 'child-1', PARENT_NODE_ID: 'root-1', TITLE: 'Check the build', IS_COMPLETE: false, IS_IMPORTANT: true },\n      { NODE_ID: 'child-2', PARENT_NODE_ID: 'root-1', TITLE: 'Update the description', IS_COMPLETE: false, IS_IMPORTANT: false },\n    ],\n  }),\n})\n\nconst { data } = await res.json()\nconst saved = data?.checkListItem?.traversedItems ?? {}\n```\n\n## Response fields\n\n| Field | Type | Description |\n|------|-----|----------|\n| `success` | boolean | `true` if the request succeeded |\n| `data.checkListItem` | object \\| null | The saved checklist. `null` if an empty `items` array was passed |\n| `data.checkListItem.traversedItems` | object | Saved items. The key is the item's `NODE_ID` from the request; for an item without `NODE_ID` it is `\"0\"`. If Bitrix24 saved items without `NODE_ID`, there is a single `\"0\"` key in the whole response: of several such new items only the last one is saved |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.id` | number | Item ID. An item without `ID` in the request gets a new ID |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.copiedId` | number \\| null | ID of the original item if the item was copied. The method returns `null` |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.entityId` | number | Task ID from the path |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.userId` | number | ID of the employee on whose behalf the call is made |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.createdBy` | number \\| null | ID of the item author. For an item saved by `ID` it is `null`; the author of such an item is returned by [`GET \u002Fv1\u002Ftasks\u002F:taskId\u002Fchecklist`](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Flist) |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.parentId` | number | ID of the parent item. `0` — a top-level item |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.title` | string | Item text |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.sortIndex` | number | The item's position among items with the same parent: the smaller the number, the higher the item |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.displaySortIndex` | string | Item number for display. The method returns an empty string |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.isComplete` | boolean | Whether the item is complete |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.isImportant` | boolean | Whether the item is important |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.completedCount` | number | Number of completed sub-items. The method returns `0` even when a sub-item is complete |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.members` | array | Item members. An empty array if there are none |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.attachments` | array \\| object | Item attachments. An empty array if there are none |\n| `data.checkListItem.traversedItems.\u003CNODE_ID>.nodeId` | string \\| null | The item's `NODE_ID` from the request. If Bitrix24 saved an item without `NODE_ID`, it is `null`, and there is exactly one such item in the successful response: the other new items without `NODE_ID` are not saved |\n| `data.checkListItem.taskId` | null | Always `null`. The task ID is in the items' `entityId` |\n\n## Response example\n\nChecklist saved:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"checkListItem\": {\n      \"traversedItems\": {\n        \"root-1\": {\n          \"id\": 268,\n          \"copiedId\": null,\n          \"entityId\": 4218,\n          \"userId\": 1295,\n          \"createdBy\": 1295,\n          \"parentId\": 0,\n          \"title\": \"Launch preparation\",\n          \"sortIndex\": 0,\n          \"displaySortIndex\": \"\",\n          \"isComplete\": false,\n          \"isImportant\": false,\n          \"completedCount\": 0,\n          \"members\": [],\n          \"attachments\": [],\n          \"nodeId\": \"root-1\"\n        },\n        \"child-1\": {\n          \"id\": 270,\n          \"copiedId\": null,\n          \"entityId\": 4218,\n          \"userId\": 1295,\n          \"createdBy\": 1295,\n          \"parentId\": 268,\n          \"title\": \"Check the build\",\n          \"sortIndex\": 0,\n          \"displaySortIndex\": \"\",\n          \"isComplete\": false,\n          \"isImportant\": true,\n          \"completedCount\": 0,\n          \"members\": [],\n          \"attachments\": [],\n          \"nodeId\": \"child-1\"\n        },\n        \"child-2\": {\n          \"id\": 272,\n          \"copiedId\": null,\n          \"entityId\": 4218,\n          \"userId\": 1295,\n          \"createdBy\": 1295,\n          \"parentId\": 268,\n          \"title\": \"Update the description\",\n          \"sortIndex\": 1,\n          \"displaySortIndex\": \"\",\n          \"isComplete\": false,\n          \"isImportant\": false,\n          \"completedCount\": 0,\n          \"members\": [],\n          \"attachments\": [],\n          \"nodeId\": \"child-2\"\n        }\n      },\n      \"taskId\": null\n    }\n  }\n}\n```\n\nAn empty `items` array was passed, and the task checklist was deleted:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"checkListItem\": null\n  }\n}\n```\n\n## Error response example\n\n404 — the task is inaccessible:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"TASK_NOT_FOUND\",\n    \"message\": \"Task not found or not accessible.\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|----------|\n| 400 | `INVALID_PARAMS` | `taskId` is not a positive integer. Message `taskId must be a positive integer` |\n| 400 | `INVALID_PARAMS` | The body is not a JSON object, for example an array. Message `JSON object body is required` |\n| 400 | `INVALID_PARAMS` | The `items` field is missing, or `items` is not an array. Message `items must be an array` |\n| 400 | `INVALID_PARAMS` | `parameters` is not an object. Message `parameters must be an object` |\n| 401 | `MISSING_API_KEY` | `X-Api-Key` is missing |\n| 401 | `TOKEN_MISSING` | The key has no Bitrix24 tokens |\n| 403 | `SCOPE_DENIED` | The key has no `task` scope |\n| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is in read-only mode. `error.details.switchUrl` contains the URL of the section where the mode is changed |\n| 415 | `FST_ERR_CTP_INVALID_MEDIA_TYPE` | A body with a `Content-Type` the API does not parse, for example `application\u002Fxml` |\n| 422 | `BITRIX_ERROR` | An 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: `[, ]` |\n| 404 | `TASK_NOT_FOUND` | The task is missing or inaccessible. This also covers an unnamed access denial in Russian, English, German or Kazakh. The same denial caused by an invalid item ID or NODE_ID in the request body also returns this code |\n| 429 | `RATE_LIMITED` | Request rate exceeded. The effective cap is in the `x-ratelimit-limit` header |\n\nFull list of common API errors — [Errors](\u002Fdocs\u002Ferrors).\n\n## Known specifics\n\n**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 \u002Fv1\u002Ftasks\u002F:taskId\u002Fchecklist`](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Flist).\n\n**A nonexistent `taskId` does not always return an error.** The response depends on the employee on whose behalf the call is made: one gets `404 TASK_NOT_FOUND`, 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 \u002Fv1\u002Ftasks\u002F:id`](\u002Fdocs\u002Fentities\u002Ftasks\u002Fget).\n\n## See also\n\n- [Checklist actions and task file](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist-actions)\n- [List checklist items](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Flist)\n- [Update a checklist item](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Fupdate)\n- [Delete a checklist item](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist\u002Fdelete)\n- [Mark an item complete with its sub-items](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist-actions\u002Fcomplete-all)\n- [Task checklist](\u002Fdocs\u002Fentities\u002Ftasks\u002Fchecklist)\n- [Tasks](\u002Fdocs\u002Fentities\u002Ftasks)\n","2026-11-12",{},1794739431282]