https://github.com/kendew-agency/clickup-sdk
Node.js library for the ClickUp API
https://github.com/kendew-agency/clickup-sdk
clickup-api clickup-sdk typescript
Last synced: 4 months ago
JSON representation
Node.js library for the ClickUp API
- Host: GitHub
- URL: https://github.com/kendew-agency/clickup-sdk
- Owner: Kendew-Agency
- License: mit
- Created: 2026-02-16T21:30:24.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-17T15:51:18.000Z (4 months ago)
- Last Synced: 2026-02-17T19:04:07.149Z (4 months ago)
- Topics: clickup-api, clickup-sdk, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@kendew-agency/clickup-sdk
- Size: 65.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
Awesome Lists containing this project
README
# @kendew-agency/clickup-sdk
A type-safe Node.js SDK for the ClickUp API, built with TypeScript.
> **⚠️ Work in Progress**: This SDK is under active development. Not all ClickUp API methods are implemented yet. Check the [API Methods](#api-methods) section below for currently available endpoints. Some endpoints may also miss some functions.
> **📝 Note on ClickUp API**: The actual data returned by ClickUp's API may sometimes differ from their official documentation. We strive to keep our types accurate based on real-world API responses, but discrepancies may occur. Please report any type mismatches you encounter.
## Installation
```bash
npm install @kendew-agency/clickup-sdk
```
```bash
pnpm add @kendew-agency/clickup-sdk
```
```bash
yarn add @kendew-agency/clickup-sdk
```
## Quick Start
```typescript
import { ClickUp } from "@kendew-agency/clickup-sdk";
const clickup = new ClickUp({
apiToken: "your_api_token_here",
});
// Get authorized user
const user = await clickup.authorization.getAuthorizedUser();
// Get tasks from a list
const tasks = await clickup.tasks.getTasks("list_id");
// Create a task
const newTask = await clickup.tasks.createTask("list_id", {
name: "My new task",
description: "Task description",
});
```
## Authentication
The SDK supports two authentication methods:
### Personal API Token
Generate a personal API token from your ClickUp settings:
```typescript
const clickup = new ClickUp({
apiToken: "pk_your_personal_token",
});
```
### OAuth Token
Use OAuth for user-specific access:
```typescript
// Exchange authorization code for access token
const tokenResponse = await clickup.authorization.getAccessToken({
client_id: "your_client_id",
client_secret: "your_client_secret",
code: "authorization_code",
});
// Create SDK instance with OAuth token
const clickup = new ClickUp({
apiToken: tokenResponse.access_token,
});
```
## Configuration
### Basic Configuration
```typescript
const clickup = new ClickUp({
apiToken: "your_token",
});
```
### Custom Headers
Add custom headers to all requests (useful for Next.js tags, etc.):
```typescript
const clickup = new ClickUp({
apiToken: "your_token",
headers: {
"X-Custom-Header": "value",
},
});
```
### Configuration Override
Create a new instance with modified configuration:
```typescript
const clickupWithCustomHeaders = clickup.withConfig({
headers: {
"X-Request-ID": "unique-id",
},
});
```
## API Methods
### Currently Implemented
The following API endpoints are currently implemented in this SDK:
- **Authorization**: OAuth token exchange, get authorized user
- **Tasks**: Get, create, update, delete tasks, manage dependencies and links
- **Comments**: Task, list, and chat view comments with threading support
- **Attachments**: Upload task attachments
- **Custom Task Types**: Get workspace custom task types
- **Spaces**: Get, create, update, delete spaces
- **Folders**: Get, create, update, delete folders
- **Lists**: Get, create, update, delete lists
- **Goals**: Get, create, update, delete goals
- **Tags**: Get, create, update, delete tags, manage task tags
- **Custom Fields**: Get accessible fields, set and remove values
Additional ClickUp API endpoints will be added in future releases. Contributions are welcome!
### Authorization
```typescript
// Get access token via OAuth
const token = await clickup.authorization.getAccessToken({
client_id: "your_client_id",
client_secret: "your_client_secret",
code: "authorization_code",
});
// Get authorized user information
const user = await clickup.authorization.getAuthorizedUser();
```
### Tasks
```typescript
// Get tasks from a list
const tasks = await clickup.tasks.getTasks("list_id", {
page: 0,
order_by: "created",
reverse: true,
subtasks: true,
include_closed: false,
});
// Get a single task
const task = await clickup.tasks.getTask("task_id");
// Create a task
const newTask = await clickup.tasks.createTask("list_id", {
name: "Task name",
description: "Task description",
assignees: [123],
tags: ["tag1"],
status: "Open",
priority: 3,
due_date: 1508369194377,
notify_all: true,
});
// Update a task
const updated = await clickup.tasks.updateTask("task_id", {
name: "Updated name",
status: "In Progress",
priority: 2,
});
// Delete a task
await clickup.tasks.deleteTask("task_id");
// Add task dependency
await clickup.tasks.addDependency("task_id", {
depends_on: "other_task_id",
});
// Delete task dependency
await clickup.tasks.deleteDependency("task_id", {
depends_on: "other_task_id",
});
// Add task link
await clickup.tasks.addTaskLink("task_id", {
links_to: "other_task_id",
});
// Delete task link
await clickup.tasks.deleteTaskLink("task_id", {
links_to: "other_task_id",
});
```
### Comments
```typescript
// Get task comments (paginated, max 25 per request)
const comments = await clickup.comments.getTaskComments("task_id", {
start: 0,
});
// Create task comment
const comment = await clickup.comments.createTaskComment("task_id", {
comment_text: "This is a comment",
notify_all: true,
});
// Update comment
await clickup.comments.updateComment("comment_id", {
comment_text: "Updated comment",
});
// Delete comment
await clickup.comments.deleteComment("comment_id");
// Get threaded comments
const replies = await clickup.comments.getThreadedComments("comment_id");
// Create threaded comment
await clickup.comments.createThreadedComment("comment_id", {
comment_text: "Reply to comment",
});
// Get chat view comments
const chatComments = await clickup.comments.getChatViewComments("view_id", {
start: 0,
});
// Create chat view comment
await clickup.comments.createChatViewComment("view_id", {
comment_text: "Chat message",
});
// Get list comments
const listComments = await clickup.comments.getListComments("list_id", {
start: 0,
});
// Create list comment
await clickup.comments.createListComment("list_id", {
comment_text: "List comment",
});
```
### Attachments
```typescript
// Upload task attachment
const attachment = await clickup.attachments.uploadTaskAttachment(
"task_id",
{
attachment: fileBuffer, // Buffer or File object
filename: "document.pdf",
},
);
```
### Custom Task Types
```typescript
// Get workspace custom task types
const taskTypes = await clickup.customTaskTypes.getCustomTaskTypes(
"workspace_id",
);
```
### Spaces
```typescript
// Get spaces in a workspace
const spaces = await clickup.spaces.getSpaces("workspace_id", {
archived: false,
});
// Get a single space
const space = await clickup.spaces.getSpace("space_id");
// Create a space
const newSpace = await clickup.spaces.createSpace("workspace_id", {
name: "New Space",
multiple_assignees: true,
features: {
due_dates: { enabled: true },
time_tracking: { enabled: true },
},
});
// Update a space
await clickup.spaces.updateSpace("space_id", {
name: "Updated Space",
});
// Delete a space
await clickup.spaces.deleteSpace("space_id");
```
### Folders
```typescript
// Get folders in a space
const folders = await clickup.folders.getFolders("space_id", {
archived: false,
});
// Get a single folder
const folder = await clickup.folders.getFolder("folder_id");
// Create a folder
const newFolder = await clickup.folders.createFolder("space_id", {
name: "New Folder",
});
// Update a folder
await clickup.folders.updateFolder("folder_id", {
name: "Updated Folder",
});
// Delete a folder
await clickup.folders.deleteFolder("folder_id");
```
### Lists
```typescript
// Get lists in a folder
const lists = await clickup.lists.getLists("folder_id", {
archived: false,
});
// Get folderless lists in a space
const folderlessLists = await clickup.lists.getFolderlessLists("space_id", {
archived: false,
});
// Get a single list
const list = await clickup.lists.getList("list_id");
// Create a list
const newList = await clickup.lists.createList("folder_id", {
name: "New List",
content: "List description",
priority: 1,
status: "active",
});
// Update a list
await clickup.lists.updateList("list_id", {
name: "Updated List",
});
// Delete a list
await clickup.lists.deleteList("list_id");
```
### Goals
```typescript
// Get goals in a workspace
const goals = await clickup.goals.getGoals(123456);
// Get a single goal
const goal = await clickup.goals.getGoal("goal_id");
// Create a goal
const newGoal = await clickup.goals.createGoal(123456, {
name: "Q1 Goals",
due_date: 1609459200000,
description: "First quarter objectives",
multiple_owners: true,
owners: [123],
color: "#32a852",
});
// Update a goal
await clickup.goals.updateGoal("goal_id", {
name: "Updated Goal",
});
// Delete a goal
await clickup.goals.deleteGoal("goal_id");
```
### Tags
```typescript
// Get tags in a space
const tags = await clickup.tags.getTags("space_id");
// Create a tag
const newTag = await clickup.tags.createTag("space_id", {
name: "urgent",
});
// Update a tag
await clickup.tags.updateTag("space_id", "tag_name", {
name: "high-priority",
});
// Delete a tag
await clickup.tags.deleteTag("space_id", "tag_name");
// Add tag to task
await clickup.tags.addTagToTask("task_id", {
tag_name: "urgent",
});
// Remove tag from task
await clickup.tags.removeTagFromTask("task_id", "tag_name");
```
### Custom Fields
```typescript
// Get accessible custom fields
const customFields = await clickup.customFields.getAccessibleCustomFields(
"list_id",
);
// Set custom field value
await clickup.customFields.setCustomFieldValue("task_id", "field_id", {
value: "custom value",
});
// Remove custom field value
await clickup.customFields.removeCustomFieldValue("task_id", "field_id");
```
## Pagination
Many endpoints support pagination using `start` and `start_id` parameters:
```typescript
// First page
const firstPage = await clickup.comments.getTaskComments("task_id", {
start: 0,
});
// Next page
const nextPage = await clickup.comments.getTaskComments("task_id", {
start: 25,
start_id: firstPage.comments[24].id,
});
```
## Custom Task IDs
ClickUp supports custom task IDs. Enable them in your requests:
```typescript
const task = await clickup.tasks.getTask("CUSTOM-123", {
custom_task_ids: true,
team_id: "your_team_id",
});
```
## Error Handling
The SDK uses a `Response` type that includes error information:
```typescript
const result = await clickup.tasks.getTask("task_id");
if ("err" in result) {
console.error("Error:", result.err);
console.error("Error code:", result.ECODE);
} else {
console.log("Task:", result);
}
```
## TypeScript Support
The SDK is written in TypeScript and provides full type definitions:
```typescript
import type {
CreateTaskParams,
GetTaskResponse,
ClickUpConfig,
} from "@kendew-agency/clickup-sdk";
```
Import types from the `/types` export:
```typescript
import type { User, Pagination } from "@kendew-agency/clickup-sdk/types";
```
## Development
```bash
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with UI
pnpm test:ui
# Run tests with coverage
pnpm test:coverage
# Lint and format
pnpm biome check
# Auto-fix linting and formatting issues
pnpm biome check --write
```
## License
MIT
## Links
- [ClickUp API Documentation](https://developer.clickup.com/docs/)
- [GitHub Repository](https://github.com/Kendew-Agency/clickup-sdk)
- [Issue Tracker](https://github.com/Kendew-Agency/clickup-sdk/issues)
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
### Known Issues
- Not all ClickUp API endpoints are implemented yet
- Some response types may not perfectly match ClickUp's documentation due to discrepancies between documented and actual API responses
- If you encounter type mismatches or missing methods, please open an issue with details about the endpoint and expected vs actual behavior