Time Activities

Time activities are the work records in a time clock, including shifts, manual breaks, and time offs. This page covers querying, creating, updating, and deleting time activities.

Endpoints

MethodEndpointDescription
GET/time-clock/v1/time-clocks/{timeClockId}/time-activitiesGet time activities
POST/time-clock/v1/time-clocks/{timeClockId}/time-activitiesCreate time activities
PUT/time-clock/v1/time-clocks/{timeClockId}/time-activitiesUpdate time activities
DELETE/time-clock/v1/time-clocks/{timeClockId}/time-activities/{timeActivityId}Delete a time activity

Activity Types

TypeDescription
shiftRegular work periods
manual_breakScheduled break periods
time_offApproved PTO entries

Get Time Activities

Retrieve time activities within a date range.

Path Parameters

ParameterTypeRequiredDescription
timeClockIdintegerYesTime clock ID

Query Parameters

ParameterTypeRequiredDescription
startDatestringYesStart date (YYYY-MM-DD)
endDatestringYesEnd date (YYYY-MM-DD)
userIdsarrayNoFilter by user IDs
jobIdsarrayNoFilter by job IDs
manualBreakIdsarrayNoFilter by manual break type IDs
policyTypeIdsarrayNoFilter by time-off policy type IDs
activityTypesarrayNoFilter by type: shift, manual_break, time_off
⚠️

Date Range Limit

The date range cannot exceed 92 days (approximately 3 months).

Example Request

curl --request GET \
  --url 'https://api.connecteam.com/time-clock/v1/time-clocks/12345/time-activities?startDate=2024-01-01&endDate=2024-01-31&activityTypes=shift' \
  --header 'X-API-KEY: YOUR_API_KEY'

Response Structure

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "timeActivitiesByUsers": [
      {
        "userId": 9170357,
        "shifts": [
          {
            "id": "shift-abc123",
            "start": {
              "timestamp": 1704110400,
              "timezone": "America/New_York",
              "locationData": {
                "address": "123 Main St, New York, NY",
                "latitude": 40.7128,
                "longitude": -74.0060
              },
              "source": {
                "type": "mobile"
              }
            },
            "end": {
              "timestamp": 1704139200,
              "timezone": "America/New_York",
              "source": {
                "type": "mobile"
              }
            },
            "jobId": "job-123",
            "subJobId": "subjob-456",
            "schedulerShiftId": "sched-789",
            "employeeNote": "Completed delivery route",
            "managerNote": "",
            "createdAt": 1704110400,
            "modifiedAt": 1704139200,
            "isAutoClockOut": false,
            "shiftAttachments": []
          }
        ],
        "manualBreaks": [],
        "timeOffs": []
      }
    ]
  }
}

Shift Response Fields

FieldTypeDescription
idstringUnique shift identifier
startobjectStart time point with timestamp, timezone, location, source
endobjectEnd time point (null if shift is ongoing)
jobIdstringAssociated job ID
subJobIdstringAssociated sub-job ID
schedulerShiftIdstringLinked scheduler shift ID
employeeNotestringNote from employee
managerNotestringNote from manager
createdAtintegerCreation timestamp
modifiedAtintegerLast modification timestamp
isAutoClockOutbooleanWhether auto clock-out occurred
shiftAttachmentsarrayAttached data (forms, files, etc.)

Create Time Activities

Create new shifts and manual breaks for users.

📝

Locked Days

You cannot create time activities on days that are locked or approved. Check timesheet status before creating entries.

Request Body

{
  "isSplitShiftOnManualBreak": false,
  "timeActivities": [
    {
      "userId": 9170357,
      "shifts": [
        {
          "start": {
            "timestamp": 1704110400,
            "timezone": "America/New_York"
          },
          "end": {
            "timestamp": 1704139200,
            "timezone": "America/New_York"
          },
          "jobId": "job-123",
          "employeeNote": "Imported from external system",
          "managerNote": "Verified"
        }
      ],
      "manualbreaks": []
    }
  ]
}

Shift Create Fields

FieldTypeRequiredDescription
startobjectYesStart time with timestamp and timezone
endobjectNoEnd time (omit for open shift)
jobIdstringConditionalRequired if job tracking is enforced
subJobIdstringConditionalRequired if job has sub-jobs
employeeNotestringNoEmployee note
managerNotestringNoManager note

Manual Break Create Fields

FieldTypeRequiredDescription
idstringYesManual break type ID (from settings)
startobjectYesStart time
endobjectNoEnd time
employeeNotestringNoEmployee note
managerNotestringNoManager note

Split shift on manual break (isSplitShiftOnManualBreak)

Optional top-level boolean on the Create Time Activities request body. Defaults to false.

ValueBehavior
false (default)The manual break is created without changing existing shifts.
trueAfter the manual break is created, any overlapping completed work shift is split into two shifts around the break window — one ending at break start, one starting at break end. Matches the Time Clock dashboard behavior when an admin adds a manual break inside a shift.

isSplitShiftOnManualBreak applies only when creating manual breaks. It has no effect when creating shifts.

⚠️

Shift must exist before the break

Split logic runs immediately when the manual break is created. It looks up shifts that already exist in the time clock at that moment. It does not run when you create a shift, and it does not re-run if you add a shift later.

👍

Recommended integration pattern

Use two separate API calls:

  1. POST — create the work shift.
  2. POST — create the manual break with "isSplitShiftOnManualBreak": true.

Do not rely on array order inside a single request. Shifts and manual breaks in the same POST are processed in parallel, so the break may be created before the shift is persisted and splitting will be skipped.

Example: shift already exists → add break with split

Suppose a user has a completed shift from 9:00–17:00. Add a 12:00–13:00 lunch break and split the shift:

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/time-activities \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "isSplitShiftOnManualBreak": true,
    "timeActivities": [
      {
        "userId": 9170357,
        "shifts": [],
        "manualBreaks": [
          {
            "id": "manual-break-type-id",
            "start": {
              "timestamp": 1706011200,
              "timezone": "America/New_York"
            },
            "end": {
              "timestamp": 1706014800,
              "timezone": "America/New_York"
            }
          }
        ]
      }
    ]
  }'

Result: two shifts (9:00–12:00 and 13:00–17:00) plus the manual break.

Example: two-step workflow (recommended)

// Step 1 — create the work shift
await fetch(
  `https://api.connecteam.com/time-clock/v1/time-clocks/${timeClockId}/time-activities`,
  {
    method: 'POST',
    headers: { 'X-API-KEY': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      timeActivities: [{
        userId: 9170357,
        shifts: [{
          start: { timestamp: 1705986000, timezone: 'America/New_York' },
          end:   { timestamp: 1706014800, timezone: 'America/New_York' },
          jobId: 'job-123'
        }],
        manualBreaks: []
      }]
    })
  }
);

// Step 2 — add manual break and split the shift
await fetch(
  `https://api.connecteam.com/time-clock/v1/time-clocks/${timeClockId}/time-activities`,
  {
    method: 'POST',
    headers: { 'X-API-KEY': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      isSplitShiftOnManualBreak: true,
      timeActivities: [{
        userId: 9170357,
        shifts: [],
        manualBreaks: [{
          id: 'manual-break-type-id',
          start: { timestamp: 1706001600, timezone: 'America/New_York' },
          end:   { timestamp: 1706005200, timezone: 'America/New_York' }
        }]
      }]
    })
  }
);

Order and timing reference

ScenarioSplit happens?
Shift exists → then break with isSplitShiftOnManualBreak: trueYes
Break with isSplitShiftOnManualBreak: true → then shift in a later callNo (too late)
Shift + break in the same request with isSplitShiftOnManualBreak: trueUnreliable (parallel processing)
isSplitShiftOnManualBreak: false or omittedNever splits

Open (in-progress) shifts are not split — only completed shifts that overlap the break window.

Example: Create Shift

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/time-activities \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "timeActivities": [
      {
        "userId": 9170357,
        "shifts": [
          {
            "start": {
              "timestamp": 1704110400,
              "timezone": "America/New_York"
            },
            "end": {
              "timestamp": 1704139200,
              "timezone": "America/New_York"
            },
            "jobId": "job-123"
          }
        ],
        "manualbreaks": []
      }
    ]
  }'

Example: Bulk Import

async function importTimeActivities(timeClockId, activities) {
  const BATCH_SIZE = 100;
  
  for (let i = 0; i < activities.length; i += BATCH_SIZE) {
    const batch = activities.slice(i, i + BATCH_SIZE);
    
    await fetch(
      `https://api.connecteam.com/time-clock/v1/time-clocks/${timeClockId}/time-activities`,
      {
        method: 'POST',
        headers: {
          'X-API-KEY': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ timeActivities: batch })
      }
    );
  }
}

Update Time Activities

Modify existing shifts and manual breaks.

Request Body

{
  "timeActivities": [
    {
      "userId": 9170357,
      "shifts": [
        {
          "id": "shift-abc123",
          "start": {
            "timestamp": 1704111000,
            "timezone": "America/New_York"
          },
          "end": {
            "timestamp": 1704140000,
            "timezone": "America/New_York"
          },
          "managerNote": "Adjusted per employee request"
        }
      ],
      "manualbreaks": []
    }
  ]
}

Shift Update Fields

FieldTypeRequiredDescription
idstringYesExisting shift ID
startobjectNoNew start time
endobjectNoNew end time
jobIdstringNoChange associated job
subJobIdstringNoChange associated sub-job
employeeNotestringNoUpdate employee note
managerNotestringNoUpdate manager note

Example: Adjust Shift Times

curl --request PUT \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/time-activities \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "timeActivities": [
      {
        "userId": 9170357,
        "shifts": [
          {
            "id": "shift-abc123",
            "end": {
              "timestamp": 1704142800,
              "timezone": "America/New_York"
            },
            "managerNote": "Extended shift for project completion"
          }
        ],
        "manualbreaks": []
      }
    ]
  }'

Delete Time Activity

Delete a single time activity — a shift or a manual break — by its unique ID. This is the same id returned by Get Time Activities and used in Update Time Activities.

👍

Good to know

You only supply the time clock and the activity ID. The server resolves which user the activity belongs to — no userId is required in the request.

Path Parameters

ParameterTypeRequiredDescription
timeClockIdintegerYesTime clock ID
timeActivityIdstringYesUnique identifier of the time activity to delete

Authentication

Requires the time_clock.delete scope (or an API key).

Behavior

  • Deletes one activity identified by timeActivityId. Deleting a manual break leaves its parent shift intact.
  • The activity must belong to the specified time clock; otherwise the request returns 404 TIME_ACTIVITY_NOT_FOUND.
  • Deletes are idempotent — deleting an already-deleted or non-existent activity returns 404 TIME_ACTIVITY_NOT_FOUND.
  • Time-off / absence entries are not addressable here and resolve to 404 TIME_ACTIVITY_NOT_FOUND.
🚧

Locked Days

An activity that falls on a locked or approved timesheet day cannot be deleted. The request fails with HAS_LOCKED_DAYS — unlock or reject the approval first.

Example Request

curl --request DELETE \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/time-activities/666edfbac1ed5f748fabd3d2 \
  --header 'X-API-KEY: YOUR_API_KEY'

Response Structure

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {}
}

A 200 OK with an empty data object confirms the deletion.


Error Responses

400 Bad Request

User not assigned to time clock:

{
  "detail": ["User 9170357 is not assigned to time clock 12345"]
}

Locked days:

{
  "detail": ["User: 9170357 has locked days: ['2024-01-15', '2024-01-16']"]
}

Invalid job:

{
  "detail": ["jobs: ['job-invalid'] not in the required time clock"]
}

Manual breaks disabled:

{
  "detail": "manual breaks are disabled for the given time clock"
}

Delete Time Activity Errors

Invalid ID format (400):

{
  "details": null,
  "error": "INVALID_ID: 'abc' is not a valid time activity identifier",
  "path": "/time-clock/v1/time-clocks/{timeClockId}/time-activities/{timeActivityId}",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Activity not found (404):

{
  "details": null,
  "error": "TIME_ACTIVITY_NOT_FOUND: no active shift or manual break matches '666edfbac1ed5f748fabd3d2' under this time clock",
  "path": "/time-clock/v1/time-clocks/{timeClockId}/time-activities/{timeActivityId}",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Locked or approved days (400):

{
  "details": null,
  "error": "HAS_LOCKED_DAYS: time activity for user 12345 falls on locked or approved days ['2024-01-23']. Unlock or reject the approval before retrying",
  "path": "/time-clock/v1/time-clocks/{timeClockId}/time-activities/{timeActivityId}",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

API Reference