@yoryoboy/clickup-sdk
v1.4.0
Published
A modular TypeScript SDK for interacting with the ClickUp API
Maintainers
Readme
ClickUp SDK for TypeScript
A modular TypeScript SDK for interacting with the ClickUp API, built with ES modules and object-oriented programming principles.
🧠 Project Overview
This SDK provides a clean, object-oriented interface to the ClickUp API, making it easier to:
- Fetch and manage tasks
- Handle pagination automatically
- Work with ClickUp data in a structured way
📦 Installation
# Clone the repository
git clone https://github.com/yourusername/clickup-sdk.git
# Navigate to the project directory
cd clickup-sdk
# Install dependencies
pnpm install🔑 Authentication
You'll need a ClickUp API key to use this SDK. You can get one from your ClickUp workspace settings.
Create a .env file in the root directory with your API key:
CLICKUP_API_KEY=your_api_key_here🚀 Usage
Importing the SDK
This package ships dual modules: ESM and CommonJS. Use either style:
- ESM/TypeScript
import ClickUp, { Task, TaskManager, TeamManager } from '@yoryoboy/clickup-sdk';- CommonJS
const sdk = require('@yoryoboy/clickup-sdk');
const ClickUp = sdk.default; // default export
const { Task, TaskManager, TeamManager } = sdk; // named exportsBasic Example
import dotenv from 'dotenv';
import ClickUp from '@yoryoboy/clickup-sdk';
// Load environment variables
dotenv.config();
// Initialize the ClickUp client
const clickUp = new ClickUp(process.env.CLICKUP_API_KEY as string);
// Get tasks from a list
const tasks = await clickUp.tasks.getTasks({
list_id: '123456789',
});
console.log(`Found ${tasks.length} tasks`);Pagination
The SDK supports automatic pagination when fetching tasks:
// Get ALL tasks from a list (handles pagination automatically)
const allTasks = await clickUp.tasks.getTasks({
list_id: '123456789',
page: 'all',
include_closed: true,
});
console.log(`Found ${allTasks.length} tasks across all pages`);
// Get only the first page of tasks
const firstPageTasks = await clickUp.tasks.getTasks({
list_id: '123456789',
page: 0,
});Filtering Tasks Across a Workspace
Use getFilteredTasks() to search for tasks across an entire workspace with powerful filtering options:
// Get tasks with specific filters across the workspace
const filteredTasks = await clickUp.tasks.getFilteredTasks({
team_id: '1234567', // Required workspace ID
page: 'all', // Get all pages
statuses: ['in progress', 'review'],
assignees: ['12345'], // User IDs
tags: ['important'],
due_date_gt: Date.now(), // Due date in the future
include_closed: false
});
console.log(`Found ${filteredTasks.length} matching tasks`);Filtering by Custom Fields
The SDK supports advanced filtering using custom fields:
// Filter tasks by custom fields
const tasksWithCustomFields = await clickUp.tasks.getFilteredTasks({
team_id: '1234567',
custom_fields: [
{
field_id: 'abc123def456',
operator: '>',
value: 5
},
{
field_id: 'xyz789',
operator: 'RANGE',
value: [1671246000000, 1671505200000] // Date range
}
]
});Working with Tasks
Each task is returned as a Task instance with helpful methods:
const tasks = await clickUp.tasks.getTasks({ list_id: '123456789' });
// Check if a task is completed
const completedTasks = tasks.filter(task => task.isCompleted());
// Get assignee names for a task
const taskWithAssignees = tasks[0];
const assigneeNames = taskWithAssignees.getAssigneeNames();
console.log(`Task assigned to: ${assigneeNames.join(', ')}`);
// Get simplified task data
const simplifiedTask = tasks[0].reduceInfo();
console.log(simplifiedTask);
// Output: { id: '123', name: 'Task Name', status: 'in progress', ... }Updating Tasks
You can update tasks using the updateTask method:
// Update a task's status and due date
const updatedTask = await clickUp.tasks.updateTask('task123', {
status: 'in progress',
due_date: Date.now() + 7 * 24 * 60 * 60 * 1000, // One week from now
due_date_time: true
});
console.log(`Task updated: ${updatedTask.name} is now ${updatedTask.status.status}`);
// Update a task's name and description
const renamedTask = await clickUp.tasks.updateTask('task456', {
name: 'New task name',
description: 'Updated description with more details'
});Simplified Task Data
The reduceInfo() method provides a simplified view of task data with a flattened structure:
const task = tasks[0];
const info = task.reduceInfo();The simplified object includes:
- Basic task properties (id, name, description, etc.)
- Flattened nested objects (status, creator, etc.)
- Simplified arrays (assignees, watchers as usernames)
- Special handling for dropdown custom fields (shows option names instead of indices)
- Only includes custom fields with defined values
📚 API Reference
ClickUp Class
The main entry point for the SDK.
const clickUp = new ClickUp(apiKey);Properties:
apiKey: Your ClickUp API keyclient: The configured Axios instancetasks: TaskManager instance for task operations
TaskManager Class
Handles all task-related operations.
getTasks(params)
Fetches tasks from a ClickUp list.
Parameters:
params.list_id(required): The ClickUp list IDparams.page: Page number or "all" to fetch all pagesparams.include_closed: Whether to include closed tasksparams.reverse: Whether to reverse the order of tasks- ...other ClickUp API parameters
Returns: Promise<Task[]> - Array of Task instances
getTask(task_id)
Fetches a single task by its ID and returns its reduced information object.
Parameters:
task_id(required): The ID of the task to retrieve
Returns: Promise - Reduced task info
Example:
// Get a single task's reduced info
const taskInfo = await clickUp.tasks.getTask('abc123def456');
console.log(taskInfo.id, taskInfo.name, taskInfo.status);getFilteredTasks(params)
Fetches filtered tasks across an entire workspace.
Parameters:
params.team_id(required): The ClickUp workspace IDparams.page: Page number or "all" to fetch all pagesparams.space_ids: Array of space IDs to filter byparams.project_ids: Array of folder IDs to filter byparams.list_ids: Array of list IDs to filter byparams.statuses: Array of status names to filter byparams.assignees: Array of user IDs to filter byparams.tags: Array of tags to filter byparams.due_date_gt/lt: Filter by due date (Unix timestamp in ms)params.date_created_gt/lt: Filter by creation dateparams.date_updated_gt/lt: Filter by update dateparams.custom_fields: Array of custom field filter objects- ...other ClickUp API parameters
Returns: Promise<Task[]> - Array of Task instances
updateTask(task_id, data)
Updates a task with new values.
Parameters:
task_id(required): The ID of the task to updatedata: Object containing the fields to updatename: New name for the taskdescription: New description for the taskstatus: New status for the taskdue_date: New due date (Unix timestamp in ms)due_date_time: Whether the due date includes a specific timestart_date: New start date (Unix timestamp in ms)time_estimate: Time estimate in millisecondsarchived: Whether the task is archived- ...other ClickUp API task fields
Returns: Promise - The updated Task instance
createTask(list_id, taskData)
Creates a new task in a specific list.
Parameters:
list_id(required): The ID of the list to create the task intaskData: Object containing the task dataname(required): Task namedescription: Task descriptionassignees: Array of assignee user IDstags: Array of tagsstatus: Task statuspriority: Task priority (null, 1, 2, 3, or 4)due_date: Due date (Unix timestamp in ms)start_date: Start date (Unix timestamp in ms)custom_fields: Array of custom field objects- ...other ClickUp API task fields
Returns: Promise - The created Task instance
createTasks(list_id, tasks, options)
Creates multiple tasks with rate limiting to handle ClickUp's API limits.
Parameters:
list_id(required): The ID of the list to create tasks intasks: Single task object or array of task objects (see createTask for object structure)options: Options for batch processingbatchSize: Number of tasks to process per batch (default: 100)delayBetweenBatches: Delay between batches in milliseconds (default: 60000ms = 1 minute)verbose: Whether to log progress to console (default: false)onProgress: Callback function for progress updates
The onProgress callback receives a progress object with the following properties:
- For
type: 'batchStart':batchNumber: Current batch number (1-based)totalBatches: Total number of batchesbatchSize: Number of tasks in the current batchtasksProcessed: Number of tasks processed so fartotalTasks: Total number of tasks to process
- For
type: 'batchComplete':- All of the above, plus:
batchDuration: Time taken to process the batch in milliseconds
- For
type: 'waiting':waitTime: Time to wait before next batch in millisecondsnextBatch: Next batch numbertotalBatches: Total number of batches
- For
type: 'complete':totalTasks: Total number of tasks createdtotalBatches: Total number of batches processed
Returns: Promise<Array> - Array of created Task instances
Example:
// Create a single task
const newTask = await clickUp.tasks.createTask("123456789", {
name: "New Task",
description: "Task description",
status: "to do",
due_date: 1735603200000 // Unix timestamp in ms
});
// Create multiple tasks with batching
const tasksToCreate = [
{ name: "Task 1", status: "to do" },
{ name: "Task 2", status: "in progress" },
// ... more tasks
];
const createdTasks = await clickUp.tasks.createTasks("123456789", tasksToCreate, {
batchSize: 50, // Process 50 tasks at a time
delayBetweenBatches: 65000 // Wait 65 seconds between batches
});uploadAttachment(task_id, attachment, options)
Uploads a file as an attachment to a task.
Parameters:
task_id(required): The ID of the task to attach the file to.attachment(required): The attachment source. Can be a local file path (string), aBuffer, aReadablestream, or aBlob(Node 18+).options(optional): An object with optional properties:filename: A custom name for the attachment.contentType: The MIME type of the file (e.g.,"image/png").
Returns: Promise<any> - The attachment creation response from the ClickUp API.
Example:
// Upload from a local file path
await clickUp.tasks.uploadAttachment(
"task_123",
"./files/report.pdf",
{ filename: "final-report.pdf" }
);
// Upload from a Buffer in memory
const fileContent = Buffer.from("This is a test file.");
await clickUp.tasks.uploadAttachment(
"task_456",
fileContent,
{ filename: "test.txt", contentType: "text/plain" }
);ListManager Class
Manages operations related to ClickUp lists. {{ ... }} {{ ... }}
Adds a task to an additional list. Note that this requires the "Tasks in Multiple Lists" ClickApp to be enabled in your workspace.
Parameters:
list_id(required): The ID of the list to add the task totask_id(required): The ID of the task to add to the list
Returns: Promise - The API response
Example:
// Add a task to another list
await clickUp.lists.addTaskToList('123456789', 'abc123def456');getList(list_id)
Retrieves a list by its ID.
Parameters:
list_id(required): The ID of the list to retrieve
Returns: Promise - The list data
Example:
// Get list details
const list = await clickUp.lists.getList('123456789');
console.log(list.name);CustomFieldManager Class
Manages operations related to ClickUp custom fields.
Methods:
getListCustomFields(list_id): Returns all custom fields for a specific listsetCustomFieldValue(params): Sets a custom field value for a specific task
getListCustomFields(list_id)
Fetches all custom fields available in a specific list.
Parameters:
list_id(required): The ClickUp list ID
Returns: Promise - Array of custom field objects
Example:
// Get custom fields for a list
const customFields = await clickUp.customFields.getListCustomFields('123456789');
console.log(customFields);setCustomFieldValue(params)
Sets a custom field value for a specific task.
Parameters:
params.task_id(required): The ID of the task to updateparams.field_id(required): The universal unique identifier (UUID) of the custom fieldparams.value(required): The value to set for the custom field (as a string)
Returns: Promise<Record<string, unknown>> - The API response
Example:
// Set a custom field value
const result = await clickUp.customFields.setCustomFieldValue({
task_id: '86b5jqha9',
field_id: 'df45878b-b48e-415d-9561-f8d0392e9f46',
value: 'New Value'
});TeamManager Class
Manages operations related to ClickUp Teams (workspaces).
getTeams()
Fetches all teams the API key has access to using GET /team.
Parameters:
- None
Returns: Promise<Teams> — where Teams is { teams: Team[] } as defined in src/types/index.ts.
Example:
// Retrieve teams (workspaces)
const { teams } = await clickUp.teams.getTeams();
// List team names
console.log(teams.map(t => t.name));
// Safely access members (may be empty or undefined depending on permissions)
for (const team of teams) {
console.log(`Team: ${team.name} (members: ${team.members?.length ?? 0})`);
}Task Class
Wrapper for individual task objects with helpful methods.
Instance Methods
getAssigneeNames(): Returns an array of assignee usernamesisCompleted(): Returns true if the task status is "done"reduceInfo(): Returns a simplified object with flattened task data- Converts nested properties into flat key-value pairs
- Transforms dropdown custom fields to show option names instead of indices
- Filters out custom fields with undefined values
Static Methods
Task.reduceInfo(tasks): Utility method that handles both single tasks and arrays of tasks- If given a single Task instance, returns its reduced info object
- If given an array of Task instances, returns an array of reduced info objects
- Eliminates the need for
tasks.map(task => task.reduceInfo())
Example:
// For a single task
const reducedTask = Task.reduceInfo(task);
// For an array of tasks - no need for .map() anymore!
const reducedTasks = Task.reduceInfo(tasks);🧱 Project Structure
clickup-sdk/
├── src/
│ ├── api/
│ │ └── axiosClient.ts # Axios client configuration
│ ├── core/
│ │ ├── ClickUp.ts # Main SDK class
│ │ ├── TaskManager.ts # Task operations
│ │ ├── ListManager.ts # List operations
│ │ ├── CustomFieldManager.ts # Custom fields operations
│ │ └── Task.ts # Task wrapper class
│ ├── utils/
│ │ └── queryBuilder.ts # Query string builder
│ └── index.ts # Package entry point
├── examples/
│ └── basic-usage.ts # Example usage
├── .env # Environment variables
├── .gitignore
├── package.json
└── README.md🛠️ Development
Adding New Features
To add new features or API endpoints:
- Create a new manager class in the
src/coredirectory - Add the manager to the ClickUp class
- Implement the API methods in the manager class
Testing
You can test the SDK by modifying the index.ts file and running:
node index.ts📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
