MASKDocs

Integration API API reference

Sessions

Shifts derived from the events, from a clock-in to the next clock-out, with work, break, personal and business time. Needs sessions:read.

A session is one shift, derived by MASK from the active events: from a clock_in to the next clock_out, and several a day are fine. Sessions are recomputed whenever an event of the shift changes, so a session's id is stable but its content is not; computedAt says when it was last recomputed.

  • status is in_progress (open), complete (closed by a clock_out) or incomplete (left open past the institution's maximum shift length and closed by MASK; endedAt is absent and the open stretch counts nothing).
  • workSeconds, breakSeconds, personalSeconds and businessSeconds are the sums of the closed stretches of each kind.
  • intervals[] are the stretches: kind, startedAt, and endedAt and seconds once closed.
  • anomalyCount counts the flagged events of the shift.

List sessions#

GET/integration/sessionsScope: sessions:read

Shifts by business date (inclusive, at most 92 days), oldest first (businessDate, startedAt, id), with intervals and totals. 403 institution_not_allowed for an institutionId outside the key.

curl -s "$MASK/integration/sessions?from=2026-11-03&to=2026-11-03&employeeId=24" -H "Authorization: Bearer $KEY"
{
  "list": [
    {
      "id": 4438,
      "employeeId": 24,
      "institutionId": 1,
      "businessDate": "2026-11-03",
      "startedAt": 1793689200,
      "endedAt": 1793719800,
      "status": "complete",
      "anomalyCount": 0,
      "workSeconds": 30600,
      "breakSeconds": 0,
      "personalSeconds": 0,
      "businessSeconds": 0,
      "intervals": [{"kind": "work", "startedAt": 1793689200, "endedAt": 1793719800, "seconds": 30600}],
      "computedAt": 1793812958
    }
  ],
  "count": 1,
  "page": 1,
  "pageSize": 50,
  "totalPages": 1
}

A shift still open (status=in_progress) has no endedAt, "workSeconds": 0, and its interval reads {"kind": "work", "startedAt": 1793811246}.

Parameters

  • fromquerydaterequired

    First business date, ISO yyyy-MM-dd, from 2000-01-01 to 2037-12-31

  • toquerydaterequired

    Last business date, ISO yyyy-MM-dd, from 2000-01-01 to 2037-12-31; from..to spans at most 92 days, both included

  • institutionIdqueryinteger

    One of the key's institutions; omitted = all of them

  • employeeIdqueryinteger

    Only this person's shifts; a person the key cannot see gives an empty list

  • statusquerystring

    all | in_progress | complete | incomplete

    default "all"

  • pagequeryinteger

    1-based

    default 1

  • pageSizequeryinteger

    1-200

    default 50

Responses

200OKSession page
Fields of Session page
  • countinteger
  • listarray of Session
    Fields of Session
    • anomalyCountinteger
    • breakSecondsinteger
    • businessDatedate

      The business date at the institution (local start time minus its day boundary), ISO date

    • businessSecondsinteger
    • computedAtinteger

      When the shift was last recomputed from its events, epoch seconds

    • employeeIdinteger
    • endedAtinteger

      Absent unless a clock_out closed the shift

    • idinteger
    • institutionIdinteger
    • intervalsarray of Interval
      Fields of Interval
      • endedAtinteger

        Absent while the stretch is open

      • kindstring

        work, break, personal or business

      • secondsinteger

        Absent while the stretch is open

      • startedAtinteger

        Epoch seconds, UTC

    • personalSecondsinteger
    • startedAtinteger

      Epoch seconds, UTC

    • statusstring

      in_progress, complete or incomplete (left open past the institution's maximum shift length)

    • workSecondsinteger
  • pageinteger
  • pageSizeinteger
  • totalPagesinteger
Errors this route can answer
  • 400Bad Requestvalidation_failedidempotency_requiredevent_too_old
  • 401Unauthorizedinvalid_api_keykey_expiredkey_revoked
  • 403Forbiddenip_not_allowedscope_missinginstitution_not_allowednot_api_eventadmin_linked_employee
  • 429Too Many Requestsrate_limited
  • 500Internal Server Errorinternal_error
  • 503Service Unavailableunavailable

Each error has the same JSON body; see Errors for what every code means.

Get session#

GET/integration/sessions/{id}Scope: sessions:read

One shift with its intervals and totals; 404 when unknown or outside the key's institutions.

A session's id stays the same when the shift is recomputed, so you can re-read a shift you stored earlier.

Parameters

  • idpathintegerrequired

Responses

200OKSession
Fields of Session
  • anomalyCountinteger
  • breakSecondsinteger
  • businessDatedate

    The business date at the institution (local start time minus its day boundary), ISO date

  • businessSecondsinteger
  • computedAtinteger

    When the shift was last recomputed from its events, epoch seconds

  • employeeIdinteger
  • endedAtinteger

    Absent unless a clock_out closed the shift

  • idinteger
  • institutionIdinteger
  • intervalsarray of Interval
    Fields of Interval
    • endedAtinteger

      Absent while the stretch is open

    • kindstring

      work, break, personal or business

    • secondsinteger

      Absent while the stretch is open

    • startedAtinteger

      Epoch seconds, UTC

  • personalSecondsinteger
  • startedAtinteger

    Epoch seconds, UTC

  • statusstring

    in_progress, complete or incomplete (left open past the institution's maximum shift length)

  • workSecondsinteger
Errors this route can answer
  • 400Bad Requestvalidation_failedidempotency_requiredevent_too_old
  • 401Unauthorizedinvalid_api_keykey_expiredkey_revoked
  • 403Forbiddenip_not_allowedscope_missinginstitution_not_allowednot_api_eventadmin_linked_employee
  • 404Not Foundnot_found
  • 429Too Many Requestsrate_limited
  • 500Internal Server Errorinternal_error
  • 503Service Unavailableunavailable

Each error has the same JSON body; see Errors for what every code means.