Klees

REST API

Klees public REST API — authentication, rate limits, endpoint reference, webhooks, and the integration patterns most customers use for custom payroll and HR workflows.

Updated May 29, 2026

Klees ships a REST API that mirrors what the apps do. Every action a manager can take in the UI is available programmatically. The API is the integration layer for custom payroll, HR, BI warehouses, and bespoke field-ops workflows. For the related security model, see Security and Compliance.

Base URL and versioning

https://api.klees.app/v1

The API is versioned at the path level. Breaking changes ship as v2. Non-breaking additions (new fields, new endpoints) ship within the current major version.

All endpoints return JSON with a consistent envelope:

{
  "data": { },
  "meta": {
    "request_id": "req_01HZ...",
    "took_ms": 24
  }
}

Errors:

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or expired token",
    "request_id": "req_01HZ..."
  }
}

Authentication

The API uses bearer tokens. From Settings → API Keys, an Admin or Owner creates a token with a label, optional expiration, and a scope (read-only, read-write, or resource-scoped).

GET /v1/workers
Authorization: Bearer kl_live_abc123...
Accept-Language: en-US

Tokens are shown once at creation — store them in your secret manager. Rotation is zero-downtime (create new, revoke old). Every API call is recorded in the audit log. OAuth 2.0 is available on Enterprise.

Rate limits

TierPer-secondPer-minutePer-day
Standard530050,000
Pro10600200,000
EnterpriseNegotiatedNegotiatedUnlimited (fair use)

Rate limit headers ship on every response:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1748736000

A 429 response includes Retry-After in seconds. Clients should implement exponential backoff with jitter.

Common endpoints

A non-exhaustive list of the most-used endpoints:

MethodPathPurpose
GET/v1/workersList workers (paginated)
GET/v1/workers/{id}Worker detail
POST/v1/workersCreate a worker (invite)
GET/v1/jobsList jobs
POST/v1/jobsCreate a job
GET/v1/jobs/{id}Job detail with geofence and budget
GET/v1/time-entriesList time entries (filterable by date, worker, job, status)
POST/v1/time-entries/{id}/approveApprove a time entry
POST/v1/time-entries/{id}/rejectReject with note
GET/v1/customersList customers
GET/v1/reports/job-costingJob costing report (JSON or CSV)
POST/v1/exports/payrollTrigger a payroll export
GET/v1/audit-logAudit log entries

Full reference with request and response shapes lives at https://api.klees.app/docs.

Pagination and filtering

Listing endpoints accept limit (default 50, max 200) and cursor. Most accept filter parameters that mirror the UI:

GET /v1/time-entries?from=2026-05-01&to=2026-05-31&status=approved&worker_id=W001

Multiple values on a single filter use comma separation. Date filters accept ISO-8601.

Webhooks

Klees can push events to your HTTP endpoint. From Settings → Webhooks, register a URL and pick which events you want.

Common events:

  • time_entry.created — a worker clocked in or out
  • time_entry.approved — a manager approved
  • time_entry.flagged_pinshot_low — PinShot scored below threshold
  • time_entry.flagged_outside_fence — worker clocked in outside the job geofence
  • job.created
  • job.budget_threshold — job crossed 75/100/110% of budget
  • schedule.published
  • payroll.export_completed

Webhook delivery uses signed requests:

POST /your-handler HTTP/1.1
Host: your-app.example.com
Content-Type: application/json
X-Klees-Signature: t=1748736000,v1=abc123...
X-Klees-Event: time_entry.flagged_pinshot_low

{
  "event": "time_entry.flagged_pinshot_low",
  "data": { "time_entry_id": "te_01HZ...", "score": 42 },
  "occurred_at": "2026-05-30T14:23:11Z"
}

Verify signatures using the secret shown when you registered the webhook. Klees retries failed deliveries with exponential backoff over 24 hours.

Common integration patterns

Custom payroll handoff — if your provider isn’t on the direct sync list, subscribe to time_entry.approved, fetch the detail, map to your provider’s schema, push. Shifts the heavy lift to the webhook side and stays close to real-time.

BI warehouse sync — nightly call /v1/time-entries, /v1/jobs, /v1/customers, and /v1/audit-log for the previous day; land in raw tables. Most customers use Fivetran or Airbyte against the REST API.

Custom Live Map embed — the /v1/positions/live endpoint streams worker positions with the same 60-second delay as the Live Map UI. Enterprise only.

Status, SDKs

API status and incident postmortems live at https://status.klees.app. Official SDKs: Node.js (@klees/sdk-node), Python (klees-sdk), Ruby (klees). Community SDKs for Go, PHP, and .NET are listed in the API portal. All SDKs handle auth, retries, and pagination cursors.