API

Clock in / clock out

Securely start or stop an employee punch from an approved partner integration.

Explicitly clock an employee in (start) or out (stop) from a trusted server-side integration.

POST https://pro.curiotime.com/api/v1/companies/{companyId}/punches
Authorization: Bearer {token}
Content-Type: application/json

Roles: owner, manager

The companyId in the route must match the company in the JWT. This endpoint does not accept or require an employee password or PIN.

Clock in

{
  "employeeId": "b8cbbc53-b2a6-43ea-8825-51e6aac0171e",
  "action": "start",
  "projectId": null,
  "subProjectId": null,
  "latitude": 64.1466,
  "longitude": -21.9426
}

Clock out

Use the same URL and employee identifier with action set to stop:

{
  "employeeId": "b8cbbc53-b2a6-43ea-8825-51e6aac0171e",
  "action": "stop",
  "latitude": 64.1466,
  "longitude": -21.9426
}

projectId and subProjectId are only used when clocking in.

Request fields

Field Required Description
employeeId Yes Employee GUID in the company
action Yes start to clock in or stop to clock out
projectId No Project GUID for clock-in; omit for clock-out
subProjectId No Subproject GUID; requires projectId
latitude, longitude No Supply both or neither. Latitude: -90…90; longitude: -180…180

Response

{
  "success": true,
  "data": {
    "message": "Clocked in.",
    "isClockedIn": true,
    "timeEntryId": "f984ec1b-8dbb-40c3-a27c-12dcadce3c83",
    "punchedAtUtc": "2026-09-30T10:00:00Z",
    "punchPhotoUploadGrant": null,
    "punchPhotoUploadGrantExpiresAtUtc": null
  },
  "errors": null
}

Errors and retrying

Status Meaning
400 Invalid request, coordinates or action
401 Missing, expired or invalid Bearer token
403 Role is not allowed, or token company does not match the route
404 Employee, project or related resource was not found
409 State conflict, such as starting an already-open punch
429 More than 120 punch requests per minute for the authenticated subject

Do not blindly retry 400, 403, 404 or 409. On 429, retry with exponential backoff. Use the returned timeEntryId as the system record identifier.

If the connection times out after sending a punch, read the employee’s time entries to confirm whether the state changed before retrying. The endpoint does not currently accept an idempotency key.