diff --git a/.gitignore b/.gitignore
index 615541a..fa0bc83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
/coverage
/src/client/shared.ts
/src/node/shared.ts
+.cursor
*.log
*.tgz
.DS_Store
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index 76421fb..78158c8 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -686,8 +686,13 @@ export default withMermaid(
collapsed: true,
items: [
{ text: "Overview", link: "/api-reference/epics/overview" },
+ { text: "Create Epic", link: "/api-reference/epics/create-epic" },
{ text: "List Epics", link: "/api-reference/epics/list-epics" },
{ text: "Get Epic", link: "/api-reference/epics/get-epic-detail" },
+ { text: "Update Epic", link: "/api-reference/epics/update-epic" },
+ { text: "Delete Epic", link: "/api-reference/epics/delete-epic" },
+ { text: "Add Epic Work Items", link: "/api-reference/epics/add-epic-work-items" },
+ { text: "List Epic Work Items", link: "/api-reference/epics/list-epic-work-items" },
],
},
{
diff --git a/docs/api-reference/epics/add-epic-work-items.md b/docs/api-reference/epics/add-epic-work-items.md
new file mode 100644
index 0000000..f8a0400
--- /dev/null
+++ b/docs/api-reference/epics/add-epic-work-items.md
@@ -0,0 +1,176 @@
+---
+title: Add work items to epic
+description: Add work items to epic via Plane API. HTTP request format, parameters, scopes, and example responses for add work items to epic.
+keywords: plane, plane api, rest api, api integration, epics, add work items to epic
+---
+
+# Add work items to epic
+
+
+ POST
+ /api/v1/workspaces/{slug}/projects/{project_id}/epics/{epic_id}/issues/
+
+
+
+
+
+Add multiple work items as sub-issues under an epic. Validates type hierarchy before assignment.
+
+
+
+### Path Parameters
+
+
+
+
+
+Epic ID
+
+
+
+
+
+Project ID
+
+
+
+
+
+Workspace slug
+
+
+
+
+
+
+
+
+### Body Parameters
+
+
+
+
+
+List of work item IDs to add to the epic
+
+
+
+
+
+
+
+
+### Scopes
+
+`projects.epics:write`
+
+
+
+
+
+
+
+
+
+
+```bash
+curl -X POST \
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/" \
+ -H "X-API-Key: $PLANE_API_KEY" \
+ # Or use -H "Authorization: Bearer $PLANE_OAUTH_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "work_item_ids": [
+ "550e8400-e29b-41d4-a716-446655440010",
+ "550e8400-e29b-41d4-a716-446655440011"
+ ]
+}'
+```
+
+
+
+
+```python
+import requests
+
+response = requests.post(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/",
+ headers={"X-API-Key": "your-api-key"},
+ json={
+ "work_item_ids": [
+ "550e8400-e29b-41d4-a716-446655440010",
+ "550e8400-e29b-41d4-a716-446655440011"
+ ]
+ }
+)
+print(response.json())
+```
+
+
+
+
+```javascript
+const response = await fetch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/",
+ {
+ method: "POST",
+ headers: {
+ "X-API-Key": "your-api-key",
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ work_item_ids: ["550e8400-e29b-41d4-a716-446655440010", "550e8400-e29b-41d4-a716-446655440011"],
+ }),
+ }
+);
+const data = await response.json();
+```
+
+
+
+
+
+
+```json
+[
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440010",
+ "name": "Implement login screen",
+ "description_html": "Build the login screen UI
",
+ "description_stripped": "Build the login screen UI",
+ "description_binary": null,
+ "state": "550e8400-e29b-41d4-a716-446655440002",
+ "priority": "high",
+ "assignees": [],
+ "labels": [],
+ "type": null,
+ "type_id": null,
+ "estimate_point": null,
+ "point": null,
+ "start_date": null,
+ "target_date": null,
+ "parent": "550e8400-e29b-41d4-a716-446655440001",
+ "sequence_id": 12,
+ "sort_order": 65535.0,
+ "is_draft": false,
+ "completed_at": null,
+ "archived_at": null,
+ "last_activity_at": "2025-03-15T10:00:00Z",
+ "project": "550e8400-e29b-41d4-a716-446655440000",
+ "workspace": "550e8400-e29b-41d4-a716-446655440003",
+ "external_id": null,
+ "external_source": null,
+ "deleted_at": null,
+ "created_at": "2025-03-10T09:00:00Z",
+ "updated_at": "2025-03-15T10:00:00Z",
+ "created_by": "550e8400-e29b-41d4-a716-446655440005",
+ "updated_by": null
+ }
+]
+```
+
+
+
+
+
+
diff --git a/docs/api-reference/epics/create-epic.md b/docs/api-reference/epics/create-epic.md
new file mode 100644
index 0000000..631dbaa
--- /dev/null
+++ b/docs/api-reference/epics/create-epic.md
@@ -0,0 +1,239 @@
+---
+title: Create an epic
+description: Create an epic via Plane API. HTTP request format, parameters, scopes, and example responses for create an epic.
+keywords: plane, plane api, rest api, api integration, epics, create an epic
+---
+
+# Create an epic
+
+
+ POST
+ /api/v1/workspaces/{slug}/projects/{project_id}/epics/
+
+
+
+
+
+Create a new epic in the specified project with the provided details.
+
+
+
+### Path Parameters
+
+
+
+
+
+Project ID
+
+
+
+
+
+Workspace slug
+
+
+
+
+
+
+
+
+### Body Parameters
+
+
+
+
+
+Name of the epic.
+
+
+
+
+
+HTML-formatted description of the epic.
+
+
+
+
+
+ID of the state (status) to assign to the epic.
+
+
+
+
+
+ID of the parent work item.
+
+
+
+
+
+Priority level. Possible values: `none`, `urgent`, `high`, `medium`, `low`.
+
+
+
+
+
+Start date of the epic in YYYY-MM-DD format.
+
+
+
+
+
+Target completion date in YYYY-MM-DD format.
+
+
+
+
+
+List of user IDs to assign to the epic.
+
+
+
+
+
+List of label IDs to apply to the epic.
+
+
+
+
+
+ID of the estimate point.
+
+
+
+
+
+Name of the source system if importing from another tool.
+
+
+
+
+
+External identifier from the source system.
+
+
+
+
+
+
+
+
+### Scopes
+
+`projects.epics:write`
+
+
+
+
+
+
+
+
+
+
+```bash
+curl -X POST \
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/" \
+ -H "X-API-Key: $PLANE_API_KEY" \
+ # Or use -H "Authorization: Bearer $PLANE_OAUTH_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "Develop Mobile Application Framework",
+ "description_html": "Create a cross-platform mobile application framework
",
+ "priority": "high",
+ "start_date": "2025-03-01",
+ "target_date": "2025-06-30"
+}'
+```
+
+
+
+
+```python
+import requests
+
+response = requests.post(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/",
+ headers={"X-API-Key": "your-api-key"},
+ json={
+ "name": "Develop Mobile Application Framework",
+ "description_html": "Create a cross-platform mobile application framework
",
+ "priority": "high",
+ "start_date": "2025-03-01",
+ "target_date": "2025-06-30"
+ }
+)
+print(response.json())
+```
+
+
+
+
+```javascript
+const response = await fetch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/",
+ {
+ method: "POST",
+ headers: {
+ "X-API-Key": "your-api-key",
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ name: "Develop Mobile Application Framework",
+ description_html: "Create a cross-platform mobile application framework
",
+ priority: "high",
+ start_date: "2025-03-01",
+ target_date: "2025-06-30",
+ }),
+ }
+);
+const data = await response.json();
+```
+
+
+
+
+
+
+```json
+{
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "name": "Develop Mobile Application Framework",
+ "description": {},
+ "description_html": "Create a cross-platform mobile application framework
",
+ "description_stripped": "Create a cross-platform mobile application framework",
+ "description_binary": null,
+ "state": "550e8400-e29b-41d4-a716-446655440001",
+ "priority": "high",
+ "assignees": [],
+ "labels": [],
+ "type": "550e8400-e29b-41d4-a716-446655440002",
+ "estimate_point": null,
+ "point": null,
+ "start_date": "2025-03-01",
+ "target_date": "2025-06-30",
+ "parent": null,
+ "sequence_id": 57,
+ "sort_order": 605535.0,
+ "is_draft": false,
+ "completed_at": null,
+ "archived_at": null,
+ "project": "550e8400-e29b-41d4-a716-446655440000",
+ "workspace": "550e8400-e29b-41d4-a716-446655440003",
+ "external_id": null,
+ "external_source": null,
+ "deleted_at": null,
+ "created_at": "2025-03-01T21:23:54.645263Z",
+ "updated_at": "2025-03-01T21:23:54.645263Z",
+ "created_by": "550e8400-e29b-41d4-a716-446655440004",
+ "updated_by": null
+}
+```
+
+
+
+
+
+
diff --git a/docs/api-reference/epics/delete-epic.md b/docs/api-reference/epics/delete-epic.md
new file mode 100644
index 0000000..af63778
--- /dev/null
+++ b/docs/api-reference/epics/delete-epic.md
@@ -0,0 +1,108 @@
+---
+title: Delete an epic
+description: Delete an epic via Plane API. HTTP request format, parameters, scopes, and example responses for delete an epic.
+keywords: plane, plane api, rest api, api integration, epics, delete an epic
+---
+
+# Delete an epic
+
+
+ DELETE
+ /api/v1/workspaces/{slug}/projects/{project_id}/epics/{epic_id}/
+
+
+
+
+
+Permanently delete an existing epic from the project. Child work items will have their parent unset.
+
+
+
+### Path Parameters
+
+
+
+
+
+Epic ID
+
+
+
+
+
+Project ID
+
+
+
+
+
+Workspace slug
+
+
+
+
+
+
+
+
+### Scopes
+
+`projects.epics:write`
+
+
+
+
+
+
+
+
+
+
+```bash
+curl -X DELETE \
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/" \
+ -H "X-API-Key: $PLANE_API_KEY" \
+ # Or use -H "Authorization: Bearer $PLANE_OAUTH_TOKEN" \
+```
+
+
+
+
+```python
+import requests
+
+response = requests.delete(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/",
+ headers={"X-API-Key": "your-api-key"}
+)
+print(response.status_code)
+```
+
+
+
+
+```javascript
+const response = await fetch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/",
+ {
+ method: "DELETE",
+ headers: {
+ "X-API-Key": "your-api-key",
+ },
+ }
+);
+console.log(response.status);
+```
+
+
+
+
+
+
+No response body.
+
+
+
+
+
+
diff --git a/docs/api-reference/epics/list-epic-work-items.md b/docs/api-reference/epics/list-epic-work-items.md
new file mode 100644
index 0000000..99a95c5
--- /dev/null
+++ b/docs/api-reference/epics/list-epic-work-items.md
@@ -0,0 +1,178 @@
+---
+title: List epic work items
+description: List epic work items via Plane API. HTTP request format, parameters, scopes, and example responses for list epic work items.
+keywords: plane, plane api, rest api, api integration, epics, list epic work items
+---
+
+# List epic work items
+
+
+ GET
+ /api/v1/workspaces/{slug}/projects/{project_id}/epics/{epic_id}/issues/
+
+
+
+
+
+Retrieve all work items under an epic.
+
+
+
+### Path Parameters
+
+
+
+
+
+Epic ID
+
+
+
+
+
+Project ID
+
+
+
+
+
+Workspace slug
+
+
+
+
+
+
+
+
+### Query Parameters
+
+
+
+
+
+Pagination cursor for getting next set of results
+
+
+
+
+
+Number of results per page (default: 20, max: 100)
+
+
+
+
+
+
+
+
+### Scopes
+
+`projects.epics:read` `projects.work-items:read`
+
+
+
+
+
+
+
+
+
+
+```bash
+curl -X GET \
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/?per_page=20" \
+ -H "X-API-Key: $PLANE_API_KEY" \
+ # Or use -H "Authorization: Bearer $PLANE_OAUTH_TOKEN" \
+```
+
+
+
+
+```python
+import requests
+
+response = requests.get(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/?per_page=20",
+ headers={"X-API-Key": "your-api-key"}
+)
+print(response.json())
+```
+
+
+
+
+```javascript
+const response = await fetch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/issues/?per_page=20",
+ {
+ method: "GET",
+ headers: {
+ "X-API-Key": "your-api-key",
+ },
+ }
+);
+const data = await response.json();
+```
+
+
+
+
+
+
+```json
+{
+ "grouped_by": null,
+ "sub_grouped_by": null,
+ "total_count": 5,
+ "next_cursor": "20:1:0",
+ "prev_cursor": "20:0:0",
+ "next_page_results": false,
+ "prev_page_results": false,
+ "count": 5,
+ "total_pages": 1,
+ "total_results": 5,
+ "extra_stats": null,
+ "results": [
+ {
+ "id": "550e8400-e29b-41d4-a716-446655440010",
+ "name": "Implement login screen",
+ "description_html": "Build the login screen UI
",
+ "description_stripped": "Build the login screen UI",
+ "description_binary": null,
+ "state": "550e8400-e29b-41d4-a716-446655440002",
+ "priority": "high",
+ "assignees": ["550e8400-e29b-41d4-a716-446655440005"],
+ "labels": [],
+ "type": null,
+ "type_id": null,
+ "estimate_point": null,
+ "point": null,
+ "start_date": "2025-03-10",
+ "target_date": "2025-03-20",
+ "parent": "550e8400-e29b-41d4-a716-446655440001",
+ "sequence_id": 12,
+ "sort_order": 65535.0,
+ "is_draft": false,
+ "completed_at": null,
+ "archived_at": null,
+ "last_activity_at": "2025-03-15T10:00:00Z",
+ "project": "550e8400-e29b-41d4-a716-446655440000",
+ "workspace": "550e8400-e29b-41d4-a716-446655440003",
+ "external_id": null,
+ "external_source": null,
+ "deleted_at": null,
+ "created_at": "2025-03-10T09:00:00Z",
+ "updated_at": "2025-03-15T10:00:00Z",
+ "created_by": "550e8400-e29b-41d4-a716-446655440005",
+ "updated_by": null
+ }
+ ]
+}
+```
+
+
+
+
+
+
diff --git a/docs/api-reference/epics/update-epic.md b/docs/api-reference/epics/update-epic.md
new file mode 100644
index 0000000..11d8677
--- /dev/null
+++ b/docs/api-reference/epics/update-epic.md
@@ -0,0 +1,239 @@
+---
+title: Update an epic
+description: Update an epic via Plane API. HTTP request format, parameters, scopes, and example responses for update an epic.
+keywords: plane, plane api, rest api, api integration, epics, update an epic
+---
+
+# Update an epic
+
+
+ PATCH
+ /api/v1/workspaces/{slug}/projects/{project_id}/epics/{epic_id}/
+
+
+
+
+
+Partially update an existing epic with the provided fields. Supports external ID validation to prevent conflicts.
+
+
+
+### Path Parameters
+
+
+
+
+
+Epic ID
+
+
+
+
+
+Project ID
+
+
+
+
+
+Workspace slug
+
+
+
+
+
+
+
+
+### Body Parameters
+
+
+
+
+
+Name of the epic.
+
+
+
+
+
+HTML-formatted description of the epic.
+
+
+
+
+
+ID of the state (status) to assign to the epic.
+
+
+
+
+
+ID of the parent work item.
+
+
+
+
+
+Priority level. Possible values: `none`, `urgent`, `high`, `medium`, `low`.
+
+
+
+
+
+Start date of the epic in YYYY-MM-DD format.
+
+
+
+
+
+Target completion date in YYYY-MM-DD format.
+
+
+
+
+
+List of user IDs to assign to the epic.
+
+
+
+
+
+List of label IDs to apply to the epic.
+
+
+
+
+
+ID of the estimate point.
+
+
+
+
+
+Name of the source system if importing from another tool.
+
+
+
+
+
+External identifier from the source system.
+
+
+
+
+
+
+
+
+### Scopes
+
+`projects.epics:write`
+
+
+
+
+
+
+
+
+
+
+```bash
+curl -X PATCH \
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/" \
+ -H "X-API-Key: $PLANE_API_KEY" \
+ # Or use -H "Authorization: Bearer $PLANE_OAUTH_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "Updated Epic Name",
+ "priority": "medium",
+ "target_date": "2025-09-30"
+}'
+```
+
+
+
+
+```python
+import requests
+
+response = requests.patch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/",
+ headers={"X-API-Key": "your-api-key"},
+ json={
+ "name": "Updated Epic Name",
+ "priority": "medium",
+ "target_date": "2025-09-30"
+ }
+)
+print(response.json())
+```
+
+
+
+
+```javascript
+const response = await fetch(
+ "https://api.plane.so/api/v1/workspaces/my-workspace/projects/550e8400-e29b-41d4-a716-446655440000/epics/550e8400-e29b-41d4-a716-446655440001/",
+ {
+ method: "PATCH",
+ headers: {
+ "X-API-Key": "your-api-key",
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ name: "Updated Epic Name",
+ priority: "medium",
+ target_date: "2025-09-30",
+ }),
+ }
+);
+const data = await response.json();
+```
+
+
+
+
+
+
+```json
+{
+ "id": "550e8400-e29b-41d4-a716-446655440001",
+ "name": "Updated Epic Name",
+ "description": {},
+ "description_html": "Create a cross-platform mobile application framework
",
+ "description_stripped": "Create a cross-platform mobile application framework",
+ "description_binary": null,
+ "state": "550e8400-e29b-41d4-a716-446655440002",
+ "priority": "medium",
+ "assignees": [],
+ "labels": [],
+ "type": "550e8400-e29b-41d4-a716-446655440003",
+ "estimate_point": null,
+ "point": null,
+ "start_date": "2025-03-01",
+ "target_date": "2025-09-30",
+ "parent": null,
+ "sequence_id": 57,
+ "sort_order": 605535.0,
+ "is_draft": false,
+ "completed_at": null,
+ "archived_at": null,
+ "project": "550e8400-e29b-41d4-a716-446655440000",
+ "workspace": "550e8400-e29b-41d4-a716-446655440004",
+ "external_id": null,
+ "external_source": null,
+ "deleted_at": null,
+ "created_at": "2025-03-01T21:23:54.645263Z",
+ "updated_at": "2025-03-05T14:12:00.123456Z",
+ "created_by": "550e8400-e29b-41d4-a716-446655440005",
+ "updated_by": "550e8400-e29b-41d4-a716-446655440005"
+}
+```
+
+
+
+
+
+