Skip to main content
Authenticate an employee with their phone number and PIN. On success returns the employee record, current clock status, recent time entries, and a JWT, and sets an auth-token cookie.
POST /api/v1/auth/employee/verify
Authentication: none (this is how an employee obtains a token).

Request body

phone
string
required
The employee’s phone number — at least 10 characters. The server normalizes the value (strips spaces, dashes, parentheses, dots) and also matches on the last 4 digits, so common formatting variations are tolerated.
pin
string
required
The employee’s PIN — 4 to 6 digits (regex ^\d{4,6}$). Verified against the stored salted PIN hash.

Response

On success returns 200 with the employee (PIN and salt stripped), their clock status, up to 5 recent time entries, and a JWT.
data.employee
object
The employee record with its company (id, name, payPeriodType, active, bookkeeperOrgId, and the org’s overtime settings + timezone). The pin and pinSalt fields are removed.
data.clockStatus
object
data.recentTimeEntries
array
The 5 most recent time entries (newest first), each with id, clockIn, clockOut, totalHours, regularHours, overtimeHours, status.
data.token
string
The JWT to send as Authorization: Bearer <token> on employee requests. Also set as the auth-token httpOnly cookie.

Errors

StatuserrorCause
400Invalid PIN format / Invalid verification dataPIN is not 4–6 digits, or the body failed validation.
401Authentication failedNo matching active employee, or PIN incorrect.
403Company inactiveThe employee’s company is deactivated.
500Verification failedUnexpected server error.
Phone matching is lenient (exact match or last-4-digit suffix match) and only considers active employees. If two active employees share the same last 4 digits, the first match wins — pass a fully-formatted phone number to disambiguate.

Examples

curl -X POST https://app.paypunch.io/api/v1/auth/employee/verify \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "512-555-0142",
    "pin": "1234"
  }'