Для AI-агентов: markdown этой страницы — /docs-content/workday/records.md индекс документации — /llms.txt

История рабочего дня

GET /v1/workday/records

Возвращает историю рабочих дней сотрудника: время начала и завершения, отработанные секунды и длительность перерывов. Записи отбираются по обязательному идентификатору сотрудника и периоду, а без периода возвращается окно за последние 7 дней.

Параметры

Параметр Тип Обязательный Описание
userId (query) number да Идентификатор сотрудника, целое больше нуля. Свой идентификатор — GET /v1/users/me, список сотрудников — GET /v1/users
from (query) string нет Начало периода, ISO-8601 с явным смещением или Z — например 2026-06-01T00:00:00Z. Отбирает по времени начала дня. Дата без времени возвращает 400. Знак плюса в смещении кодируется как %2B, иначе значение приходит с пробелом вместо знака и не распознаётся
to (query) string нет Конец периода в том же формате. Значение from позже to возвращает 400
limit (query) number нет Записей на страницу, от 1 до 50. По умолчанию 50
offset (query) number нет Смещение от начала выборки, целое от нуля. По умолчанию 0. Не сочетается с page
page (query) number нет Номер страницы от единицы, равнозначен offset со значением (page − 1) × limit. Не сочетается с offset
order (query) string нет Порядок по времени начала дня: desc — от новых к старым, asc — от старых к новым. По умолчанию desc

Оба конца периода необязательны: если ни from, ни to не переданы, выборка ограничивается последними 7 днями от момента запроса. Параметр запроса вне этого списка возвращает 400 INVALID_PARAMS с именем переданного ключа и перечнем принимаемых.

Примеры

curl — личный ключ

Terminal
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://vibecode.bitrix24.tech/v1/workday/records?userId=1&from=2020-01-01T00:00:00Z&limit=3&order=asc"

curl — записи другого сотрудника

Terminal
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://vibecode.bitrix24.tech/v1/workday/records?userId=503&from=2020-01-01T00:00:00Z&limit=3&order=asc"

curl — OAuth-приложение

Terminal
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  "https://vibecode.bitrix24.tech/v1/workday/records?userId=1&from=2020-01-01T00:00:00Z&limit=3&order=asc"

JavaScript — личный ключ

javascript
const params = new URLSearchParams({
  userId: '1',
  from: '2020-01-01T00:00:00Z',
  limit: '3',
  order: 'asc',
})
const res = await fetch(`https://vibecode.bitrix24.tech/v1/workday/records?${params}`, {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data, meta } = await res.json()
for (const record of data) {
  console.log(record.startTime, '— отработано секунд:', record.duration)
}
console.log('Есть ещё записи:', meta.hasMore)

JavaScript — OAuth-приложение

javascript
const params = new URLSearchParams({
  userId: '1',
  from: '2020-01-01T00:00:00Z',
  limit: '3',
  order: 'asc',
})
const res = await fetch(`https://vibecode.bitrix24.tech/v1/workday/records?${params}`, {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})
const { data, meta } = await res.json()

Поля ответа

Поле Тип Описание
success boolean true при успешном ответе
data array Массив записей рабочего дня. Пустой массив, когда под период не попала ни одна запись
data[].id number Идентификатор записи рабочего дня
data[].userId number Идентификатор сотрудника, которому принадлежит запись
data[].startTime string Время начала дня, ISO-8601 со смещением часового пояса сотрудника
data[].endTime string Время завершения дня в том же формате
data[].duration number Отработано за день, в секундах
data[].breakLength number Суммарная длительность перерывов за день, в секундах
data[].state.status string Состояние записи в нижнем регистре. На проверенных записях приходит closed
data[].state.recommendedCloseTime string | null Рекомендованное время закрытия дня. На проверенных записях null
data[].isApproved boolean Признак подтверждённой записи рабочего дня
meta.hasMore boolean true, когда страница заполнена до limit и за ней есть продолжение
meta.total number Количество записей в выборке — сумма offset и длины страницы. Приходит только когда страница короче limit
meta.from string Нижняя граница применённого периода. Приходит, когда она задана — переданным from либо подставленным окном за последние 7 дней
meta.to string Верхняя граница применённого периода. У периода, открытого сверху (передан только from), поля нет

Пример ответа

Первые три записи от старых к новым, ?userId=1&from=2020-01-01T00:00:00Z&limit=3&order=asc:

JSON
{
  "success": true,
  "data": [
    {
      "id": 1,
      "userId": 1,
      "startTime": "2020-04-23T13:42:10+03:00",
      "endTime": "2020-04-23T17:53:26+03:00",
      "duration": 12999,
      "breakLength": 2077,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 5,
      "userId": 1,
      "startTime": "2020-04-24T09:16:12+03:00",
      "endTime": "2020-04-24T16:30:13+03:00",
      "duration": 26041,
      "breakLength": 0,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 7,
      "userId": 1,
      "startTime": "2020-04-27T09:04:11+03:00",
      "endTime": "2020-04-27T18:00:00+03:00",
      "duration": 32149,
      "breakLength": 0,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    }
  ],
  "meta": { "hasMore": true, "from": "2020-01-01T00:00:00Z" }
}

Последняя страница той же выборки, ?userId=1&from=2020-01-01T00:00:00Z&offset=40&order=asc — записей пришло меньше limit, поэтому в meta появляется total:

JSON
{
  "success": true,
  "data": [
    {
      "id": 163,
      "userId": 1,
      "startTime": "2024-07-24T17:34:51+03:00",
      "endTime": "2024-07-25T02:35:00+03:00",
      "duration": 32409,
      "breakLength": 0,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 165,
      "userId": 1,
      "startTime": "2024-08-26T12:34:47+03:00",
      "endTime": "2024-08-26T12:58:15+03:00",
      "duration": 1408,
      "breakLength": 0,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 167,
      "userId": 1,
      "startTime": "2024-09-05T12:07:30+03:00",
      "endTime": "2025-03-27T14:53:08+03:00",
      "duration": 17548827,
      "breakLength": 311,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 171,
      "userId": 1,
      "startTime": "2026-05-05T09:52:51+03:00",
      "endTime": "2026-05-05T09:53:37+03:00",
      "duration": 20,
      "breakLength": 26,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 173,
      "userId": 1,
      "startTime": "2026-05-05T09:55:38+03:00",
      "endTime": "2026-05-05T09:55:39+03:00",
      "duration": 1,
      "breakLength": 0,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    },
    {
      "id": 175,
      "userId": 1,
      "startTime": "2026-05-05T10:07:02+03:00",
      "endTime": "2026-05-05T10:07:06+03:00",
      "duration": 2,
      "breakLength": 2,
      "state": { "status": "closed", "recommendedCloseTime": null },
      "isApproved": true
    }
  ],
  "meta": { "hasMore": false, "total": 46, "from": "2020-01-01T00:00:00Z" }
}

Пример ответа при ошибке

400 — не передан обязательный параметр:

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_REQUIRED_PARAMS",
    "message": "userId is required. Bitrix24 refuses this method without it; get the id from GET /v1/users/me."
  }
}

Ошибки

HTTP Код Описание
400 MISSING_REQUIRED_PARAMS Не передан userId
400 INVALID_PARAMS Нарушена валидация параметров: некорректный userId, limit вне диапазона от 1 до 50, дата без явного смещения или несуществующая в календаре, from позже to, offset вместе с page, повторённый дважды параметр, смещение больше 999 999 999, неизвестный параметр запроса
401 MISSING_API_KEY Не передан заголовок X-Api-Key
401 INVALID_API_KEY Неверный API-ключ
401 KEY_EXPIRED Срок действия API-ключа истёк
401 TOKEN_MISSING Ключу не настроены OAuth-токены для портала
402 ACCOUNT_FROZEN Баланс портала заморожен
403 SCOPE_DENIED У ключа нет скоупа timeman
403 BITRIX_ACCESS_DENIED Битрикс24 отказал в доступе — в том числе когда у ключа нет права читать табель указанного сотрудника
409 TIMEMAN_MODULE_NOT_ENABLED Битрикс24 не принял метод. Вызовите GET /v1/workday/status: тот же отказ означает, что на портале выключен модуль учёта рабочего времени, ответ 200 — что портал не отдаёт историю рабочего дня, а текущее состояние дня остаётся доступным
422 BITRIX_ERROR Прочие отказы Битрикс24 — текст в message
429 RATE_LIMITED Превышен лимит темпа этого эндпоинта — 30 запросов в минуту на ключ. Для ключа приложения счёт ведётся отдельно по каждому сотруднику
429 RATE_LIMITED Превышен лимит запросов портала Битрикс24
502 BITRIX_UNAVAILABLE Портал Битрикс24 недоступен

Полный список общих ошибок API — Ошибки.

Известные особенности

  • Ключ не сужает права до личности вызывающего. Личный ключ vibe_api_… обращается к порталу через входящий вебхук и читает табель правами того сотрудника Битрикс24, под которым этот вебхук выпущен, — то есть правами создателя ключа, а не того, кто ключ применяет. Владелец такого ключа перебором userId выгружает приходы и уходы всей компании. Ключ приложения vibe_app_… работает иначе — запрос идёт правами сотрудника, открывшего сессию. Кто вправе читать чужой табель, решает Битрикс24, а не платформа: администратор портала или прямой руководитель сотрудника.
  • Ответ называет применённый период. meta.from и meta.to приходят и тогда, когда период не передавали: иначе meta.total со значением 0 невозможно отличить от «у сотрудника нет записей вообще», хотя это означает лишь «нет записей за последние 7 дней». У периода, открытого с одной стороны, приходит только заданная граница.
  • Параметр нельзя передавать дважды. ?userId=1&userId=2 возвращает 400, а не выбирает одно из значений молча.
  • meta.total приходит только на короткой странице. На полной странице поля в ответе нет вовсе, поэтому обработчик, читающий его безусловно, получит undefined. Значение верно на момент ответа: при order=desc запись, добавленная между двумя запросами, сдвигает окно выдачи.
  • Длительности приходят в секундах. duration и breakLength — целые числа секунд. У соседнего GET /v1/workday/status длительности отдаются строкой вида HH:MM:SS, поэтому разбор с одной страницы на другую не переносится.
  • Отбор ограничен сотрудником и временем начала дня. Других осей у эндпоинта нет: сузить выборку по времени завершения, длительности или признаку подтверждения нельзя, сортировка тоже идёт только по времени начала. Нужный срез собирается из полученных записей на своей стороне.
  • Вся история обходится страницами по 50 записей. Больше 50 записей за запрос эндпоинт не отдаёт, глубина берётся через offset или page. Признак конца выдачи — meta.hasMore со значением false. Запрос со смещением за концом выборки возвращает пустой массив, и meta.total в таком ответе не приходит.

Смотрите также