[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Ftasks\u002Ftime\u002Fglobal-list":3,"docs-tabs-entities\u002Ftasks\u002Ftime\u002Fglobal-list":6},{"content":4,"lastmod":5},"\n## List entries across the whole Bitrix24 account\n\n`GET \u002Fv1\u002Ftask-time`\n\nReturns time-tracking entries from all tasks in the Bitrix24 account in a single request, with filtering by employee, period and task. Use it when the list of tasks is not known in advance — for example, for an employee's monthly time report.\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|----------|-----|-----------|---------|\n| `userId` (query) | number | — | Employee identifier. List: `GET \u002Fv1\u002Fusers`. If omitted, the response includes entries for all employees the key owner can access |\n| `from` (query) | string | — | Lower bound of the period, inclusive, by the `createdDate` field. Accepts ISO 8601 `2026-05-01T00:00:00+00:00` and a plain date `2026-05-01` |\n| `to` (query) | string | — | Upper bound of the period, inclusive, by the `createdDate` field. Same format as `from`. A plain date covers the whole day |\n| `taskId` (query) | number | — | Narrow the result set to a single task, on top of `userId`, `from` and `to`. Identifier: `GET \u002Fv1\u002Ftasks` |\n| `limit` (query) | number | `50` | Page size, from 1 to 500. A value above 500 is clamped to 500 |\n| `offset` (query) | number | `0` | Offset within the result set. Must be a multiple of `limit` |\n\n**Pagination.** A single call returns up to 500 entries. With a `limit` above 50, Vibecode assembles the window server-side and returns it in full. The `offset` value must be a multiple of `limit` — `0`, `limit`, `2 × limit`, and so on, otherwise `400 INVALID_OFFSET` is returned. `meta.hasMore` indicates whether more entries exist beyond the window.\n\n**Filter format.** The generic `filter` envelope is not supported. Use the named query parameters `userId`, `taskId`, `from`, and `to`. Any bracket key `filter[...]`, a non-empty `filter` value, a JSON form including `filter={}`, or a repeated `filter` parameter returns `400 UNSUPPORTED_FILTER`. A single empty `filter=` parameter means no filter and preserves status `200`.\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftask-time?userId=1&from=2026-05-01&to=2026-05-31\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth application\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftask-time?userId=1&from=2026-05-01&to=2026-05-31\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — personal key\n\n```javascript\nconst url = 'https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftask-time?userId=1&from=2026-05-01&to=2026-05-31'\n\nconst res = await fetch(url, {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data, meta } = await res.json()\nconst totalSeconds = data.reduce((sum, r) => sum + r.seconds, 0)\nconsole.log(`For the period: ${totalSeconds \u002F 3600} h, ${meta.total} entries`)\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst url = 'https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Ftask-time?userId=1&from=2026-05-01&to=2026-05-31'\n\nconst res = await fetch(url, {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data, meta } = await res.json()\n```\n\n## Response fields\n\n| Field | Type | Description |\n|------|-----|---------|\n| `success` | boolean | Always `true` on success |\n| `data` | array | Array of time-tracking entries |\n| `data[].id` | number | Entry identifier |\n| `data[].taskId` | number | Parent task identifier. Card: `GET \u002Fv1\u002Ftasks\u002F:id` |\n| `data[].userId` | number | Entry author. Profile: `GET \u002Fv1\u002Fusers\u002F:userId` |\n| `data[].seconds` | number | Duration in seconds |\n| `data[].minutes` | number | Duration in minutes, derived from `seconds` |\n| `data[].commentText` | string | Comment for the entry. An empty comment is returned as `\"\"` |\n| `data[].source` | string | Source: `2` — REST API |\n| `data[].createdDate` | datetime | When the entry was created |\n| `data[].dateStart` | datetime | Start of the tracked interval, filled automatically |\n| `data[].dateStop` | datetime | End of the tracked interval, filled automatically |\n| `meta.total` | number | Total number of entries matching the filter |\n| `meta.limit` | number | Applied page size |\n| `meta.offset` | number | Applied offset |\n| `meta.hasMore` | boolean | Whether there are more entries beyond the current window |\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 161,\n      \"taskId\": 3881,\n      \"userId\": 1,\n      \"commentText\": \"Code review\",\n      \"seconds\": 900,\n      \"minutes\": 15,\n      \"source\": \"2\",\n      \"createdDate\": \"2026-05-13T16:15:41+00:00\",\n      \"dateStart\": \"2026-05-13T17:15:41+00:00\",\n      \"dateStop\": \"2026-05-13T17:15:41+00:00\"\n    },\n    {\n      \"id\": 159,\n      \"taskId\": 3867,\n      \"userId\": 1,\n      \"commentText\": \"Build check\",\n      \"seconds\": 600,\n      \"minutes\": 10,\n      \"source\": \"2\",\n      \"createdDate\": \"2026-05-06T10:46:12+00:00\",\n      \"dateStart\": \"2026-05-06T11:46:12+00:00\",\n      \"dateStop\": \"2026-05-06T11:46:12+00:00\"\n    },\n    {\n      \"id\": 157,\n      \"taskId\": 289,\n      \"userId\": 1,\n      \"commentText\": \"Draft preparation\",\n      \"seconds\": 1800,\n      \"minutes\": 30,\n      \"source\": \"2\",\n      \"createdDate\": \"2026-05-06T10:45:47+00:00\",\n      \"dateStart\": \"2026-05-06T11:45:47+00:00\",\n      \"dateStop\": \"2026-05-06T11:45:47+00:00\"\n    }\n  ],\n  \"meta\": {\n    \"total\": 3,\n    \"limit\": 50,\n    \"offset\": 0,\n    \"hasMore\": false\n  }\n}\n```\n\n## Error response example\n\n400 — `userId` is not a positive integer:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_USER_ID\",\n    \"message\": \"userId must be a positive integer\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|---------|\n| 400 | `INVALID_USER_ID` | `userId` is not a positive integer |\n| 400 | `INVALID_TASK_ID` | `taskId` is not a positive integer |\n| 400 | `INVALID_PARAMS` | `from` or `to` cannot be parsed as a date — `YYYY-MM-DD` and ISO 8601 are accepted |\n| 400 | `INVALID_OFFSET` | `offset` is not a multiple of `limit` — pagination requires the values `0`, `limit`, `2 × limit`, and so on |\n| 400 | `UNSUPPORTED_FILTER` | An unsupported `filter` was provided; use `userId`, `taskId`, `from`, and `to` |\n| 403 | `SCOPE_DENIED` | The API key lacks the `task` scope |\n| 401 | `TOKEN_MISSING` | The API key has no configured tokens |\n\nFull list of common API errors — [Errors](\u002Fdocs\u002Ferrors).\n\n## Known specifics\n\n**Sorted newest to oldest.** The most recently added entries are returned first. `limit` and `offset` work on top of this sort.\n\n**A malformed date is refused up front.** A `from` or `to` value that cannot be parsed as a date answers `400 INVALID_PARAMS` before Bitrix24 is called. It used to be dropped in silence and the whole range came back with status `200`, so a typo in a date read as either \"nothing in that period\" or a full dump. An empty value (`?from=`) still means \"no filter\".\n\n**An offset past the end of the result set.** A request whose `offset` exceeds the number of entries returns an empty array, and `meta.total` in that response echoes the `offset`. Detect the end of the listing by `meta.hasMore` being `false`, not by comparing `offset` with `meta.total`.\n\n## See also\n\n- [List entries of a task](.\u002Flist.md)\n- [Add an entry](.\u002Fcreate.md)\n- [Task time tracking](\u002Fdocs\u002Fentities\u002Ftasks\u002Ftime)\n- [Tasks](\u002Fdocs\u002Fentities\u002Ftasks)\n- [Employees](\u002Fdocs\u002Fentities\u002Fusers)\n- [Limits and optimization](\u002Fdocs\u002Foptimization)\n","2026-09-08",{},1794739439051]