Manual Break Clocking

Start and end a live manual break for an employee, mirroring the Connecteam mobile app's "take a break" experience. Unlike Create time activities — which writes a completed, historical break — these endpoints open and close a break in the live punch lifecycle, so a physical clock device or kiosk stays in sync with the employee's real state.

The key advantage is the automatic shift transition: if the employee is clocked into a shift when the break starts, the server closes that shift and opens the break in a single call. When the break ends, the server can re-open the shift on the same job automatically — no two-step orchestration, no race conditions on flaky connections.

Endpoints

MethodEndpointDescription
POST/time-clock/v1/time-clocks/{timeClockId}/manual-breaks/{manualBreakId}/clock-inStart a manual break (auto-closes an open shift)
POST/time-clock/v1/time-clocks/{timeClockId}/manual-breaks/clock-outEnd the open manual break (optionally resume the shift)
📘

Get the manual break IDs first

The manualBreakId path parameter is the ID of a manual break type configured on the time clock (e.g. "Lunch", "Rest"). Retrieve the available types — and whether manual breaks are enabled — from Settings & Configuration (GET /time-clock/v1/time-clocks/{timeClockId}/manual-breaks).


How It Works

These endpoints reproduce the mobile app's one-tap break flow. The server inspects the employee's current state and does the right thing automatically.

Starting a break (clock-in)

State when calling clock-inServer actionResponse
Idle (not on a shift)Opens a standalone breakisSwitchFromShift: false
On an open shift (same time clock)Closes the shift and opens the break in one call, attributing the break to the shift's jobisSwitchFromShift: true, closedShift present
Already on a manual breakRejected400 ALREADY_ON_BREAK
On an open shift on a different time clockBreak starts independently (per-time-clock state)isSwitchFromShift: false

Ending a break (clock-out)

State when calling clock-outisResumeShift (request)Server actionResponse
Break started from a shifttrue (default)Ends the break and re-opens the source shift on the same jobisResumeShift: true, resumedShift present
Break started from a shiftfalseEnds the break only — employee becomes idleisResumeShift: false
Standalone breakanyEnds the break only — no shift to resumeisResumeShift: false
No open breakanyRejected400 NO_OPEN_BREAK
👍

The response reflects the actual outcome

isResumeShift in the response may be false even if you requested true — for example, when the break was standalone and there is no shift to resume. Always read the returned value rather than assuming the request value was applied.


Mandatory Breaks (Early-Return Restriction)

A manual break type can be configured as mandatory with a minimum duration. When a break is mandatory, the employee cannot end it early — it must run for its full configured duration. This mirrors the mobile and dashboard behavior, where the "End break" button is disabled until the minimum is reached.

Elapsed time (break start → end)Result
≤ 45 secondsAllowed — short grace window to undo an accidental start
45s < elapsed < configured durationBlocked400 MANDATORY_BREAK_TOO_SHORT
≥ configured durationAllowed
🚧

The restriction applies to every end path

Mandatory minimums are enforced even when isResumeShift: true. An employee cannot use auto-resume to return to their job before a mandatory break completes. For non-mandatory breaks there is no restriction — they can be ended at any time.

When an offline timestamp is supplied on clock-out, the elapsed duration is measured against that timestamp (not the current server time), so a break that legitimately ran its full duration offline is not wrongly blocked.


Offline Mode (Retroactive Punches)

Both endpoints accept an optional timestamp (Unix seconds), identical in behavior to Real-Time Clocking. Use it when a physical clock device flushes queued punches after reconnecting, so the timesheet reflects when the break actually happened.

📘

Timestamp rules (when timestamp is supplied)

  • Unix time in seconds
  • Not in the future
  • No more than 12 hours in the past
  • Clock-out only: must be strictly after the open break's start time
  • Clock-out only: the punch day must not be locked or approved
  • Must not overlap an already-completed shift or break
  • When omitted, the server captures the time at request receipt

For breaks older than 12 hours, use Create time activities instead.


Authentication

Both endpoints require authentication via API key or OAuth 2.0.

  • API KeyX-API-KEY header, or
  • OAuth 2.0 — scope time_clock.write

Clock In to a Manual Break

Start a manual break for an employee. If the employee is clocked into a shift on the same time clock, the shift is automatically closed and the break is started in one call (attributed to the shift's job). If the employee is idle, the break starts standalone.

Path Parameters

ParameterTypeRequiredDescription
timeClockIdintegerYesTime clock ID
manualBreakIdstringYesID of the manual break type to start (from the manual-breaks settings)

Request Body

FieldTypeRequiredDescription
userIdintegerYesUser's ID (must be assigned to the time clock)
timezonestringNoTz format (e.g., America/New_York). Defaults to the time clock setting
timestampintegerNoBreak-start time in Unix seconds. Omitted = server-now. Max 12 hours in the past; not in the future. Use when flushing offline punches.
locationDataobjectNoGPS coordinates and address
locationData.latitudenumberNoLatitude coordinate
locationData.longitudenumberNoLongitude coordinate
locationData.addressstringNoAddress associated with the GPS data
⚠️

User Assignment & Manual Breaks Enabled

The user must be assigned to the time clock, and manual breaks must be enabled for that time clock. Otherwise the request is rejected with USER_NOT_ASSIGNED or MANUAL_BREAKS_DISABLED.

Example: Start a Break While Idle (Standalone)

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/8b8a161e-dfb5-42ac-bbf0-0448fc0c0c82/clock-in \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York"
  }'

Example: Start a Break From an Open Shift (Auto-Close Shift)

When the employee is on a shift, the same call closes the shift and opens the break:

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/8b8a161e-dfb5-42ac-bbf0-0448fc0c0c82/clock-in \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York"
  }'

Example: Start a Break With Location

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/8b8a161e-dfb5-42ac-bbf0-0448fc0c0c82/clock-in \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York",
    "locationData": {
      "address": "123 Main St, New York, NY 10001",
      "latitude": 40.7128,
      "longitude": -74.0060
    }
  }'

Example: Retroactive Break Start (Offline Mode)

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/8b8a161e-dfb5-42ac-bbf0-0448fc0c0c82/clock-in \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York",
    "timestamp": 1748345820
  }'

The returned data.start.timestamp equals 1748345820.

Response: Break Started While Idle

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "id": "break_activity_xyz789",
    "start": {
      "timestamp": 1748345820,
      "timezone": "America/New_York"
    },
    "isSwitchFromShift": false
  }
}

Response: Break Started From an Open Shift

The closedShift object describes the shift that was automatically closed:

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "id": "break_activity_xyz789",
    "start": {
      "timestamp": 1748345820,
      "timezone": "America/New_York"
    },
    "isSwitchFromShift": true,
    "closedShift": {
      "id": "shift-abc123",
      "userId": 9170357,
      "start": {
        "timestamp": 1748342220,
        "timezone": "America/New_York",
        "source": { "type": "api" }
      },
      "end": {
        "timestamp": 1748345820,
        "timezone": "America/New_York",
        "source": { "type": "api" }
      },
      "jobId": "job-123"
    }
  }
}

Clock-In Response Fields

FieldTypeDescription
requestIdstringUnique identifier for this API request
data.idstringID of the break activity that was started
data.start.timestampintegerBreak start time recorded by the server (Unix seconds)
data.start.timezonestringTz format timezone
data.isSwitchFromShiftbooleantrue if an open shift was automatically closed to start this break; false if the employee was idle
data.closedShiftobjectThe shift that was closed. Present only when isSwitchFromShift is true

Clock Out From a Manual Break

End the currently open manual break. By default, if the break was started from an open shift, the shift is re-opened on the same job (mobile "Return to job"). Set isResumeShift: false to end the break without resuming (mobile "End shift").

Path Parameters

ParameterTypeRequiredDescription
timeClockIdintegerYesTime clock ID
📝

No manualBreakId on clock-out

Clock-out targets whichever manual break is currently open for the user, so the break type ID is not part of the path.

Request Body

FieldTypeRequiredDescription
userIdintegerYesUser's ID (must be assigned to the time clock)
timezonestringNoTz format. Defaults to the time clock setting
timestampintegerNoBreak-end time in Unix seconds. Omitted = server-now. Max 12 hours in the past; not in the future; must be after the open break's start.
isResumeShiftbooleanNoDefaults to true (mobile "Return to job"). When true and the break came from a shift, the shift is re-opened on the same job. Set to false to end the break without resuming.
locationDataobjectNoGPS coordinates and address
locationData.latitudenumberNoLatitude coordinate
locationData.longitudenumberNoLongitude coordinate
locationData.addressstringNoAddress associated with the GPS data
📝

Open Break Required

The user must have an open manual break in this time clock. If there is no open break, the request is rejected with NO_OPEN_BREAK.

Example: End Break and Return to Job (Default)

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/clock-out \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York"
  }'

Example: End Break Without Resuming the Shift

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/clock-out \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York",
    "isResumeShift": false
  }'

Example: Retroactive Break End (Offline Mode)

curl --request POST \
  --url https://api.connecteam.com/time-clock/v1/time-clocks/12345/manual-breaks/clock-out \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: YOUR_API_KEY' \
  --data '{
    "userId": 9170357,
    "timezone": "America/New_York",
    "timestamp": 1748349420
  }'

The returned data.end.timestamp equals 1748349420.

Response: Break Ended and Shift Resumed

The resumedShift object describes the shift that was re-opened:

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "id": "break_activity_xyz789",
    "end": {
      "timestamp": 1748349420,
      "timezone": "America/New_York"
    },
    "isResumeShift": true,
    "resumedShift": {
      "id": "shift-def456",
      "userId": 9170357,
      "start": {
        "timestamp": 1748349420,
        "timezone": "America/New_York",
        "source": { "type": "api" }
      },
      "jobId": "job-123"
    }
  }
}

Response: Break Ended, No Shift Resumed

Returned for a standalone break, or when isResumeShift: false:

{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "id": "break_activity_xyz789",
    "end": {
      "timestamp": 1748349420,
      "timezone": "America/New_York"
    },
    "isResumeShift": false
  }
}

Clock-Out Response Fields

FieldTypeDescription
requestIdstringUnique identifier for this API request
data.idstringID of the break activity that was ended
data.end.timestampintegerBreak end time recorded by the server (Unix seconds)
data.end.timezonestringTz format timezone
data.isResumeShiftbooleanThe actual outcome: true if a shift was re-opened, false otherwise (standalone break, or isResumeShift: false)
data.resumedShiftobjectThe shift that was re-opened. Present only when isResumeShift is true

Integration Example

A complete "take a break and return to job" flow, plus offline flush:

class ManualBreakIntegration {
  constructor(apiKey, timeClockId) {
    this.apiKey = apiKey;
    this.timeClockId = timeClockId;
    this.baseUrl = 'https://api.connecteam.com/time-clock/v1/time-clocks';
  }

  get headers() {
    return { 'X-API-KEY': this.apiKey, 'Content-Type': 'application/json' };
  }

  // Start a break. If the user is on a shift, the shift auto-closes.
  async startBreak(userId, manualBreakId, { location, timestamp } = {}) {
    const body = {
      userId,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    };
    if (location) body.locationData = location;
    if (timestamp != null) body.timestamp = timestamp;

    const res = await fetch(
      `${this.baseUrl}/${this.timeClockId}/manual-breaks/${manualBreakId}/clock-in`,
      { method: 'POST', headers: this.headers, body: JSON.stringify(body) }
    );
    return res.json();
  }

  // End the open break. Defaults to returning to the source shift.
  async endBreak(userId, { isResumeShift = true, location, timestamp } = {}) {
    const body = {
      userId,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      isResumeShift,
    };
    if (location) body.locationData = location;
    if (timestamp != null) body.timestamp = timestamp;

    const res = await fetch(
      `${this.baseUrl}/${this.timeClockId}/manual-breaks/clock-out`,
      { method: 'POST', headers: this.headers, body: JSON.stringify(body) }
    );
    return res.json();
  }
}

const mb = new ManualBreakIntegration('YOUR_API_KEY', 12345);

// On shift → tap "take break" → shift auto-closes, break opens
const started = await mb.startBreak(9170357, '8b8a161e-dfb5-42ac-bbf0-0448fc0c0c82');
console.log('Switched from shift:', started.data.isSwitchFromShift); // true

// Tap "return to job" → break closes, shift re-opens on the same job
const ended = await mb.endBreak(9170357); // isResumeShift defaults to true
console.log('Resumed shift:', ended.data.isResumeShift); // true

Error Responses

HTTP StatusError CodeWhen
400MANUAL_BREAKS_DISABLEDManual breaks are not enabled for the time clock
400MANUAL_BREAK_NOT_FOUNDThe manualBreakId does not exist on the time clock or has been deleted
400ALREADY_ON_BREAK(Clock-in only.) The user is already on an open manual break
400NO_OPEN_BREAK(Clock-out only.) The user has no open manual break to end
400MANDATORY_BREAK_TOO_SHORT(Clock-out only.) The break is mandatory and its minimum duration has not elapsed
400INVALID_TIMESTAMP_FUTURESupplied timestamp is in the future
400INVALID_TIMESTAMP_TOO_OLDtimestamp is more than 12 hours in the past
400INVALID_TIMESTAMP_BEFORE_START(Clock-out only.) timestamp is at or before the open break's start time
400OUTSIDE_GEOFENCEPunch location is outside the configured geofence
400LOCATION_REQUIREDLocation data is required by the time clock's geofence configuration
400USER_NOT_ASSIGNEDThe user is not assigned to the time clock
409HAS_LOCKED_DAYSThe punch falls on a locked or approved timesheet day

Notes

📝

Important Considerations

  • Switch attribution: when a break is started from a shift, the break is attributed to the shift's job for payroll. The closed shift's end equals the break's start.
  • Out of scope: switching to a different job when ending a break, NFC tag handoff, and outside-geofence approval-request fallback are not supported by these endpoints.
  • Per-time-clock state: break state is tracked independently per time clock. A shift open on a different time clock is not affected by a break here.
  • For completed/historical breaks (older than 12 hours, or bulk imports), use Create time activities.
  • See Real-Time Clocking for the shift-level clock-in/clock-out equivalents.

Clock In API Reference · Clock Out API Reference