---
updatedAt: 2026-05-13T09:36:41.000Z
---

Fetch the complete documentation index at: https://developer.connecteam.com/llms.txt. Use this file to discover all available pages before exploring further.

# Lock Days

Lock or unlock individual timesheet days for a user on a Time Clock. Locking a day prevents subsequent edits to that day's time activities until it is unlocked.

## Endpoint

| Method | Endpoint                                                          | Description                              |
| :----- | :---------------------------------------------------------------- | :--------------------------------------- |
| PUT    | /time-clock/v1/time-clocks/{timeClockId}/users/{userId}/lock-days | Lock or unlock specific dates for a user |

***

## Overview

Use this endpoint to programmatically lock or unlock individual days on a user's timesheet:

* Locking a day prevents any edits to that day's punches, shifts, or breaks
* Unlocking a day restores normal edit access
* A single call can change up to **50 dates** at once
* The operation is **idempotent**: dates already in the requested state are silently skipped, and the response always reflects the final state of every date you sent
* This endpoint does **not** reopen approved payroll periods (see the warning below)

> 👍 Idempotency
>
> **Re-sending the same payload is safe.** If a date is already locked when you ask to lock it (or already unlocked when you ask to unlock it), the API returns 200 and the dates are echoed back unchanged — no error, no duplicate work, no extra BI events.

> 🚧 Approved Payroll Periods
>
> If `isLocked` is `false` and **any** of the requested dates would actually transition from locked to unlocked but fall inside an **approved** payroll period for this user, the entire request is rejected with **409 DAYS\_IN\_APPROVED\_PERIOD**. No dates are unlocked. Reopen the approved period from the dashboard first, then retry.
>
> Locking a day inside an approved period is allowed (it's already effectively locked, so it's a no-op).

***

## Authentication

* **API Key** (`X-API-KEY` header), or
* **OAuth 2.0** with scope `time_clock.write`

***

## Path Parameters

| Parameter   | Type    | Required | Description                                      |
| :---------- | :------ | :------- | :----------------------------------------------- |
| timeClockId | integer | Yes      | The Time Clock ID the user is assigned to        |
| userId      | integer | Yes      | The user whose days you are locking or unlocking |

***

## Request Body

| Field    | Type             | Required | Description                                                     |
| :------- | :--------------- | :------- | :-------------------------------------------------------------- |
| dates    | array of strings | Yes      | 1–50 unique dates in `YYYY-MM-DD` format                        |
| isLocked | boolean          | No       | `true` to lock the dates, `false` to unlock. Defaults to `true` |

***

## Example Request — Lock

```bash
curl --request PUT \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/users/9170357/lock-days \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "dates": ["2026-04-10", "2026-04-11", "2026-04-12"],
    "isLocked": true
  }'
```

## Example Request — Unlock

```bash
curl --request PUT \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/users/9170357/lock-days \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "dates": ["2026-04-10"],
    "isLocked": false
  }'
```

***

## Response Structure

```json
{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "userId": 9170357,
    "isLocked": true,
    "dates": ["2026-04-10", "2026-04-11", "2026-04-12"]
  }
}
```

## Response Fields

| Field         | Type             | Description                                              |
| :------------ | :--------------- | :------------------------------------------------------- |
| data.userId   | integer          | The user from the path, echoed back                      |
| data.isLocked | boolean          | The state applied to all requested dates                 |
| data.dates    | array of strings | The dates from your request, in the order they were sent |

***

## Error Codes

| HTTP Status | Error Code                           | Description                                                                              |
| :---------- | :----------------------------------- | :--------------------------------------------------------------------------------------- |
| `400`       | TIME\_CLOCK\_NOT\_FOUND              | The `timeClockId` does not exist                                                         |
| `400`       | USER\_NOT\_ASSIGNED\_TO\_TIME\_CLOCK | The user is valid but is not assigned to this Time Clock                                 |
| `400`       | Request body validation              | Body fails schema validation (empty dates, duplicates, invalid format, > 50 dates, etc.) |
| `400`       | Token missing required scope         | OAuth token does not include `time_clock.write`                                          |
| `403`       | LOCK\_DAYS\_DISABLED                 | Timesheet approval / lock days is disabled in this Time Clock's settings                 |
| `404`       | USER\_NOT\_FOUND                     | The `userId` does not exist in the company                                               |
| `409`       | DAYS\_IN\_APPROVED\_PERIOD           | One or more dates to unlock fall inside an approved payroll period                       |

***

## Integration Example — Lock a Pay Period After Approval

```javascript
async function lockApprovedPayPeriod(timeClockId, userId, startDate, endDate) {
  // Build the date list for the period
  const dates = [];
  const cursor = new Date(startDate);
  const end = new Date(endDate);
  while (cursor <= end) {
    dates.push(cursor.toISOString().slice(0, 10));
    cursor.setDate(cursor.getDate() + 1);
  }

  // Lock days in chunks of 50 (max per request)
  for (let i = 0; i < dates.length; i += 50) {
    const chunk = dates.slice(i, i + 50);
    const res = await fetch(
      `https://api.connecteam.com/time-clock/v1/time-clocks/${timeClockId}/users/${userId}/lock-days`,
      {
        method: 'PUT',
        headers: {
          'X-API-KEY': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ dates: chunk, isLocked: true })
      }
    );
    if (!res.ok) {
      const err = await res.json();
      throw new Error(`Lock failed for ${chunk[0]}..${chunk[chunk.length - 1]}: ${err.error}`);
    }
  }
}

// Lock January 1-31 for user 9170357 on time clock 12345
await lockApprovedPayPeriod(12345, 9170357, '2026-01-01', '2026-01-31');
```

***

## Notes

> 📝 Important Considerations
>
> * Locking and unlocking are scoped to a **single user on a single Time Clock**. Dates locked here do not affect other users or other Time Clocks.
> * The endpoint enforces a **per-request limit of 50 dates**. Loop over chunks of 50 to cover larger ranges.
> * Dates can be sent in **any order**; the response echoes them back in the same order they were sent.
> * Locking a day **does not retroactively reject existing edits** — it only prevents future edits to that day's time activities until it is unlocked.
> * The lock-days feature requires **Timesheet Approval (Lock Days)** to be enabled in the Time Clock settings. If it is disabled, the API returns 403 `LOCK_DAYS_DISABLED`.

***

[API Reference](https://developer.connecteam.com/reference/)