For AI agents: markdown of this page — /docs-content-en/entities/tasks/time/fields.md documentation index — /llms.txt
Time-tracking entry fields
GET /v1/task-time/fields
Returns the field schema of a time-tracking entry. One schema covers every task, so the path is flat and carries no task identifier.
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/task-time/fields" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth app
curl "https://vibecode.bitrix24.com/v1/task-time/fields" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/task-time/fields', {
headers: {
'X-Api-Key': 'YOUR_API_KEY',
},
})
const { success, data } = await res.json()
console.log('Fields:', Object.keys(data.fields).length)
JavaScript — OAuth app
const res = await fetch('https://vibecode.bitrix24.com/v1/task-time/fields', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.fields |
object | Entry field schema. The key is the field name in camelCase, the value is its descriptor |
data.fields.<name>.type |
string | Value type of the field: number, string or datetime |
data.fields.<name>.readonly |
boolean | true — the field is filled by the system and is not accepted on write |
data.fields.<name>.createOnly |
boolean | Present on fields accepted only when an entry is created. In an update request such a field is refused with 400 READONLY_FIELD |
data.fields.<name>.label |
string | Short name of the field |
data.fields.<name>.description |
string | Explanation of the field, including the key name in the request body when it differs from the name in the response |
The schema describes ten fields:
| Field | Type | RO | Description |
|---|---|---|---|
id |
number | yes | Entry identifier |
taskId |
number | yes | Identifier of the parent task. On the nested paths it is taken from the request path and is not set in the body |
userId |
number | The employee the time is logged for. List: GET /v1/users. Accepted on creation only, and defaults to the key owner |
|
seconds |
number | Logged duration in seconds. Required on creation, optional on update | |
minutes |
number | yes | Duration in minutes, derived from seconds |
commentText |
string | Comment for the entry. In the request body it is passed under the name comment. An empty comment arrives as an empty string |
|
source |
string | yes | Origin of the entry. The value 2 means the entry was created through the REST API |
createdDate |
datetime | Creation date in ISO 8601 with the account's UTC offset. Accepted on creation and on update, which lets you backdate an entry | |
dateStart |
datetime | yes | Start of the tracked interval in ISO 8601 with the account's UTC offset |
dateStop |
datetime | yes | End of the tracked interval in ISO 8601 with the account's UTC offset |
Response example
{
"success": true,
"data": {
"fields": {
"id": {
"type": "number",
"readonly": true,
"label": "ID",
"description": "Time-entry identifier. Serialized as a number."
},
"taskId": {
"type": "number",
"readonly": true,
"label": "Task ID",
"description": "Numeric id of the parent task. Comes from the URL path on the nested routes — not settable in the body."
},
"userId": {
"type": "number",
"readonly": false,
"label": "Author ID",
"description": "Numeric id of the user the time is logged for — an id from GET /v1/users. Optional on create (defaults to the key owner); PATCH rejects it with 400 READONLY_FIELD, because Bitrix24 cannot reassign the author.",
"createOnly": true
},
"seconds": {
"type": "number",
"readonly": false,
"label": "Seconds",
"description": "Logged duration in seconds. Required on create, optional on update. Body key: seconds."
},
"minutes": {
"type": "number",
"readonly": true,
"label": "Minutes",
"description": "Duration in minutes, derived from seconds by Bitrix24. Read-only through this API — the Vibe route never forwards it."
},
"commentText": {
"type": "string",
"readonly": false,
"label": "Comment",
"description": "Comment for the entry. On write pass it as comment in the body — commentText is the response name. An empty comment is returned as \"\", not null."
},
"source": {
"type": "string",
"readonly": true,
"label": "Source",
"description": "Origin of the entry, set by Bitrix24: \"2\" — created through the REST API."
},
"createdDate": {
"type": "datetime",
"readonly": false,
"label": "Created at",
"description": "Creation date, ISO 8601 with the account's UTC offset (for example 2026-05-13T16:15:41+00:00). Writable on create and update — pass createdDate to backdate an entry."
},
"dateStart": {
"type": "datetime",
"readonly": true,
"label": "Interval start",
"description": "Start of the tracked interval, ISO 8601 with the account's UTC offset. Filled by Bitrix24 automatically and not editable through this API."
},
"dateStop": {
"type": "datetime",
"readonly": true,
"label": "Interval end",
"description": "End of the tracked interval, ISO 8601 with the account's UTC offset. Filled by Bitrix24 automatically and not editable through this API."
}
}
}
}
Error response example
403 — scope missing:
{
"success": false,
"error": {
"code": "SCOPE_DENIED",
"message": "This endpoint requires 'task' scope"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | WRONG_PATH |
The request went to the nested path GET /v1/tasks/:taskId/time/fields. The correct flat path is named in the error text |
| 403 | SCOPE_DENIED |
The key lacks the task scope |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not sent |
Full list of common API errors — Errors.
Known specifics
The schema does not depend on the Bitrix24 account. The response is assembled on the Vibecode platform side and makes no Bitrix24 call along the way. That is why the request only needs the task scope — the account's configured tokens are not required for it.