### Setup Test Environment
Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md
Steps to set up the test environment by copying the example environment file and updating it with necessary test credentials.
```bash
# Copy the environment template
cp env.example .env.test
# Update .env.test with your test environment details
# Edit the file with your actual test environment details
nano .env.test
# Required environment variables:
# TEST_WORKSPACE_SLUG: Your test workspace slug
# TEST_PROJECT_ID: Your test project ID
# TEST_USER_ID: Your test user ID
# TEST_WORK_ITEM_ID: A test work item ID
# TEST_CUSTOMER_ID: A test customer ID
# And other test-specific IDs as needed
```
--------------------------------
### Example: Fetching App Installations
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Demonstrates how to fetch all app installations for a bot or a specific installation using a bot token. This is useful for managing bot deployments across different workspaces.
```typescript
const botToken = (await oauth.getBotToken("installation-123")).access_token;
// Get all installations for this bot
const allInstallations = await oauth.getAppInstallations(botToken);
console.log(`Bot installed in ${allInstallations.length} workspaces`);
// Get specific installation
const installation = await oauth.getAppInstallations(
botToken,
"installation-123"
);
console.log(`Workspace: ${installation[0].workspace_detail.name}`);
```
--------------------------------
### Complete Project Setup with States, Labels, and Members
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/States-Labels-Members.md
This comprehensive example demonstrates how to set up a project by creating workflow states, labels, and adding team members using the Plane Node.js SDK. It also shows how to create a work item with assigned states and labels, and finally lists the created resources.
```typescript
import { PlaneClient, HttpError } from "@makeplane/plane-node-sdk";
const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY });
async function setupProject() {
const workspace = "my-workspace";
const projectId = "project-123";
try {
// 1. Create workflow states
console.log("Creating workflow states...");
const backlogState = await client.states.create(workspace, projectId, {
name: "Backlog",
group: "backlog",
color: "#CCCCCC",
});
const inProgressState = await client.states.create(workspace, projectId, {
name: "In Progress",
group: "in_progress",
color: "#FFA500",
});
const doneState = await client.states.create(workspace, projectId, {
name: "Done",
group: "completed",
color: "#00AA00",
});
// 2. Create labels
console.log("Creating labels...");
const bugLabel = await client.labels.create(workspace, projectId, {
name: "bug",
color: "#FF0000",
description: "Something isn't working",
});
const featureLabel = await client.labels.create(workspace, projectId, {
name: "feature",
color: "#0000FF",
description: "New functionality",
});
const docLabel = await client.labels.create(workspace, projectId, {
name: "documentation",
color: "#00FF00",
description: "Documentation updates",
});
// 3. Add team members
console.log("Adding team members...");
const member1 = await client.members.add(workspace, projectId, {
member: "user-1",
role: 15,
});
const member2 = await client.members.add(workspace, projectId, {
member: "user-2",
role: 10,
});
// 4. Create work items with states and labels
console.log("Creating work items...");
const issue = await client.workItems.create(workspace, projectId, {
name: "Fix login button styling",
description_html: "
Login button is misaligned on mobile
",
state: backlogState.id,
labels: [bugLabel.id],
priority: "high",
});
// 5. List all project resources
console.log("\nProject Setup Complete:");
console.log(`States: ${(await client.states.list(workspace, projectId)).length}`);
console.log(`Labels: ${(await client.labels.list(workspace, projectId)).length}`);
console.log(`Members: ${(await client.members.list(workspace, projectId)).length}`);
} catch (error) {
if (error instanceof HttpError) {
console.error(`HTTP ${error.statusCode}: ${error.message}`);
}
}
}
setupProject();
```
--------------------------------
### Run an Example Script
Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md
Execute a TypeScript example script using ts-node.
```bash
npx ts-node examples/bootstrap-project.ts
```
--------------------------------
### Copy Example .env File
Source: https://github.com/makeplane/plane-node-sdk/blob/main/tests/unit/README.md
Create a .env file in the project root by copying the example file. Update this file with your specific test environment details.
```bash
# Copy the example and update with your values
cp env.example .env
```
--------------------------------
### Bot/App Installation Flow
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Demonstrates the complete flow for setting up a bot or application, including obtaining a bot token, retrieving installation details, and performing operations with a bot client.
```typescript
import { OAuthClient, PlaneClient } from "@makeplane/plane-node-sdk";
const oauth = new OAuthClient({
clientId: "bot-app-id",
clientSecret: "bot-app-secret",
redirectUri: "https://bot.example.com/oauth/callback",
});
async function setupBot() {
// 1. Get bot token for app installation
const tokenResponse = await oauth.getBotToken("app-installation-456");
const botToken = tokenResponse.access_token;
// 2. Check installation details
const installation = await oauth.getAppInstallations(botToken);
console.log(`Bot installed in workspace: ${installation[0].workspace_detail.name}`);
// 3. Create client for bot operations
const botClient = new PlaneClient({ accessToken: botToken });
// 4. Perform bot operations
const workItem = await botClient.workItems.create(
installation[0].workspace_detail.slug,
"project-id",
{
name: "Auto-generated from bot",
description_html: "Created by bot integration
",
}
);
console.log(`Created work item: ${workItem.id}`);
}
setupBot().catch(console.error);
```
--------------------------------
### Get App Installations
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Retrieve a list of app installations associated with a bot token. Optionally, filter the results to a specific app installation ID.
```typescript
async getAppInstallations(token: string, appInstallationId?: string): Promise
```
--------------------------------
### Install Dependencies
Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md
Run this command to install the necessary Node.js dependencies for the Plane SDK.
```bash
npm install
```
--------------------------------
### getAppInstallations
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Fetches app installation(s) associated with a bot token. This method can retrieve all installations or filter down to a specific one if an ID is provided.
```APIDOC
## getAppInstallations
### Description
Get app installation(s) using a bot token.
### Method
```typescript
async getAppInstallations(token: string, appInstallationId?: string): Promise
```
### Parameters
#### Path Parameters
- **token** (string) - Required - Bot token from getBotToken method
- **appInstallationId** (string) - Optional - Filter to specific installation (optional)
### Returns
`PlaneOAuthAppInstallation[]`
### PlaneOAuthAppInstallation Type
```typescript
interface PlaneOAuthAppInstallation {
id: string;
workspace: string;
workspace_detail: {
name: string;
slug: string;
id: string;
logo_url?: string;
};
application: string;
status: string;
created_at: string;
updated_at: string;
deleted_at?: string;
created_by?: string;
updated_by?: string;
installed_by: string;
app_bot: string;
webhook?: string;
}
```
### Throws
`Error` if no installations found with the given ID
### Example
```typescript
const botToken = (await oauth.getBotToken("installation-123")).access_token;
// Get all installations for this bot
const allInstallations = await oauth.getAppInstallations(botToken);
console.log(`Bot installed in ${allInstallations.length} workspaces`);
// Get specific installation
const installation = await oauth.getAppInstallations(
botToken,
"installation-123"
);
console.log(`Workspace: ${installation[0].workspace_detail.name}`);
```
```
--------------------------------
### Install Dependencies with pnpm
Source: https://github.com/makeplane/plane-node-sdk/blob/main/CLAUDE.md
Use this command to install all project dependencies using pnpm.
```bash
pnpm install
```
--------------------------------
### Install Plane Node SDK
Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md
Install the Plane Node.js SDK using npm. This command downloads and installs the necessary package for your project.
```bash
npm install @makeplane/plane-node-sdk
```
--------------------------------
### Example HTTP Headers
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Provides an example of the HTTP headers object constructed by the `getHeaders` method. This includes `Content-Type` and authentication headers like `X-Api-Key` or `Authorization`.
```typescript
{
"Content-Type": "application/json",
"X-Api-Key": "your-api-key" // or "Authorization": "Bearer ..."
}
```
--------------------------------
### Quick Start with PlaneClient
Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md
Initialize the PlaneClient and perform basic operations like listing and creating projects. Ensure you replace placeholders with your actual API key or access token and workspace slug.
```typescript
import { PlaneClient } from "@plane/node-sdk";
const client = new PlaneClient({
apiKey: "your-api-key",
});
// Or with custom base URL
const client = new PlaneClient({
baseUrl: "https://your-custom-api.plane.so",
accessToken: "your-access-token",
});
// List projects
const projects = await client.projects.list();
// Create a project
const project = await client.projects.create("workspace-slug", {
name: "My Project",
description: "A new project",
});
```
--------------------------------
### Example: Using getBotToken and Creating a Client
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Demonstrates how to retrieve a bot access token and then use it to instantiate a PlaneClient for performing bot operations. This is useful for automating tasks or integrating bot functionalities.
```typescript
// Get token for bot/app operations
const botTokenResponse = await oauth.getBotToken("app-installation-123");
const botAccessToken = botTokenResponse.access_token;
// Create client for bot operations
const botClient = new PlaneClient({ accessToken: botAccessToken });
// Perform bot operations
await botClient.workItems.create("workspace", "project", {
name: "Auto-created work item",
});
```
--------------------------------
### Error Logging Example
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Illustrates the format for logged errors, including the HTTP status and message.
```json
❌ [ERROR] HttpError: 404 Not Found
```
--------------------------------
### Complete Project Management Example
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Demonstrates the full lifecycle of a project using the Plane Node.js SDK, including creation, retrieval, member listing, feature checking, updating, and archiving. Ensure your PLANE_API_KEY is set in your environment variables.
```typescript
import { PlaneClient, HttpError } from "@makeplane/plane-node-sdk";
const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY });
async function manageProject() {
try {
// Create a new project
const project = await client.projects.create("my-workspace", {
name: "Web Platform",
identifier: "WEB",
description: "Main web application",
});
console.log(`Created project: ${project.id}`);
// Get project details
const details = await client.projects.retrieve("my-workspace", project.id);
console.log(`Name: ${details.name}`);
// List team members
const members = await client.projects.getMembers("my-workspace", project.id);
console.log(`Team size: ${members.length}`);
// Check features
const features = await client.projects.retrieveFeatures("my-workspace", project.id);
console.log(`Cycles enabled: ${features.cycles}`);
// Update project
const updated = await client.projects.update("my-workspace", project.id, {
description: "Updated main web application",
});
// Archive project
await client.projects.archive("my-workspace", project.id);
console.log("Project archived");
} catch (error) {
if (error instanceof HttpError) {
console.error(`Error: ${error.statusCode} - ${error.message}`);
}
}
}
manageProject();
```
--------------------------------
### Request Logging Example
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Shows the format of logged requests when enableLogging is true. Sensitive headers are redacted.
```json
🚀 [REQUEST] {
method: "POST",
url: "https://api.plane.so/api/v1/workspaces/",
headers: { "X-Api-Key": "[REDACTED]", ... },
data: { name: "Project", ... },
params: { ... }
}
```
--------------------------------
### Example of buildUrl Method
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Illustrates the expected output of the `buildUrl` helper method when constructing a full URL for a request, combining the base path with an endpoint.
```typescript
// buildUrl("/workspaces/my-ws/projects/") returns:
// "https://api.plane.so/api/v1/workspaces/my-ws/projects/"
```
--------------------------------
### Example Usage of PaginatedResponse
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md
Demonstrates how to fetch a paginated list of projects and iterate over the results.
```typescript
const response = await client.projects.list("workspace", {
limit: 20,
offset: 0,
});
response.results.forEach(project => console.log(project.name));
```
--------------------------------
### Run Development Watch Mode with pnpm
Source: https://github.com/makeplane/plane-node-sdk/blob/main/CLAUDE.md
Starts the project in watch mode for active development, automatically recompiling on changes.
```bash
pnpm dev
```
--------------------------------
### PlaneOAuthAppInstallation Type Definition
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Defines the structure of an app installation object returned by the getAppInstallations method. This includes details about the workspace, application, and installation status.
```typescript
interface PlaneOAuthAppInstallation {
id: string;
workspace: string;
workspace_detail: {
name: string;
slug: string;
id: string;
logo_url?: string;
};
application: string;
status: string;
created_at: string;
updated_at: string;
deleted_at?: string;
created_by?: string;
updated_by?: string;
installed_by: string;
app_bot: string;
webhook?: string;
}
```
--------------------------------
### Custom Resource Example
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Demonstrates how to extend BaseResource to create a custom API resource, such as `CustomResource`, with methods for listing, creating, retrieving, updating, and deleting custom entities.
```APIDOC
## Example: Creating a Custom Resource
### Description
This example shows how to create a custom API resource by extending the `BaseResource` class. It defines methods like `list`, `create`, `retrieve`, `update`, and `delete` that leverage the inherited `get`, `post`, `patch`, and `httpDelete` methods.
### Class Definition
```typescript
import { BaseResource } from "@makeplane/plane-node-sdk";
import { Configuration } from "../Configuration";
interface CustomEntity {
id: string;
name: string;
// ... other fields
}
export class CustomResource extends BaseResource {
constructor(config: Configuration) {
super(config);
}
async list(workspaceSlug: string): Promise {
// Use inherited get() method
return this.get(`/workspaces/${workspaceSlug}/custom-entities/`);
}
async create(
workspaceSlug: string,
data: Omit
): Promise {
// Use inherited post() method
return this.post(
`/workspaces/${workspaceSlug}/custom-entities/`,
data
);
}
async retrieve(
workspaceSlug: string,
entityId: string
): Promise {
// Use inherited get() method
return this.get(
`/workspaces/${workspaceSlug}/custom-entities/${entityId}/`
);
}
async update(
workspaceSlug: string,
entityId: string,
updates: Partial
): Promise {
// Use inherited patch() method
return this.patch(
`/workspaces/${workspaceSlug}/custom-entities/${entityId}/`,
updates
);
}
async delete(workspaceSlug: string, entityId: string): Promise {
// Use inherited httpDelete() method
return this.httpDelete(
`/workspaces/${workspaceSlug}/custom-entities/${entityId}/`
);
}
}
```
```
--------------------------------
### Retrieve Work Item Examples
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md
Demonstrates retrieving a basic work item versus a work item with expanded labels and assignees.
```typescript
// Type: WorkItemBase with string arrays for labels/assignees
const item = await client.workItems.retrieve("ws", "proj", "id");
// Type: WorkItem with labels: Label[], assignees: User[]
const expanded = await client.workItems.retrieve(
"ws",
"proj",
"id",
["labels", "assignees"]
);
```
--------------------------------
### Complete OAuth Flow Example
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
This example demonstrates a full OAuth 2.0 authorization code flow using Express.js. It includes redirecting users to Plane for authorization, handling the callback, exchanging the authorization code for access and refresh tokens, storing them in the session, and using a middleware to ensure the access token is valid before making API calls.
```typescript
import express from "express";
import { OAuthClient, PlaneClient } from "@makeplane/plane-node-sdk";
const app = express();
const oauth = new OAuthClient({
clientId: process.env.PLANE_CLIENT_ID!,
clientSecret: process.env.PLANE_CLIENT_SECRET!,
redirectUri: "http://localhost:3000/oauth/callback",
});
// Step 1: Redirect user to authorization
app.get("/login", (req, res) => {
const state = Math.random().toString(36).substring(7);
req.session.oauthState = state; // Store for verification
const authUrl = oauth.getAuthorizationUrl("code", state);
res.redirect(authUrl);
});
// Step 2: Handle OAuth callback
app.get("/oauth/callback", async (req, res) => {
const code = req.query.code as string;
const state = req.query.state as string;
const error = req.query.error as string;
if (error) {
return res.status(400).send(`Authorization denied: ${error}`);
}
if (state !== req.session.oauthState) {
return res.status(400).send("State mismatch - CSRF attack detected");
}
try {
// Exchange code for tokens
const tokenResponse = await oauth.exchangeCodeForToken(code);
// Store in session
req.session.accessToken = tokenResponse.access_token;
req.session.refreshToken = tokenResponse.refresh_token;
req.session.expiresAt = Date.now() + ((tokenResponse.expires_in || 3600) * 1000);
res.redirect("/dashboard");
} catch (error) {
console.error("OAuth error:", error);
res.status(500).send("Authentication failed");
}
});
// Middleware to ensure token is fresh
app.use(async (req, res, next) => {
if (!req.session.accessToken) {
return res.redirect("/login");
}
if (req.session.expiresAt < Date.now()) {
try {
const newToken = await oauth.getRefreshToken(req.session.refreshToken);
req.session.accessToken = newToken.access_token;
req.session.expiresAt = Date.now() + ((newToken.expires_in || 3600) * 1000);
} catch (error) {
return res.redirect("/login");
}
}
next();
});
// Step 3: Use access token for API calls
app.get("/api/projects", async (req, res) => {
try {
const client = new PlaneClient({
accessToken: req.session.accessToken,
});
const projects = await client.projects.list("workspace-slug");
res.json(projects);
} catch (error) {
res.status(500).json({ error: "Failed to fetch projects" });
}
});
app.listen(3000, () => {
console.log("OAuth server running on http://localhost:3000");
});
```
--------------------------------
### Projects Class Extending BaseResource
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Example of a subclass calling the BaseResource constructor.
```typescript
class Projects extends BaseResource {
constructor(config: Configuration) {
super(config); // Call parent constructor
}
}
```
--------------------------------
### Development Commands
Source: https://github.com/makeplane/plane-node-sdk/blob/main/README.md
Common commands for developing the Plane Node.js SDK, including installing dependencies, building the project, running tests, linting, and formatting code.
```bash
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run tests
pnpm test
# Lint code
pnpm lint
# Format code
pnpm format
```
--------------------------------
### Assign Work Item with States, Labels, and Members
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/States-Labels-Members.md
This example demonstrates how to fetch states, labels, and members, and then use them to create and assign a new work item. Ensure you have your PLANE_API_KEY set in your environment variables.
```typescript
import { PlaneClient } from "@makeplane/plane-node-sdk";
const client = new PlaneClient({ apiKey: process.env.PLANE_API_KEY });
async function assignWorkItem() {
const workspace = "my-workspace";
const projectId = "project-123";
try {
// Get states
const states = await client.states.list(workspace, projectId);
const inProgressState = states.find(s => s.group === "in_progress");
// Get labels
const labels = await client.labels.list(workspace, projectId);
const bugLabel = labels.find(l => l.name === "bug");
const priorityLabel = labels.find(l => l.name === "critical");
// Get members
const members = await client.members.list(workspace, projectId);
const lead = members[0];
// Create and assign work item
const item = await client.workItems.create(workspace, projectId, {
name: "Critical production bug",
state: inProgressState?.id,
labels: [bugLabel?.id, priorityLabel?.id].filter(Boolean) as string[],
assignees: [lead.user],
priority: "urgent",
});
console.log(`Created and assigned: ${item.id}`);
} catch (error) {
console.error(error);
}
}
assignWorkItem();
```
--------------------------------
### Get Bot Access Token
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Obtain an access token for bot or application installations using the client credentials grant. This token is required for subsequent bot operations.
```typescript
async getBotToken(appInstallationId: string): Promise
```
--------------------------------
### Client Initialization
Source: https://github.com/makeplane/plane-node-sdk/blob/main/AGENTS.MD
Demonstrates how to initialize the Plane Node.js SDK client with necessary configuration.
```APIDOC
## Client Initialization
### Description
Initialize the `PlaneClient` by providing your Plane API base URL, API key, or access token.
### Code Example
```typescript
import { PlaneClient } from "@plane/node-sdk";
const client = new PlaneClient({
baseUrl: process.env.PLANE_BASE_URL, // e.g., "https://api.plane.com/v1"
apiKey: process.env.PLANE_API_KEY, // Optional: for API key authentication
accessToken: process.env.PLANE_ACCESS_TOKEN // Optional: for OAuth/JWT authentication
});
```
### Configuration Parameters
- **baseUrl** (string) - Required - The base URL of the Plane API.
- **apiKey** (string) - Optional - Your Plane API key for authentication.
- **accessToken** (string) - Optional - Your access token for authentication (e.g., JWT or OAuth).
### Usage
Once initialized, the `client` object can be used to access various API resources like `client.projects`, `client.workItems`, etc.
```
--------------------------------
### Initialize PlaneClient
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md
Demonstrates the recommended pattern for initializing the PlaneClient. Ensure PLANE_API_KEY or PLANE_ACCESS_TOKEN environment variables are set. Logging is enabled in development environments.
```typescript
function initializePlaneClient(): PlaneClient {
const apiKey = process.env.PLANE_API_KEY;
const accessToken = process.env.PLANE_ACCESS_TOKEN;
if (!apiKey && !accessToken) {
throw new Error("PLANE_API_KEY or PLANE_ACCESS_TOKEN environment variable required");
}
return new PlaneClient({
baseUrl: process.env.PLANE_BASE_URL, // Optional, defaults to https://api.plane.so
apiKey: apiKey,
accessToken: accessToken,
enableLogging: process.env.NODE_ENV === "development",
});
}
const client = initializePlaneClient();
export default client;
```
--------------------------------
### Get Total Work Logs
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Retrieves the total work logs for a specific project within a workspace. Use this to get aggregated time tracking data.
```typescript
async getTotalWorkLogs(workspaceSlug: string, projectId: string): Promise
```
```typescript
const workLogs = await client.projects.getTotalWorkLogs("my-workspace", "project-123");
console.log(`Total hours logged: ${workLogs.total_duration}`);
```
--------------------------------
### Initialize Configuration with API Key
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md
Create a new Configuration instance, specifying the base URL and API key for authentication. Always call the validate method after initialization to ensure configuration is correct.
```typescript
const config = new Configuration({
baseUrl: "https://api.plane.so",
apiKey: "your-api-key",
});
config.validate(); // Throws if invalid
```
--------------------------------
### Perform GET Request
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Use the `get` method to retrieve data from a specified API endpoint. It accepts query parameters for filtering or sorting results. This method is intended for internal use within subclasses.
```typescript
protected async get(endpoint: string, params?: any): Promise
```
```typescript
return this.get(
`/workspaces/${workspaceSlug}/projects/${projectId}/`
);
```
--------------------------------
### create
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Creates a new project within a specified workspace. You can provide details like name, identifier, description, and timezone.
```APIDOC
## create
### Description
Create a new project in a workspace.
### Method
`POST` (Implicit, SDK method)
### Endpoint
`/workspaces/{workspaceSlug}/projects` (Conceptual)
### Parameters
#### Path Parameters
- **workspaceSlug** (string) - Yes - The workspace identifier (slug)
#### Request Body
- **createProject** (CreateProject) - Yes - Project creation data
- **name** (string) - Yes - Project name
- **identifier** (string) - Optional - Project identifier (auto-generated from name if omitted)
- **description** (string) - Optional - Project description
- **timezone** (string) - Optional - Project timezone
- **cover_image** (string) - Optional - Cover image URL
- **icon_prop** (any) - Optional - Icon properties
### Request Example
```typescript
await client.projects.create("my-workspace", {
name: "Mobile App",
identifier: "MOBILE",
description: "iOS and Android application",
timezone: "America/New_York",
});
```
### Response
#### Success Response (200)
- **Project** (object) - The created project
```
--------------------------------
### Initialize Plane Client and List Projects
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/README.md
Initializes the PlaneClient with an API key and demonstrates how to list projects within a workspace. Ensure you replace 'your-api-key' and 'workspace-slug' with your actual credentials and workspace identifier.
```typescript
import { PlaneClient } from "@makeplane/plane-node-sdk";
const client = new PlaneClient({
apiKey: "your-api-key",
});
// List projects
const projects = await client.projects.list("workspace-slug");
```
--------------------------------
### Get Project Members
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Retrieves a list of members associated with a specific project within a workspace.
```APIDOC
## GET /projects/{workspace_id}/{project_id}/members
### Description
Retrieves a list of members associated with a specific project within a workspace.
### Method
GET
### Endpoint
`/projects/{workspace_id}/{project_id}/members`
### Parameters
#### Path Parameters
- **workspace_id** (string) - Required - The ID of the workspace.
- **project_id** (string) - Required - The ID of the project.
### Response
#### Success Response (200 OK)
- **members** (array) - An array of member objects.
#### Response Example
```json
[
{
"id": "user_abc",
"username": "john.doe",
"display_name": "John Doe",
"email": "john.doe@example.com",
"avatar_url": "https://example.com/avatar.png",
"role": 1
}
]
```
```
--------------------------------
### List Projects with Pagination
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md
Demonstrates how to list projects and access pagination details like total count, items per page, and cursor for loading the next page.
```typescript
const response = await client.projects.list(workspace);
console.log(response.total_count); // Total items
console.log(response.count); // Items in page
console.log(response.results); // Array of items
console.log(response.total_pages); // Total pages
if (response.next_cursor) {
// Load next page
}
```
--------------------------------
### retrieve
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md
Get a cycle by its ID. Requires workspace slug, project ID, and cycle ID.
```APIDOC
## retrieve
### Description
Get a cycle by ID.
### Method
GET (Assumed based on retrieve operation)
### Endpoint
`/workspaces/{workspaceSlug}/projects/{projectId}/cycles/{cycleId}` (Assumed based on parameters)
### Parameters
#### Path Parameters
- **workspaceSlug** (string) - Required - The workspace identifier
- **projectId** (string) - Required - The project ID
- **cycleId** (string) - Required - The cycle ID
### Response
#### Success Response (200 OK)
- **id** (string) - The unique identifier for the cycle
- **name** (string) - Cycle name
- **description** (string) - Cycle description
- **start_date** (string) - Start date (YYYY-MM-DD)
- **end_date** (string) - End date (YYYY-MM-DD)
- **status** (string) - Cycle status
#### Response Example
```json
{
"id": "cycle-123",
"name": "Sprint 1",
"description": "First development sprint",
"start_date": "2024-01-15",
"end_date": "2024-01-29",
"status": "open"
}
```
```
--------------------------------
### Create Project
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Creates a new project within a specified workspace. Requires workspace ID and project details including name, identifier, and description.
```APIDOC
## POST /projects/create
### Description
Creates a new project within a specified workspace.
### Method
POST
### Endpoint
`/projects/create`
### Parameters
#### Path Parameters
- **workspace_id** (string) - Required - The ID of the workspace to create the project in.
#### Request Body
- **name** (string) - Required - The name of the project.
- **identifier** (string) - Required - A unique identifier for the project (e.g., "WEB").
- **description** (string) - Optional - A description of the project.
### Response
#### Success Response (201 Created)
- **project** (Project) - The created project object.
#### Response Example
```json
{
"id": "proj_123",
"name": "Web Platform",
"identifier": "WEB",
"description": "Main web application",
"workspace": "my-workspace",
"is_member": true,
"member_role": 1,
"total_members": 1,
"total_cycles": 0,
"total_modules": 0,
"timezone": "UTC",
"is_deployed": false,
"module_view": true,
"cycle_view": true,
"issue_views_view": true,
"page_view": true,
"intake_view": false,
"archive_in": 30,
"close_in": 60
}
```
```
--------------------------------
### Retrieve Project
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md
Retrieves a specific project by its ID within a workspace. Used for error handling examples.
```APIDOC
## Retrieve Project
### Description
Retrieves a specific project by its ID within a workspace. Used for error handling examples.
### Method
GET
### Endpoint
`/api/v1/workspaces/{workspace_id}/projects/{project_id}`
### Parameters
#### Path Parameters
- **workspace_id** (string) - Required - The identifier of the workspace.
- **project_id** (string) - Required - The identifier of the project.
### Response
#### Success Response (200)
- **id** (string) - The unique identifier of the project.
- **name** (string) - The name of the project.
### Request Example
```typescript
try {
const project = await client.projects.retrieve(
"workspace",
"non-existent-id"
);
} catch (error) {
// Error handling logic
}
```
```
--------------------------------
### Constructor
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/BaseResource.md
Initializes the BaseResource with a configuration object. This constructor is called by all subclasses.
```APIDOC
## Constructor
### Description
Initializes the BaseResource with a configuration object containing authentication and base URL details.
### Signature
```typescript
constructor(config: Configuration)
```
### Parameters
#### Path Parameters
- **config** (`Configuration`) - Required - Configuration object with auth and base URL
```
--------------------------------
### Create Work Item with Priority
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/types.md
Example of creating a work item and assigning it an 'urgent' priority using the PriorityEnum.
```typescript
await client.workItems.create("workspace", "project", {
name: "Fix critical bug",
priority: "urgent",
});
```
--------------------------------
### retrieveFeatures
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Get project features (enabled/disabled capabilities). This method fetches the current feature status for a given project.
```APIDOC
## retrieveFeatures
### Description
Get project features (enabled/disabled capabilities).
### Method
`async`
### Endpoint
`client.projects.retrieveFeatures(workspaceSlug: string, projectId: string)`
### Parameters
#### Path Parameters
- **workspaceSlug** (string) - Yes - The workspace identifier
- **projectId** (string) - Yes - The project ID
### Response
#### Success Response
- **ProjectFeatures**
```
--------------------------------
### Create Sprint Cycle
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md
Create a new sprint cycle with a specified name, start date, and end date.
```typescript
const cycle = await client.cycles.create(workspace, projectId, {
name: "Sprint 5",
start_date: "2024-02-01",
end_date: "2024-02-15",
});
```
--------------------------------
### Initialize PlaneClient with API Key
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md
Initialize the client using an API key for authentication. Ensure 'your-api-key' is replaced with your actual key.
```typescript
const client = new PlaneClient({
apiKey: "your-api-key",
});
```
--------------------------------
### Set API Key Environment Variable
Source: https://github.com/makeplane/plane-node-sdk/blob/main/examples/README.md
Configure your Plane API key as an environment variable before running SDK examples.
```bash
export PLANE_API_KEY="your-api-key"
```
--------------------------------
### Get Project Members
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Fetches the members of a project along with their role information, using the workspace slug and project ID.
```typescript
async getMembers(workspaceSlug: string, projectId: string): Promise
```
```typescript
const members = await client.projects.getMembers("my-workspace", "project-123");
members.forEach(member => {
console.log(`${member.member_detail?.display_name}: ${member.role}`);
});
```
--------------------------------
### Import and Initialize PlaneClient
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md
Import the PlaneClient and initialize it with your API key to access the SDK's functionalities.
```typescript
import { PlaneClient } from "@makeplane/plane-node-sdk";
const client = new PlaneClient({ apiKey: "..." });
```
--------------------------------
### OAuth Flow: Get Authorization URL
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md
Generate the authorization URL required to initiate the OAuth flow and redirect the user.
```typescript
const oauth = new OAuthClient({
clientId: "your-client-id",
clientSecret: "your-client-secret",
redirectUri: "https://yourapp.com/oauth/callback",
});
// 1. Get authorization URL
const authUrl = oauth.getAuthorizationUrl("code", "unique-state-id");
// Redirect user to this URL
```
--------------------------------
### Configuration Class
Source: https://github.com/makeplane/plane-node-sdk/blob/main/AGENTS.MD
Details the `Configuration` class used for setting up the Plane client.
```APIDOC
## Configuration Class
### Description
The `Configuration` class holds the necessary details to connect to the Plane API, including the base URL and authentication credentials.
### Code Example
```typescript
// src/Configuration.ts
export class Configuration {
public basePath: string;
public apiKey?: string;
public accessToken?: string;
constructor(config: {
basePath: string;
apiKey?: string;
accessToken?: string;
}) {
this.basePath = config.basePath;
this.apiKey = config.apiKey;
this.accessToken = config.accessToken;
}
}
```
### Constructor Parameters
- **basePath** (string) - Required - The base URL for the API.
- **apiKey** (string) - Optional - The API key for authentication.
- **accessToken** (string) - Optional - The access token for authentication.
```
--------------------------------
### Initialize PlaneClient with API Key
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md
Instantiate the PlaneClient using an API key for authentication. Ensure the PLANE_API_KEY environment variable is set.
```typescript
import { PlaneClient } from "@makeplane/plane-node-sdk";
// API Key authentication
const client = new PlaneClient({
apiKey: process.env.PLANE_API_KEY,
});
```
--------------------------------
### Manage Projects
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md
Perform CRUD operations on projects within a workspace. Examples include listing, creating, retrieving, and updating projects.
```typescript
// List projects
const projects = await client.projects.list("workspace-slug");
// Create project
const project = await client.projects.create("workspace-slug", {
name: "My Project",
identifier: "PROJ",
});
// Get project details
const details = await client.projects.retrieve("workspace-slug", "project-id");
// Update project
const updated = await client.projects.update("workspace-slug", "project-id", {
description: "Updated description",
});
```
--------------------------------
### Paginate Projects
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/INDEX.md
Demonstrates how to fetch a paginated list of projects from a workspace. Includes loading the next page using a cursor.
```typescript
const response = await client.projects.list("workspace", {
limit: 20,
offset: 0,
});
console.log(`Page 1 of ${response.total_pages}`);
response.results.forEach(item => console.log(item));
if (response.next_cursor) {
// Load next page using cursor
}
```
--------------------------------
### getBotToken
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/OAuthClient.md
Retrieves an access token for bot or application installations using the client credentials grant. This token is essential for authenticating bot operations.
```APIDOC
## getBotToken
### Description
Get an access token for bot/app installations using client credentials grant.
### Method
```typescript
async getBotToken(appInstallationId: string): Promise
```
### Parameters
#### Path Parameters
- **appInstallationId** (string) - Required - The app installation ID
### Returns
`PlaneOAuthTokenResponse` - Bot token response
### Example
```typescript
// Get token for bot/app operations
const botTokenResponse = await oauth.getBotToken("app-installation-123");
const botAccessToken = botTokenResponse.access_token;
// Create client for bot operations
const botClient = new PlaneClient({ accessToken: botAccessToken });
// Perform bot operations
await botClient.workItems.create("workspace", "project", {
name: "Auto-created work item",
});
```
```
--------------------------------
### Enable Request Logging in PlaneClient
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/README.md
Shows how to initialize the PlaneClient with request and response logging enabled. Sensitive headers like Authorization and X-Api-Key are automatically redacted in the logs.
```typescript
const client = new PlaneClient({
apiKey: "your-api-key",
enableLogging: true, // Logs with sensitive data redaction
});
```
--------------------------------
### Example Validation Error Response
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/errors.md
A sample JSON response illustrating validation errors, which may include a 'detail' field or an 'errors' object.
```json
{
"detail": "Project identifier must be unique within workspace",
"errors": {
"identifier": ["This field may not be blank."]
}
}
```
--------------------------------
### getTotalWorkLogs
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Projects.md
Get total work logs for a project. This method retrieves aggregated work log statistics for a specified project within a workspace.
```APIDOC
## getTotalWorkLogs
### Description
Get total work logs for a project.
### Method
`async`
### Endpoint
`client.projects.getTotalWorkLogs(workspaceSlug: string, projectId: string)`
### Parameters
#### Path Parameters
- **workspaceSlug** (string) - Yes - The workspace identifier
- **projectId** (string) - Yes - The project ID
### Response
#### Success Response
- **any** - Total work log statistics
```
--------------------------------
### Create Sprint Cycle
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/README.md
Creates a new sprint cycle for a project, specifying the cycle's name, start date, and end date.
```APIDOC
## POST /cycles.create
### Description
Creates a new sprint cycle.
### Method
POST
### Endpoint
`/cycles.create`
### Parameters
#### Path Parameters
- **workspace** (string) - Required - The workspace ID.
- **projectId** (string) - Required - The project ID.
#### Request Body
- **name** (string) - Required - The name of the sprint cycle (e.g., "Sprint 5").
- **start_date** (string) - Required - The start date of the cycle (YYYY-MM-DD).
- **end_date** (string) - Required - The end date of the cycle (YYYY-MM-DD).
```
--------------------------------
### Initialize PlaneClient with Access Token
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/configuration.md
Initialize the client using an OAuth access token for authentication. Replace 'your-access-token' with your actual token.
```typescript
const client = new PlaneClient({
accessToken: "your-access-token",
});
```
--------------------------------
### Create Cycle
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md
Creates a new cycle (sprint) within a specified project and workspace. Requires name, start date, and end date.
```APIDOC
## Create Cycle
### Description
Creates a new cycle (sprint) within a specified project and workspace. Requires name, start date, and end date.
### Method
POST
### Endpoint
`/api/v1/workspaces/{workspace_id}/projects/{project_id}/cycles`
### Parameters
#### Path Parameters
- **workspace_id** (string) - Required - The identifier of the workspace.
- **project_id** (string) - Required - The identifier of the project.
#### Request Body
- **name** (string) - Required - The name of the cycle.
- **start_date** (string) - Required - The start date of the cycle (YYYY-MM-DD).
- **end_date** (string) - Required - The end date of the cycle (YYYY-MM-DD).
### Response
#### Success Response (201)
- **id** (string) - The unique identifier of the created cycle.
- **name** (string) - The name of the cycle.
- **start_date** (string) - The start date of the cycle.
- **end_date** (string) - The end date of the cycle.
### Request Example
```typescript
const cycle = await client.cycles.create(
"my-workspace",
"project-123",
{
name: "Sprint 1",
start_date: "2024-01-15",
end_date: "2024-01-29",
}
);
```
### Response Example
```json
{
"id": "cycle-abcde",
"name": "Sprint 1",
"start_date": "2024-01-15",
"end_date": "2024-01-29"
}
```
```
--------------------------------
### PlaneClient Constructor
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/PlaneClient.md
Initializes a new instance of the PlaneClient. It requires authentication credentials and optionally accepts a base URL and logging configuration.
```APIDOC
## PlaneClient Constructor
### Description
Initializes a new instance of the PlaneClient. It requires authentication credentials and optionally accepts a base URL and logging configuration.
### Method
`new PlaneClient(config: { baseUrl?: string; apiKey?: string; accessToken?: string; enableLogging?: boolean; })`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters Table
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| baseUrl | `string` | No | `"https://api.plane.so"` | Base URL for the Plane API. Use for self-hosted instances. |
| apiKey | `string` | No (1) | — | API key for authentication (X-Api-Key header). |
| accessToken | `string` | No (1) | — | OAuth access token (Authorization: Bearer header). |
| enableLogging | `boolean` | No | `false` | Enable request/response logging with sensitive data redaction. |
**(1)** Either `apiKey` or `accessToken` is required.
### Throws
`Error` if neither apiKey nor accessToken is provided, or if baseUrl is invalid.
### Example
```typescript
const client = new PlaneClient({
apiKey: "your-api-key",
enableLogging: true,
});
```
```
--------------------------------
### create
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/Cycles.md
Create a new cycle in a project. Requires workspace slug, project ID, and cycle creation data.
```APIDOC
## create
### Description
Create a new cycle in a project.
### Method
POST (Assumed based on create operation)
### Endpoint
`/workspaces/{workspaceSlug}/projects/{projectId}/cycles` (Assumed based on parameters)
### Parameters
#### Path Parameters
- **workspaceSlug** (string) - Required - The workspace identifier
- **projectId** (string) - Required - The project ID
#### Request Body
- **name** (string) - Required - Cycle name
- **description** (string) - Optional - Cycle description
- **start_date** (string) - Optional - Start date (YYYY-MM-DD)
- **end_date** (string) - Optional - End date (YYYY-MM-DD)
- **status** (string) - Optional - Cycle status
### Request Example
```json
{
"name": "Sprint 1",
"description": "First development sprint",
"start_date": "2024-01-15",
"end_date": "2024-01-29"
}
```
### Response
#### Success Response (201 Created - Assumed)
- **id** (string) - The unique identifier for the created cycle
- **name** (string) - Cycle name
- **description** (string) - Cycle description
- **start_date** (string) - Start date (YYYY-MM-DD)
- **end_date** (string) - End date (YYYY-MM-DD)
- **status** (string) - Cycle status
#### Response Example
```json
{
"id": "cycle-abc",
"name": "Sprint 1",
"description": "First development sprint",
"start_date": "2024-01-15",
"end_date": "2024-01-29",
"status": "open"
}
```
```
--------------------------------
### Retrieve a Work Item by Identifier
Source: https://github.com/makeplane/plane-node-sdk/blob/main/_autodocs/api-reference/WorkItems.md
Get a single work item using its unique identifier, which can span across projects. Optionally expand fields for more detailed information.
```typescript
const item = await client.workItems.retrieveByIdentifier(
"my-workspace",
"PROJ-123"
);
console.log(`Retrieved: ${item.name}`);
```