Summary and recommendation
Clockify's REST API (base URL: https://api.clockify.me/api/v1) authenticates exclusively via API key passed as the X-Api-Key request header - Bearer token auth is not supported. The API key is user-scoped, so all admin-level operations (listing workspace users, updating roles, deactivating members) require the key of an ADMIN or OWNER account.
There are no OAuth scopes; permission boundaries are determined entirely by the role of the key-owning account.
The API enforces a hard rate limit of 10 requests per second per API key. No rate-limit headers are returned in responses, so 429 handling must be implemented client-side with exponential backoff. Pagination is offset-based using ?page (1-indexed) and ?page-size (default 50, max 5000).
SCIM is not available at any plan tier. All programmatic provisioning must go through the REST endpoints. This API surface is the primary integration point for identity graph construction and lifecycle automation against Clockify workspaces.
API quick reference
| Has user API | Yes |
| Auth method | API Key (header: X-Api-Key) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: API Key (header: X-Api-Key)
Setup steps
- Log in to Clockify and navigate to Profile Settings.
- Scroll to the API section and click 'Generate' to create an API key.
- Copy the generated key.
- Include the key in all API requests as the HTTP header: X-Api-Key:
.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique user identifier | system-generated | immutable | Used as userId in all user-scoped endpoints |
| string | User's email address | required | not updatable via API | Used as the invite target | |
| name | string | Display name of the user | optional | read-only via workspace API | Set by the user in their profile |
| status | string | Workspace membership status: ACTIVE, PENDING_EMAIL_VERIFICATION, DECLINED | system-set | can be set to INACTIVE to deactivate | INACTIVE removes workspace access |
| role | string | Workspace role: OWNER, ADMIN, MANAGER, USER | defaults to USER | updatable | MANAGER role requires Pro plan or higher |
| memberships | array | List of workspace/project memberships with roles | auto-assigned to workspace | managed via membership endpoints | Each entry contains membershipType, membershipStatus, targetId |
| profilePicture | string | URL to user's profile picture | null | read-only via API | Set by user only |
| activeWorkspace | string | ID of the user's currently active workspace | system-set | read-only | |
| defaultWorkspace | string | ID of the user's default workspace | system-set | read-only | |
| settings | object | User preferences: weekStart, timeZone, timeFormat, dateFormat, sendNewsletter, etc. | defaults applied | updatable via PUT /users/{userId}/settings | Timezone must be a valid IANA timezone string |
| hourlyRate | object | User's hourly rate {amount, currency} | optional | updatable | Requires Pro plan or higher to set per-user rates |
| costRate | object | User's cost rate {amount, currency} | optional | updatable | Enterprise feature |
| customFields | array | Custom field values assigned to the user | optional | updatable | Custom fields must be pre-configured in workspace settings |
Core endpoints
Get current user (self)
- Method: GET
- URL:
https://api.clockify.me/api/v1/user - Watch out for: Returns the user associated with the API key used. Cannot retrieve another user's data via this endpoint.
Request example
GET /api/v1/user
X-Api-Key: <api_key>
Response example
{
"id": "5a0ab5acb07987125438b60f",
"name": "John Doe",
"email": "john@example.com",
"activeWorkspace": "5a0ab5acb07987125438b60e",
"status": "ACTIVE"
}
List workspace users
- Method: GET
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/users - Watch out for: Only ADMIN or OWNER API keys can list all workspace users. Supports filtering by ?status=ACTIVE|INACTIVE|PENDING_EMAIL_VERIFICATION and ?name= for search.
Request example
GET /api/v1/workspaces/{workspaceId}/users?page=1&page-size=50
X-Api-Key: <api_key>
Response example
[
{
"id": "5a0ab5acb07987125438b60f",
"name": "John Doe",
"email": "john@example.com",
"status": "ACTIVE",
"role": "USER"
}
]
Invite user to workspace
- Method: POST
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/users - Watch out for: Sends an email invitation. User status remains PENDING until they accept. If the user already has a Clockify account, they are added directly.
Request example
POST /api/v1/workspaces/{workspaceId}/users
X-Api-Key: <api_key>
Content-Type: application/json
{"email": "newuser@example.com"}
Response example
{
"id": "5b1bc6bdb07987125438c71a",
"email": "newuser@example.com",
"status": "PENDING_EMAIL_VERIFICATION"
}
Update workspace user (role/status)
- Method: PUT
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/users/{userId} - Watch out for: Setting membershipStatus to INACTIVE deactivates the user in the workspace but does not delete their account or time entries.
Request example
PUT /api/v1/workspaces/{workspaceId}/users/{userId}
X-Api-Key: <api_key>
Content-Type: application/json
{"membershipStatus": "INACTIVE"}
Response example
{
"id": "5a0ab5acb07987125438b60f",
"status": "INACTIVE",
"role": "USER"
}
Remove user from workspace
- Method: DELETE
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/users/{userId} - Watch out for: Removes the user from the workspace. Their historical time entries are retained. Cannot remove the workspace OWNER.
Request example
DELETE /api/v1/workspaces/{workspaceId}/users/{userId}
X-Api-Key: <api_key>
Response example
HTTP 200 OK
{}
Get workspace user by ID
- Method: GET
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/users/{userId} - Watch out for: Requires ADMIN or OWNER API key. Returns workspace-scoped user data, not global profile.
Request example
GET /api/v1/workspaces/{workspaceId}/users/{userId}
X-Api-Key: <api_key>
Response example
{
"id": "5a0ab5acb07987125438b60f",
"name": "John Doe",
"email": "john@example.com",
"role": "ADMIN",
"status": "ACTIVE"
}
Update user settings
- Method: PUT
- URL:
https://api.clockify.me/api/v1/users/{userId}/settings - Watch out for: Can only update settings for the user whose API key is used, or an ADMIN updating another user. Full object replacement - omitted fields revert to defaults.
Request example
PUT /api/v1/users/{userId}/settings
X-Api-Key: <api_key>
Content-Type: application/json
{"timeZone": "America/New_York", "weekStart": "MONDAY"}
Response example
{
"weekStart": "MONDAY",
"timeZone": "America/New_York",
"timeFormat": "HOUR12"
}
List workspace user groups
- Method: GET
- URL:
https://api.clockify.me/api/v1/workspaces/{workspaceId}/user-groups - Watch out for: User groups are available on Pro plan and above. Returns empty array on lower plans without error.
Request example
GET /api/v1/workspaces/{workspaceId}/user-groups
X-Api-Key: <api_key>
Response example
[
{
"id": "5c3de6bdb07987125438d82b",
"name": "Engineering",
"userIds": ["5a0ab5acb07987125438b60f"]
}
]
Rate limits, pagination, and events
- Rate limits: Clockify enforces rate limits per API key. The documented limit is 10 requests per second per API key.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: Exceeding the rate limit returns HTTP 429. No official documentation of rate-limit response headers. Implement exponential backoff on 429 responses.
- Pagination method: offset
- Default page size: 50
- Max page size: 5000
- Pagination pointer: page and page-size
| Plan | Limit | Concurrent |
|---|---|---|
| All plans | 10 requests/second per API key | 0 |
- Webhooks available: Yes
- Webhook notes: Clockify supports webhooks configured per workspace. Webhooks send HTTP POST payloads to a configured URL when specified events occur.
- Alternative event strategy: Poll GET /workspaces/{workspaceId}/users with ?updatedAfter= parameter for user change detection if webhooks are not suitable.
- Webhook events: NEW_TIME_ENTRY, TIME_ENTRY_UPDATED, TIME_ENTRY_DELETED, NEW_PROJECT, PROJECT_UPDATED, NEW_CLIENT, NEW_TASK, NEW_USER_WORKSPACE, USER_DELETED_FROM_WORKSPACE, TIMER_STARTED, TIMER_STOPPED
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- SCIM provisioning is not documented or officially supported by Clockify as of the policy date.
- SSO (SAML 2.0) is available on Enterprise plan but does not include SCIM.
- User provisioning must be done via the REST API or manual invitation.
Common scenarios
Onboarding: retrieve workspaceId via GET /api/v1/workspaces, then POST /api/v1/workspaces/{workspaceId}/users with the invitee's email. If the user already holds a Clockify account, they are added immediately with ACTIVE status - skip polling.
If not, poll GET /workspaces/{workspaceId}/users? email= until status transitions from PENDING_EMAIL_VERIFICATION to ACTIVE before issuing a role update via PUT /workspaces/{workspaceId}/users/{userId}.
Deactivation: locate userId via GET /workspaces/{workspaceId}/users?name=, then PUT /workspaces/{workspaceId}/users/{userId} with {"membershipStatus": "INACTIVE"}. This revokes workspace access immediately but preserves all historical time entries. Use DELETE /workspaces/{workspaceId}/users/{userId} only when full workspace removal is required - the OWNER cannot be removed via this endpoint.
Bulk audit: GET /workspaces/{workspaceId}/users?status=ACTIVE&page=1&page-size=5000 returns up to 5,000 users per call. If the response length equals page-size, increment page and repeat. Map id, email, name, role, and memberships fields for identity graph output. At 10 req/sec, large workspaces requiring multiple pages will hit the rate limit quickly - implement backoff accordingly.
Webhooks: NEW_USER_WORKSPACE and USER_DELETED_FROM_WORKSPACE events enable event-driven identity graph updates without polling. Configure per workspace via the Clockify UI. If webhooks are not viable, use GET /workspaces/{workspaceId}/users?updatedAfter= as a polling fallback.
Onboard a new employee to a workspace
- GET /api/v1/workspaces to retrieve the target workspaceId.
- POST /api/v1/workspaces/{workspaceId}/users with body {"email": "newuser@example.com"} to invite the user.
- Poll GET /api/v1/workspaces/{workspaceId}/users?email=newuser@example.com until status transitions from PENDING_EMAIL_VERIFICATION to ACTIVE.
- PUT /api/v1/workspaces/{workspaceId}/users/{userId} to assign the appropriate role (e.g., MANAGER) if needed.
- Optionally POST /api/v1/workspaces/{workspaceId}/user-groups/{groupId}/users/{userId} to add to a user group (Pro+ plan).
Watch out for: If the user already has a Clockify account, they are added immediately (no email step). Check status immediately after invite POST.
Deactivate a departing employee
- GET /api/v1/workspaces/{workspaceId}/users?name=
to locate the userId. - PUT /api/v1/workspaces/{workspaceId}/users/{userId} with body {"membershipStatus": "INACTIVE"} to revoke workspace access.
- Verify deactivation by confirming status is INACTIVE in the response.
Watch out for: INACTIVE status blocks login to the workspace but does not delete the user account or their time entries. Use DELETE endpoint only if full removal is required.
Bulk list and audit all active workspace users
- GET /api/v1/workspaces to retrieve workspaceId.
- GET /api/v1/workspaces/{workspaceId}/users?status=ACTIVE&page=1&page-size=5000 to retrieve all active users in one call (if under 5000).
- If response length equals page-size, increment page and repeat until a partial page is returned.
- Map each user object's id, email, name, role, and memberships fields for audit output.
Watch out for: Max page-size is 5000. For workspaces with more than 5000 users, multiple paginated requests are required. Rate limit of 10 req/sec applies.
Why building this yourself is a trap
The most common integration failure is key-role mismatch: using a Regular User or Project Manager API key for workspace-level operations returns empty results or silent failures rather than explicit 403 errors on some endpoints - always provision a dedicated ADMIN-owned service key.
A second frequent trap is the PUT /users/{userId}/settings endpoint, which performs full object replacement; omitting any field reverts it to the platform default, which can silently overwrite user timezone or date format preferences set outside the integration.
User groups (required for team-scoped access patterns) are only available on Pro plan and above. API calls to group endpoints succeed on lower plans but return empty arrays without error, making plan-gating invisible at the API layer - validate plan tier before building group-dependent workflows.
For identity graph integrity, note that membershipStatus INACTIVE and workspace deletion via DELETE are distinct states with different data retention implications. Inactive users remain in the identity graph with preserved time entry history; deleted users lose workspace association but their Clockify account persists.
Model these as separate lifecycle states to avoid false negatives in access audits.
Automate Clockify workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.