Skip to main content

Attendance & time

Days, punches, and the requests that correct them. Read the attendance settings before interpreting any record — a late_minutes of 20 means nothing until you know the grace period was 15.

List attendance records

GET/v1/attendance_records

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
updated_sincetimestampNoReturn records changed at or after this instant. Tracks the record itself, not its child collections.
employee_idstringNoOnly records belonging to this employee.
date_fromdateNoInclusive lower bound on the record's own date.
date_todateNoInclusive upper bound — the named day is included.
statusstring (enum)NoOnly days with this status.

Responses

StatusMeaning
200A page of attendance records.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Mark attendance

POST/v1/attendance_records

Marks one day for one employee. There is at most one record per (employee, date), so this REPLACES an existing day rather than adding a second one — which is why it answers 200 and not 201.

Unless is_manual_override is set, a status the punches contradict is re-graded by the workspace's own late thresholds: sending present for a day with a two-hour late clock-in can come back as absent. That is usually what you want, and occasionally the opposite.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
200The resulting attendance record.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409The request conflicts with the current state.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an attendance record

GET/v1/attendance_records/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The attendance record.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance record in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

List attendance punches

GET/v1/attendance_punches

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
employee_idstringNoOnly records belonging to this employee.
punch_typein · outNoOnly clock-ins, or only clock-outs.
punched_aftertimestampNoInclusive lower bound on punch_time.
punched_beforetimestampNoExclusive upper bound on punch_time.

Responses

StatusMeaning
200A page of attendance punches.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create an attendance punch

POST/v1/attendance_punches

Records a punch and applies it to the day, exactly as a device punch is applied — attribution date, lateness grading and the checkout window all behave identically.

punch_time may be backdated, since a time clock that lost connectivity has to be able to push what it buffered. It may not be post-dated.

A punch that changes no attendance record answers 409, not 201: a clock-in when the employee is already clocked in, a clock-out with no open record, or a clock-out past the checkout window. The punch is still written to the log in every one of those cases, so a 409 here means "the punch was kept but the day did not move", never "nothing happened".

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting attendance punch.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409The punch was recorded in the log but changed no attendance record. detail says which case applied.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an attendance punch

GET/v1/attendance_punches/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The attendance punch.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance punch in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve the attendance settings

GET/v1/attendance_settings

A workspace singleton, so there is no id. Read-only: these rules change how existing pay is calculated, which is not something an integration should be able to do in a single call.

Read it before interpreting any attendance record — a late_minutes of 20 means nothing until you know the grace period was 15.

Responses

StatusMeaning
200The settings.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

List attendance regularizations

GET/v1/attendance_regularizations

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
updated_sincetimestampNoReturn records changed at or after this instant. Tracks the record itself, not its child collections.
employee_idstringNoOnly records belonging to this employee.
statuspending · approved · rejectedNoOnly requests in this state.
date_fromdateNoInclusive lower bound on the record's own date.
date_todateNoInclusive upper bound — the named day is included.

Responses

StatusMeaning
200A page of attendance regularizations.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create an attendance regularization

POST/v1/attendance_regularizations

Asks to correct one day's attendance. Refused for an employee whose shift does not require punches — there is no missing-punch state to fix.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting attendance regularization.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409A regularisation for this employee and date is already awaiting a decision.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an attendance regularization

GET/v1/attendance_regularizations/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The attendance regularization.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance regularization in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Approve an attendance regularization

POST/v1/attendance_regularizations/{id}/approve

Approving REWRITES that day's attendance record and stamps it source: regularization, which then protects it from the automatic recompute. Answers 409 if the request was already decided.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The decided attendance regularization.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance regularization in this workspace.
409This request has already been decided.
429Rate limit exceeded. See the RateLimit-* headers.

Reject an attendance regularization

POST/v1/attendance_regularizations/{id}/reject

Approving REWRITES that day's attendance record and stamps it source: regularization, which then protects it from the automatic recompute. Answers 409 if the request was already decided.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The decided attendance regularization.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance regularization in this workspace.
409This request has already been decided.
429Rate limit exceeded. See the RateLimit-* headers.

List overtime requests

GET/v1/overtime_requests

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
updated_sincetimestampNoReturn records changed at or after this instant. Tracks the record itself, not its child collections.
employee_idstringNoOnly records belonging to this employee.
statuspending · approved · rejectedNoOnly requests in this state.
date_fromdateNoInclusive lower bound on the record's own date.
date_todateNoInclusive upper bound — the named day is included.

Responses

StatusMeaning
200A page of overtime requests.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create an overtime request

POST/v1/overtime_requests

Claims overtime for one day. A workspace with auto-approval enabled returns the request already approved.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting overtime request.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409An overtime request for this employee and date is already awaiting a decision.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an overtime request

GET/v1/overtime_requests/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The overtime request.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such overtime request in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Approve an overtime request

POST/v1/overtime_requests/{id}/approve

Whether approval is what makes the minutes count toward pay depends on overtime_require_approval in the attendance settings. Answers 409 if the request was already decided.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The decided overtime request.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such overtime request in this workspace.
409This request has already been decided.
429Rate limit exceeded. See the RateLimit-* headers.

Reject an overtime request

POST/v1/overtime_requests/{id}/reject

Whether approval is what makes the minutes count toward pay depends on overtime_require_approval in the attendance settings. Answers 409 if the request was already decided.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The decided overtime request.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such overtime request in this workspace.
409This request has already been decided.
429Rate limit exceeded. See the RateLimit-* headers.

List rest day swaps

GET/v1/rest_day_swaps

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
updated_sincetimestampNoReturn records changed at or after this instant. Tracks the record itself, not its child collections.
employee_idstringNoOnly records belonging to this employee.

Responses

StatusMeaning
200A page of rest day swaps.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create a rest day swap

POST/v1/rest_day_swaps

worked_date must be a rest day for that employee — a weekly off or a holiday — off_date must be an ordinary working day, and both must fall in the same calendar month.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting rest day swap.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409One of the dates is already part of another swap. A rest day can be swapped once, and a substitute day can absorb one swap.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve a rest day swap

GET/v1/rest_day_swaps/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The rest day swap.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such rest day swap in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Delete a rest day swap

DELETE/v1/rest_day_swaps/{id}

Removes the swap, restoring both days to their ordinary classification.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The deleted rest day swap, so you have what was removed.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such rest day swap in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

List employee shifts

GET/v1/employee_shifts

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
employee_idstringNoOnly records belonging to this employee.
shift_idstringNoOnly assignments of this shift.
currentbooleanNoOnly the assignment in force today.

Responses

StatusMeaning
200A page of employee shifts.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create an employee shift

POST/v1/employee_shifts

Assigns a shift from a date, closing any open assignment the day before this one starts.

Worth doing straight after creating an employee. Employee creation does not assign a shift, and an employee without one has no expected hours — so attendance has nothing to grade against and payroll cannot classify their days.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting employee shift.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409The request conflicts with the current state.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an employee shift

GET/v1/employee_shifts/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The employee shift.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such employee shift in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Delete an employee shift

DELETE/v1/employee_shifts/{id}

Removes the assignment and recomputes attendance over the period it covered, so any grading that depended on it resolves again.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The deleted employee shift, so you have what was removed.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such employee shift in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

List attendance sites

GET/v1/attendance_sites

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 100 are clamped.
starting_afterstringNoOpaque cursor from a previous response’s next_cursor.
updated_sincetimestampNoReturn records changed at or after this instant. Tracks the record itself, not its child collections.
statusactive · inactiveNoOnly sites in this state.

Responses

StatusMeaning
200A page of attendance sites.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
429Rate limit exceeded. See the RateLimit-* headers.

Create an attendance site

POST/v1/attendance_sites

Creates a geofenced site. radius_meters defaults to 150 and is bounded to 10–10000, matching what the app itself accepts.

A site with no assigned employees accepts no punches — see the assignments sub-resource.

Headers

NameTypeRequiredDescription
Idempotency-KeystringNoA unique value per logical request. Replaying it returns the original response with Idempotent-Replay: true.

Responses

StatusMeaning
201The resulting attendance site.
400The request body failed validation.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
409The request conflicts with the current state.
429Rate limit exceeded. See the RateLimit-* headers.

Retrieve an attendance site

GET/v1/attendance_sites/{id}

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The attendance site.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance site in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Update an attendance site

PATCH/v1/attendance_sites/{id}

Only the fields present in the body are changed. branch_id: null detaches the site from its branch.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The updated attendance site.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance site in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Delete an attendance site

DELETE/v1/attendance_sites/{id}

Permanent. Assignments go with it; punch-attempt history survives with the site reference cleared.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The deleted attendance site, so you have what was removed.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance site in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

List the employees assigned to a site

GET/v1/attendance_sites/{id}/assignments

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The assigned employee ids.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance site in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.

Replace the employees assigned to a site

PUT/v1/attendance_sites/{id}/assignments

Send the COMPLETE list, not a delta — it replaces whatever was assigned. An empty array unassigns everyone, which leaves the site accepting no punches.

Path parameters

NameTypeRequiredDescription
idstringYesThe identifier returned as id on the object.

Responses

StatusMeaning
200The assigned employee ids after the change.
400One of the employees is not in this workspace.
401The API key is missing, malformed, revoked or expired.
403The key does not carry the required scopes.
404No such attendance site in this workspace.
429Rate limit exceeded. See the RateLimit-* headers.