Clockify-ts is an unofficial wrapper for the clockify API written in TypeScript. By using Clockify's REST-based API, you can push and pull data to and from Clockify, and integrate it with other systems.
You can install this package using NPM!
$ npm install clockify-ts
And import the package using require/import syntax.
import Clockify from "clockify-ts";
// Alternatively
const Clockify = require("clockify-ts").default;
Note: To use the "import"-syntax, you must use a bundler like Webpack, Parel or Vite that can handle ECMAScript modules (ESM).
All communication with the Clockify API needs to be authenticated using a Auth-Token. This token can be generated in the User Settings page and needs to be passed to the clockify instance.
If your workspace is on a subdomain (eg. something.clockify.me), you'll need to generate a new API key in your Profile Settings that will work just for that workspace.
If you're a self-hosted user, you'll have to use a different API base endpoint: "https://yourcustomdomain.com/api" and "https://yourdomain.com/reports" (you can find exact endpoints when you go to "https://youdomain.com/web/boot").
import Clockify from "clockify-ts";
const clockifyApiKey = "YOUR-API-KEY";
const clockify = new Clockify("clockifyApiKey");
Clockify-ts wrapps all base API Endpoints from clockify. This is best illustrated using an example:
import Clockify from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
// Endpoint: GET /workspaces/{workspaceId}/projects
const projects = await clockify.workspace.withId("workspaceId").projects.get();
There are type definitions available for all return values and all possible query objects. The type definitions can be imported directly from the clockify-ts package:
import Clockify from "clockify-ts";
import type { ProjectType } from "clockify-ts";
const project: ProjectType = {
id: "xxx"
}
The following clockify API features are already well implemented and tested.
- Client ✔️
- Project ✔️
- Tag ✔️
- Task ✔️
- Time Entry ✔️
- User ✔️
- Group: ❌
- Workspace ✔️
- Custom Fields ✔️
- Detailed Reports: ✔️
- Summary Reports: ✔️
- Weekly Reports: ❌
- Shared Reports: ❌
import Clockify from "clockify-ts";
import type { ClientType } from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
const clients: ClientType[] = await clockify.workspace.withId("workspaceId").clients.get();
Or with a more complex query:
import Clockify, { ClientsQuery } from "clockify-ts";
import type { ClientType } from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
const query: ClientsQuery = {
name: "Project Name",
page: 1,
}
const clients: ClientType[] = await clockify.workspace.withId("workspaceId").clients.get(query);
import Clockify from "clockify-ts";
import type { ClientType } from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
const client: ClientType = await clockify.workspace.withId("workspaceId").clients.post({ name: "name" });
const clockify = new Clockify("clockifyApiKey");
const updatedClient = await clockify.workspace.withId("workspaceId").clients.withId("clientId").put(client)
const clockify = new Clockify("clockifyApiKey");
const deleted_client = await clockify.workspace.withId("workspaceId").clients.withId("clientId").delete();
const clockify = new Clockify("clockifyApiKey");
const projects = await clockify.workspace.withId("workspaceId").projects.get();
const clockify = new Clockify("clockifyApiKey");
const project = await clockify.workspace.withId("workspaceId").projects.withId("projectId").get();
const clockify = new Clockify("clockifyApiKey");
const project = await clockify.workspace.withId("workspaceId").projects.post({ name });
const clockify = new Clockify("clockifyApiKey");
const updatedProject = await clockify.workspace.withId("workspaceId").projects.withId("projectId").put( project )
const clockify = new Clockify("clockifyApiKey");
const updatedProject = await clockify.workspace.withId("workspaceId").projects.withId("projectId").estimate.patch(projectEstimate)
const clockify = new Clockify("clockifyApiKey");
const project = await clockify.workspace.withId("workspaceId").projects.withId("projectId").memberships.patch(membership);
const clockify = new Clockify("clockifyApiKey");
const projectNoTemplate = await clockify.workspace.withId("workspaceId").projects.withId("projectId").template.patch({
isTemplate: false,
});
const clockify = new Clockify("clockifyApiKey");
const deletedProject = await clockify.workspace.withId("workspaceId").projects.withId("archivedProjectId").delete();
const clockify = new Clockify("clockifyApiKey");
const tags = await clockify.workspace.withId("workspaceId").tags.get();
const clockify = new Clockify("clockifyApiKey");
const createdTag = await clockify.workspace.withId("workspaceId").tags.post({ name });
const clockify = new Clockify("clockifyApiKey");
const updatedTag = await clockify.workspace.withId("workspaceId").tags.withId("tagId").put({ name });
const clockify = new Clockify("clockifyApiKey");
const deletedTag = await clockify.workspace.withId("workspaceId").tags.withId("tagId").delete();
const clockify = new Clockify("clockifyApiKey");
const tasks = await clockify.workspace.withId("workspaceId").projects.withId("projectId").tasks.get();
const clockify = new Clockify("clockifyApiKey");
const task = await clockify.workspace.withId("workspaceId").projects.withId("projectId").tasks.withId("taskId").get();
const clockify = new Clockify("clockifyApiKey");
const createdTask = await clockify.workspace.withId("workspaceId").projects.withId("projectId").tasks.post(task);
const clockify = new Clockify("clockifyApiKey");
const updatedTask = await clockify.workspace.withId("workspaceId").projects.withId("projectId").tasks.withId("taskId").put(task);
const clockify = new Clockify("clockifyApiKey");
const deletedTask = await clockify.workspace.withId("workspaceId").projects.withId("projectId").tasks.withId("taskId").delete();
const clockify = new Clockify("clockifyApiKey");
const timeEntries = await clockify.workspace.withId("workspaceId").users.withId("userId").timeEntries.get();
const clockify = new Clockify("clockifyApiKey");
const timeEntry = await clockify.workspace.withId("workspaceId").timeEntries.withId("timeEntryId").get();
const clockify = new Clockify("clockifyApiKey");
const createdTimeEntry = await clockify.workspace.withId("workspaceId").timeEntries.post(timeEntry);
const clockify = new Clockify("clockifyApiKey");
const createdTimeEntry = await clockify.workspace.withId("workspaceId").users.withId("userId").timeEntries.post(timeEntry);
const clockify = new Clockify("clockifyApiKey");
const updatedTimeEntry = await clockify.workspace.withId("workspaceId").users.withId("userId").timeEntries.patch({ end: new Date() });
const clockify = new Clockify("clockifyApiKey");
const updatedTimeEntry = await clockify.workspace.withId("workspaceId").timeEntries.withId("timeEntryId").put(updatedTimeEntry);
const clockify = new Clockify("clockifyApiKey");
const updatedTimeEntry = await clockify.workspace.withId("workspaceId").timeEntries.invoiced.patch(invoiced);
const clockify = new Clockify("clockifyApiKey");
await clockify.workspace.withId("workspaceId").timeEntries.withId("timeEntryId").delete();
const clockify = new Clockify("clockifyApiKey");
const user = await clockify.user.get();
const clockify = new Clockify("clockifyApiKey");
const members = await clockify.workspace.withId("workspaceId").users.get();
const clockify = new Clockify("clockifyApiKey");
const member = await clockify.workspace.withId("workspaceId").users.post({
email: "[email protected]"
})
const clockify = new Clockify("clockifyApiKey");
const inactiveUser = await clockify.workspace.withId("workspaceId").users.withId("userId").put({
membershipStatus: UserStatusEnum.inactive,
})
const clockify = new Clockify("clockifyApiKey");
const removedUser = await clockify.workspace.withId("workspaceId").users.withId("userId").delete();
const clockify = new Clockify("clockifyApiKey");
const workspaces = await clockify.workspace.get();
import type { RequestSummaryReportType } from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
const summaryQuery: RequestSummaryReportType = {
dateRangeStart: new Date(1577836800000), // Jan. 2020
dateRangeEnd: new Date(1609459199000), // Jan. 2021
summaryFilter: {
groups: [RequestSummaryReportGroupsEnum.project],
}
}
const report = await clockify.workspaces.withId(testWorkspaceId).reports.summary.post(summaryQuery);
import type { RequestDetailedReportType } from "clockify-ts";
const clockify = new Clockify("clockifyApiKey");
const detailedQuery: RequestDetailedReportType = {
dateRangeStart: new Date(1577836800000), // Jan. 2020
dateRangeEnd: new Date(1609459199000), // Jan. 2021
detailedFilter: {}
}
const report = await clockify.workspaces.withId(testWorkspaceId).reports.detailed.post(detailedQuery);
Here you find an exhaustive list of all Types, Queries and Enums you can import form "clockify-ts".
- ClientType
- CustomFieldType
- EntityType
- EstimateType
- MembershipType
- MemberType
- NewClientType
- NewProjectType
- NewTaskType
- NewTimeEntryType
- NewUserType
- ProjectType
- RoleType
- TagType
- TaskType
- TimeEntryType
- UpdateClientType
- UpdateProjectType
- UserGroupType
- UserType
- WorkspaceType
- RequestDetailedReportType
- RequestSummaryReportType
- ClientsQuery
- CustomFieldsQuery
- ProjectsQuery
- Query
- TagsQuery
- TasksQuery
- TimeEntriesQuery
- TimeEntryQuery
- UpdateClientQuery
- UpdateProjectQuery
- UserGroupQuery
- UsersQuery
- CustomFieldTypeEnum,
- CustomFieldStatusEnum,
- CustomFieldProjectDefaultValuesStatusEnum,
- TimeEstimateTypeEnum,
- BudgetEstimateTypeEnum,
- TimeEstimateResetOptionEnum,
- BudgetEstimateResetOptionEnum,
- MembershipStatusEnum,
- MembershipTypeEnum,
- TaskStatusEnum,
- RoleEnum,
- CustomFieldQueryStatusEnum,
- QuerySortOrderEnum,
- ProjectsQueryClientStatusEnum,
- ProjectsQueryUserStatusEnum,
- UpdateProjectQueryEstimateTypeEnum,
- UserQueryMembershipsEnum,
- UserQueryStatusEnum,
- RequestDetailedReportGroupsEnum
- RequestDetailedReportTotalOptionEnum
- RequestDetailedReportSortOrderEnum
- RequestDetailedReportInvoicingStateEnum
- RequestDetailedReportApprovalStateEnum
- RequestDetailedReportSortColumnEnum
- RequestDetailedReportAmountShownEnum
- RequestDetailedReportExportTypeEnum
- RequestDetailedReportContainsFilterEnum
- RequestDetailedReportContainedInTimeEntryFilterEnum
- RequestDetailedReportProjectStatusFilterEnum
- RequestDetailedReportClientStatusFilterEnum
- RequestDetailedReportTagStatusFilterEnum
- RequestDetailedReportUserStatusFilterEnum
- RequestDetailedReportTaskStatusFilterEnum
- RequestSummaryReportGroupsEnum
- RequestSummaryReportSortOrderEnum
- RequestSummaryReportInvoicingStateEnum
- RequestSummaryReportApprovalStateEnum
- RequestSummaryReportSortColumnEnum
- RequestSummaryReportAmountShownEnum
- RequestSummaryReportExportTypeEnum
- RequestSummaryReportContainsFilterEnum
- RequestSummaryReportContainedInTimeEntryFilterEnum
- RequestSummaryReportProjectStatusFilterEnum
- RequestSummaryReportClientStatusFilterEnum
- RequestSummaryReportTagStatusFilterEnum
- RequestSummaryReportUserStatusFilterEnum
- RequestSummaryReportTaskStatusFilterEnum