When to use this endpoint

Use UserClockin_closeEarlierOpenSessions only as the repair step after UserClockin_new or UserClockin_setClockoutTime returns earlier_clockins_open. Retry the original create/clock-out request after this call succeeds.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session.

In id mode the row must belong to the signed-in user. In proposed-clockin mode the handler always uses the signed-in user; it cannot repair another user’s sessions.

Parameters

ParameterTypeRequiredDescription
idInteger stringOne of id or clockinCurrent open session ID. A positive ID takes precedence over clockin, must exist, must belong to the signed-in user, and must have a positive clock-in with no clock-out.
clockinUnix secondsOne of id or clockinProposed start of a not-yet-created self clock-in. Used only when id integer-converts below 1.

Example request

$repair = FM_api('UserClockin_closeEarlierOpenSessions', [
	'clockin' => (string) $newClockinEpoch,
]);

Example response

{
  "ok": 1,
  "closed": 2,
  "sessions": [
    {"id": 81, "clockout": 1788278400},
    {"id": 93, "clockout": 1788364800}
  ]
}

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error":"missing or invalid parameter: id or clockin"}Neither parameter integer-converts above zero. This check runs before the explicit login check.
{"error":"clockin does not exist"}A positive id does not resolve in the tenant.
{"error":"no permission to update this clockin"}The current row belongs to another user.
{"error":"current clockin is not open"}The current row has no positive clock-in or already has a clock-out.
{"error":"...","error_code":"manual_clockin_correction_required","session":{...},"conflict":{...}}At least one proposed repair would overlap a stored session or the proposed not-yet-created session. No repairs are written.
{"error":"failed to close earlier clock-in sessions"}The final batch update reports failure.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Earlier means a lower clock-in epoch, or the same epoch with a lower ID when a current id is supplied. Results are considered in descending clock-in/ID order.
  • Each proposed clock-out is the later of one second after that row’s clock-in and the end of its effective workday. The effective workday uses the tenant timezone, the user’s custom work shifts or company work-day-start/work-day-end/week-days-off defaults, and approved Availability rules. When HR enhancements are disabled it uses company defaults and ignores Availability events.
  • Overnight shifts can close on the following date. If no effective work interval exists, or the stored clock-in is already after its workday end, the row closes one second after clock-in.
  • With no earlier rows the exact response is {"ok":1,"closed":0,"sessions":[]}. The returned sessions list contains synthetic proposals and is not re-read after the update.

Side effects

  • For every still-open earlier row, sets clockout, recalculates gross duration, and invalidates the user-clock-ins cache.
  • If a row has no clock-out creation timestamp, also records the current server epoch in clockout_cdate and stores current time minus the proposed clock-out in clockout_diff. Existing creation/difference values are preserved.
  • Does not write generic audit history and does not change the current/proposed session.

See it in Fieldmotion

CRM1

The header clock-in/clock-out widgets offer this repair when an earlier open session blocks the requested action.

CRM2

The quick clock-in menu follows the same repair-and-retry flow.

Related endpoints