Install
openclaw skills install clockifyClockify API integration with managed OAuth. Track time, manage projects, clients, tasks, and workspaces. Use this skill when users want to track time, create or manage projects, view time entries, or manage workspace members. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
openclaw skills install clockifyAccess the Clockify API with managed OAuth authentication. Track time, manage projects, clients, tasks, tags, and workspaces.
# Get current user
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/clockify/api/v1/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/clockify/{native-api-path}
Maton proxies requests to api.clockify.me and automatically injects your credentials.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Clockify OAuth connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=clockify&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'clockify'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-13T09:18:02.529448Z",
"last_updated_time": "2026-02-13T09:18:09.334540Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "clockify",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Clockify connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/clockify/api/v1/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
GET /clockify/api/v1/user
Response:
{
"id": "698eeb9f5cd3a921db12069f",
"email": "user@example.com",
"name": "John Doe",
"activeWorkspace": "698eeb9e5cd3a921db120693",
"defaultWorkspace": "698eeb9e5cd3a921db120693",
"status": "ACTIVE"
}
GET /clockify/api/v1/workspaces
GET /clockify/api/v1/workspaces/{workspaceId}
POST /clockify/api/v1/workspaces
Content-Type: application/json
{
"name": "My Workspace"
}
GET /clockify/api/v1/workspaces/{workspaceId}/users
GET /clockify/api/v1/workspaces/{workspaceId}/projects
GET /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}
POST /clockify/api/v1/workspaces/{workspaceId}/projects
Content-Type: application/json
{
"name": "My Project",
"isPublic": true,
"clientId": "optional-client-id"
}
Response:
{
"id": "698f7cba4f748f6209ea8995",
"name": "My Project",
"clientId": "",
"workspaceId": "698eeb9e5cd3a921db120693",
"billable": true,
"color": "#1976D2",
"archived": false,
"public": true
}
PUT /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}
Content-Type: application/json
{
"name": "Updated Project Name",
"archived": true
}
DELETE /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}
Note: You cannot delete active projects. Set archived: true first.
GET /clockify/api/v1/workspaces/{workspaceId}/clients
GET /clockify/api/v1/workspaces/{workspaceId}/clients/{clientId}
POST /clockify/api/v1/workspaces/{workspaceId}/clients
Content-Type: application/json
{
"name": "Acme Corp",
"address": "123 Main St",
"note": "Important client"
}
Response:
{
"id": "698f7cba0705b7d880830262",
"name": "Acme Corp",
"workspaceId": "698eeb9e5cd3a921db120693",
"archived": false,
"address": "123 Main St",
"note": "Important client"
}
PUT /clockify/api/v1/workspaces/{workspaceId}/clients/{clientId}
Content-Type: application/json
{
"name": "Acme Corporation"
}
DELETE /clockify/api/v1/workspaces/{workspaceId}/clients/{clientId}
GET /clockify/api/v1/workspaces/{workspaceId}/tags
GET /clockify/api/v1/workspaces/{workspaceId}/tags/{tagId}
POST /clockify/api/v1/workspaces/{workspaceId}/tags
Content-Type: application/json
{
"name": "urgent"
}
Response:
{
"id": "698f7cbbaa9e9f33e5fc0126",
"name": "urgent",
"workspaceId": "698eeb9e5cd3a921db120693",
"archived": false
}
PUT /clockify/api/v1/workspaces/{workspaceId}/tags/{tagId}
Content-Type: application/json
{
"name": "high-priority"
}
DELETE /clockify/api/v1/workspaces/{workspaceId}/tags/{tagId}
GET /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}/tasks
GET /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{taskId}
POST /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}/tasks
Content-Type: application/json
{
"name": "Implement feature",
"assigneeIds": ["user-id-1"],
"estimate": "PT2H",
"billable": true
}
Response:
{
"id": "698f7cc4aa9e9f33e5fc017b",
"name": "Implement feature",
"projectId": "698f7cba4f748f6209ea8995",
"assigneeIds": [],
"estimate": "PT0S",
"status": "ACTIVE",
"billable": true
}
PUT /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{taskId}
Content-Type: application/json
{
"name": "Updated task name",
"status": "DONE"
}
DELETE /clockify/api/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{taskId}
Note: You cannot delete active tasks. Set status: "DONE" first.
GET /clockify/api/v1/workspaces/{workspaceId}/user/{userId}/time-entries
Response:
[
{
"id": "698f7cc4aa9e9f33e5fc0180",
"description": "Working on project",
"userId": "698eeb9f5cd3a921db12069f",
"billable": true,
"projectId": "698f7cba4f748f6209ea8995",
"taskId": null,
"workspaceId": "698eeb9e5cd3a921db120693",
"timeInterval": {
"start": "2026-02-13T18:34:28Z",
"end": "2026-02-13T19:34:28Z",
"duration": "PT1H"
}
}
]
POST /clockify/api/v1/workspaces/{workspaceId}/time-entries
Content-Type: application/json
{
"start": "2026-02-13T09:00:00Z",
"end": "2026-02-13T10:00:00Z",
"description": "Team meeting",
"projectId": "project-id",
"taskId": "task-id",
"tagIds": ["tag-id-1", "tag-id-2"],
"billable": true
}
POST /clockify/api/v1/workspaces/{workspaceId}/user/{userId}/time-entries
Content-Type: application/json
{
"start": "2026-02-13T09:00:00Z",
"end": "2026-02-13T10:00:00Z",
"description": "Team meeting"
}
GET /clockify/api/v1/workspaces/{workspaceId}/time-entries/{timeEntryId}
PUT /clockify/api/v1/workspaces/{workspaceId}/time-entries/{timeEntryId}
Content-Type: application/json
{
"start": "2026-02-13T09:00:00Z",
"end": "2026-02-13T11:00:00Z",
"description": "Extended meeting"
}
DELETE /clockify/api/v1/workspaces/{workspaceId}/time-entries/{timeEntryId}
PATCH /clockify/api/v1/workspaces/{workspaceId}/user/{userId}/time-entries
Content-Type: application/json
{
"end": "2026-02-13T17:00:00Z"
}
GET /clockify/api/v1/workspaces/{workspaceId}/time-entries
Clockify uses page-based pagination:
GET /clockify/api/v1/workspaces/{workspaceId}/projects?page=1&page-size=50
Query Parameters:
page - Page number (1-indexed, default: 1)page-size - Items per page (default varies by endpoint)Response includes a Last-Page header indicating if there are more pages.
const response = await fetch(
'https://api.maton.ai/clockify/api/v1/workspaces',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const workspaces = await response.json();
import os
import requests
response = requests.get(
'https://api.maton.ai/clockify/api/v1/workspaces',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
workspaces = response.json()
import os
import requests
from datetime import datetime, timedelta, timezone
workspace_id = "your-workspace-id"
start_time = (datetime.now(timezone.utc) - timedelta(hours=1)).isoformat().replace('+00:00', 'Z')
end_time = datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z')
response = requests.post(
f'https://api.maton.ai/clockify/api/v1/workspaces/{workspace_id}/time-entries',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'start': start_time,
'end': end_time,
'description': 'Working on feature'
}
)
2026-02-13T09:00:00Z)PT1H for 1 hour, PT30M for 30 minutes)curl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing Clockify connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions |
| 404 | Resource not found |
| 429 | Rate limited (50 req/sec per workspace) |
| 4xx/5xx | Passthrough error from Clockify API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
clockify. For example:https://api.maton.ai/clockify/api/v1/userhttps://api.maton.ai/api/v1/user