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
| Method | Endpoint | Description |
|---|---|---|
| GET | /time-clock/v1/time-clocks/{timeClockId}/time-activities | Get time activities |
| POST | /time-clock/v1/time-clocks/{timeClockId}/time-activities | Create time activities |
| PUT | /time-clock/v1/time-clocks/{timeClockId}/time-activities | Update time activities |
| DELETE | /time-clock/v1/time-clocks/{timeClockId}/time-activities/{timeActivityId} | Delete a time activity |
Activity Types
| Type | Description |
|---|---|
shift | Regular work periods |
manual_break | Scheduled break periods |
time_off | Approved PTO entries |
Get Time Activities
Retrieve time activities within a date range.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| timeClockId | integer | Yes | Time clock ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| startDate | string | Yes | Start date (YYYY-MM-DD) |
| endDate | string | Yes | End date (YYYY-MM-DD) |
| userIds | array | No | Filter by user IDs |
| jobIds | array | No | Filter by job IDs |
| manualBreakIds | array | No | Filter by manual break type IDs |
| policyTypeIds | array | No | Filter by time-off policy type IDs |
| activityTypes | array | No | Filter by type: shift, manual_break, time_off |
Date Range LimitThe 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
| Field | Type | Description |
|---|---|---|
| id | string | Unique shift identifier |
| start | object | Start time point with timestamp, timezone, location, source |
| end | object | End time point (null if shift is ongoing) |
| jobId | string | Associated job ID |
| subJobId | string | Associated sub-job ID |
| schedulerShiftId | string | Linked scheduler shift ID |
| employeeNote | string | Note from employee |
| managerNote | string | Note from manager |
| createdAt | integer | Creation timestamp |
| modifiedAt | integer | Last modification timestamp |
| isAutoClockOut | boolean | Whether auto clock-out occurred |
| shiftAttachments | array | Attached data (forms, files, etc.) |
Create Time Activities
Create new shifts and manual breaks for users.
Locked DaysYou 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
| Field | Type | Required | Description |
|---|---|---|---|
| start | object | Yes | Start time with timestamp and timezone |
| end | object | No | End time (omit for open shift) |
| jobId | string | Conditional | Required if job tracking is enforced |
| subJobId | string | Conditional | Required if job has sub-jobs |
| employeeNote | string | No | Employee note |
| managerNote | string | No | Manager note |
Manual Break Create Fields
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Manual break type ID (from settings) |
| start | object | Yes | Start time |
| end | object | No | End time |
| employeeNote | string | No | Employee note |
| managerNote | string | No | Manager note |
Split shift on manual break (isSplitShiftOnManualBreak)
isSplitShiftOnManualBreak)Optional top-level boolean on the Create Time Activities request body. Defaults to false.
| Value | Behavior |
|---|---|
false (default) | The manual break is created without changing existing shifts. |
true | After 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 breakSplit 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 patternUse two separate API calls:
- POST — create the work shift.
- 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
| Scenario | Split happens? |
|---|---|
Shift exists → then break with isSplitShiftOnManualBreak: true | Yes |
Break with isSplitShiftOnManualBreak: true → then shift in a later call | No (too late) |
Shift + break in the same request with isSplitShiftOnManualBreak: true | Unreliable (parallel processing) |
isSplitShiftOnManualBreak: false or omitted | Never 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
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Existing shift ID |
| start | object | No | New start time |
| end | object | No | New end time |
| jobId | string | No | Change associated job |
| subJobId | string | No | Change associated sub-job |
| employeeNote | string | No | Update employee note |
| managerNote | string | No | Update 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 knowYou only supply the time clock and the activity ID. The server resolves which user the activity belongs to — no
userIdis required in the request.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| timeClockId | integer | Yes | Time clock ID |
| timeActivityId | string | Yes | Unique 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 DaysAn 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"
}