Download OpenAPI specification:
Backend API for collaborative project management with JWT auth, file storage, full-text search, AI-powered task suggestions, automated releases, and dual npm publishing.
All endpoints require JWT authentication via Authorization: Bearer <token> header,
except the following public endpoints:
/auth/login - User login/health - Health check/ - Root endpointAll list endpoints use cursor-based pagination with ULID cursors:
page[size]: Number of items (1-200, default 50)page[after]: ULID cursor for next pageResponse format:
{
"data": [...],
"pagination": {
"next_cursor": "01HQXXXXXXXXXXXXXXXXXXXXXX",
"has_more": true,
"size": 50
}
}
Bulk operations and file uploads support the Idempotency-Key header (optional but recommended):
POST /tasks:bulkPOST /files/versionsUse a unique ULID or UUID to prevent duplicate operations on retry.
User login
| email required | string (Email) |
| password required | string (Password) |
{- "email": "string",
- "password": "string"
}{- "access": "string",
- "refresh": "string",
- "user": {
- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
}Public user registration endpoint
Creates a new regular user account (non-admin). Email must be unique.
| name required | string (Name) |
| email required | string <email> (Email) |
| password required | string (Password) |
{- "name": "string",
- "email": "user@example.com",
- "password": "string"
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Request password reset
Generates a reset token and returns it. In production, this would send an email instead of returning the token.
| email required | string <email> (Email) Email address of the user |
{- "email": "user@example.com"
}{- "message": "string",
- "email": "string"
}Reset password with token
Uses the token from forgot-password to set a new password.
| token required | string (Token) non-empty Password reset token |
| new_password required | string (New Password) >= 6 characters New password (min 6 characters) |
{- "token": "string",
- "new_password": "string"
}{- "message": "string"
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Update own profile (name, avatar)
Name (string) or Name (null) (Name) | |
Avatar (string) or Avatar (null) (Avatar) |
{- "name": "string",
- "avatar": "string"
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Change own password (requires old password)
| old_password required | string (Old Password) >= 6 characters |
| new_password required | string (New Password) >= 6 characters |
{- "old_password": "string",
- "new_password": "string"
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}{- "user": {
- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}, - "stats": {
- "workspaces_count": 0,
- "projects_count": 0,
- "tasks_assigned": 0,
- "tasks_completed": 0,
- "tasks_in_progress": 0
}
}[- {
- "id": "string",
- "device_info": "string",
- "ip_address": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "last_used_at": "2025-10-09T14:30:00Z",
- "expires_at": "2025-10-09T14:30:00Z",
- "is_current": true
}
]Admin-only: Search and filter users with advanced criteria
Q (string) or Q (null) (Q) Search query (name or email) | |
Is Admin (boolean) or Is Admin (null) (Is Admin) Filter by admin status | |
Is Active (boolean) or Is Active (null) (Is Active) Filter by active status | |
| sort_by | string (Sort By) Default: "created_at" Sort field: name, email, created_at |
| sort_order | string (Sort Order) Default: "desc" Sort order: asc, desc |
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Admin-only: Activate a deactivated user account
| user_id required | string (User Id) |
{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: Deactivate a user account (soft delete)
| user_id required | string (User Id) |
{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: Bulk import users from JSON
required | Array of objects (Users) [ 1 .. 1000 ] items List of users to import (1-1000) |
{- "users": [
- {
- "name": "string",
- "email": "user@example.com",
- "password": "string",
- "is_admin": false
}
]
}{- "created": [
- {
- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "failed": [
- {
- "property1": "string",
- "property2": "string"
}
], - "total": 0,
- "success_count": 0,
- "failure_count": 0
}Admin-only: Create a new user with optional admin privileges
| name required | string (Name) |
| email required | string <email> (Email) |
| password required | string (Password) |
Is Admin (boolean) or Is Admin (null) (Is Admin) Default: false |
{- "name": "string",
- "email": "user@example.com",
- "password": "string",
- "is_admin": false
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: List all users with cursor-based pagination
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Admin-only: Get detailed information about a specific user
| user_id required | string (User Id) |
{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: Update user information (name, email, avatar, admin status)
| user_id required | string (User Id) |
Name (string) or Name (null) (Name) | |
Email (string) or Email (null) (Email) | |
Avatar (string) or Avatar (null) (Avatar) | |
Is Admin (boolean) or Is Admin (null) (Is Admin) |
{- "name": "string",
- "email": "user@example.com",
- "avatar": "string",
- "is_admin": true
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: Change a user's password
| user_id required | string (User Id) |
| password required | string (Password) >= 6 characters New password (min 6 characters) |
{- "password": "string"
}{- "name": "string",
- "email": "user@example.com",
- "id": "string",
- "avatar": "string",
- "is_admin": true,
- "is_active": true,
- "last_login_at": "2025-10-09T14:30:00Z",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Admin-only: View audit trail of all admin actions
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "id": "string",
- "user_id": "string",
- "action": "string",
- "target_type": "string",
- "target_id": "string",
- "details": { },
- "ip_address": "string",
- "created_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Create a new team
| name required | string (Name) |
{- "name": "string"
}{- "id": "string",
- "name": "string",
- "created_at": "2025-10-09T14:30:00Z"
}List user's teams with pagination.
Returns all teams where the current user is a member.
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "id": "string",
- "name": "string",
- "created_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Add member to team
| team_id required | string (Team Id) |
| user_id required | string (User Id) |
| role required | string (Role) |
{- "user_id": "string",
- "role": "string"
}nullList team members with pagination.
Returns all members of the specified team.
| team_id required | string (Team Id) |
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "id": "string",
- "team_id": "string",
- "user_id": "string",
- "role": "string"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Update team
| team_id required | string (Team Id) |
Name (string) or Name (null) (Name) |
{- "name": "string"
}{- "id": "string",
- "name": "string",
- "created_at": "2025-10-09T14:30:00Z"
}Update team member role
| team_id required | string (Team Id) |
| member_id required | string (Member Id) |
Role (string) or Role (null) (Role) |
{- "role": "string"
}{- "id": "string",
- "team_id": "string",
- "user_id": "string",
- "role": "string"
}Create a new workspace
| name required | string (Name) |
Key (string) or Key (null) (Key) | |
Settings (object) or Settings (null) (Settings) |
{- "key": "MYCO",
- "name": "My Company Workspace",
- "settings": {
- "notifications": true,
- "theme": "dark"
}
}{- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "name": "My Company Workspace",
- "key": "MYCO",
- "settings_json": "{\"theme\": \"dark\", \"notifications\": true}",
- "created_at": "2025-10-09T10:00:00Z",
- "updated_at": "2025-10-09T10:00:00Z"
}List workspaces with cursor-based pagination.
Use filter[member]=me to list only workspaces where current user is a member.
Filter[Member] (string) or Filter[Member] (null) (Filter[Member]) | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "name": "string",
- "key": "string",
- "settings_json": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Get workspace details
| workspace_id required | string (Workspace Id) |
{- "id": "string",
- "name": "string",
- "key": "string",
- "settings_json": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Update workspace
| workspace_id required | string (Workspace Id) |
Name (string) or Name (null) (Name) | |
Settings (object) or Settings (null) (Settings) |
{- "name": "string",
- "settings": { }
}{- "id": "string",
- "name": "string",
- "key": "string",
- "settings_json": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}List all principals (access control entries) for a workspace.
Returns users and teams with their roles (viewer, member, admin, owner).
Example Response:
{
"data": [
{
"id": "01HQX1A2B3C4D5E6F7G8H9J0K1",
"workspace_id": "01HQY...",
"principal_type": "user",
"principal_id": "01HQZ...",
"role": "owner",
"created_at": "2025-10-09T10:00:00Z"
}
],
"pagination": {
"next_cursor": "01HQX1A2B3C4D5E6F7G8H9J0K1",
"has_more": true,
"size": 50
}
}
| workspace_id required | string (Workspace Id) |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "principal_type": "string",
- "principal_id": "string",
- "role": "string",
- "created_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Add principal to workspace
| workspace_id required | string (Workspace Id) |
| principal_type required | string (Principal Type) Type of principal (user or team) |
| principal_id required | string (Principal Id) ULID of user or team |
| role required | string (Role) Role (viewer, member, admin, owner) |
{- "principal_type": "string",
- "principal_id": "string",
- "role": "string"
}nullUpdate workspace principal role
| workspace_id required | string (Workspace Id) |
| principal_id required | string (Principal Id) |
| role required | string (Role) New role for the principal |
{- "role": "string"
}nullCreate a new project
| workspace_id required | string (Workspace Id) |
| name required | string (Name) |
Code (string) or Code (null) (Code) | |
Start At (string) or Start At (null) (Start At) | |
End At (string) or End At (null) (End At) | |
Description (string) or Description (null) (Description) |
{- "code": "WEB-2025",
- "description": "Complete redesign of company website with new branding",
- "end_at": "2025-12-31T23:59:59Z",
- "name": "Website Redesign",
- "start_at": "2025-10-15T00:00:00Z",
- "workspace_id": "01HQXXXXXXXXXXXXXXXXXXXXXX"
}{- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "workspace_id": "01HQYYYYYYYYYYYYYYYYYYYY",
- "name": "Website Redesign",
- "code": "WEB-2025",
- "status": "active",
- "start_at": "2025-10-15T00:00:00Z",
- "end_at": "2025-12-31T23:59:59Z",
- "description": "Complete redesign of company website",
- "created_at": "2025-10-09T10:00:00Z",
- "updated_at": "2025-10-09T10:00:00Z"
}List projects with cursor-based pagination.
Use filter[workspaceId] to list projects in a specific workspace. Use filter[status] to filter by project status.
Filter[Workspaceid] (string) or Filter[Workspaceid] (null) (Filter[Workspaceid]) | |
Filter[Status] (string) or Filter[Status] (null) (Filter[Status]) | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "workspace_id": "string",
- "name": "string",
- "code": "string",
- "status": "string",
- "start_at": "string",
- "end_at": "string",
- "manager_id": "string",
- "description": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Get project details
| project_id required | string (Project Id) |
{- "id": "string",
- "workspace_id": "string",
- "name": "string",
- "code": "string",
- "status": "string",
- "start_at": "string",
- "end_at": "string",
- "manager_id": "string",
- "description": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Update project
| project_id required | string (Project Id) |
Name (string) or Name (null) (Name) | |
Code (string) or Code (null) (Code) | |
Status (string) or Status (null) (Status) | |
Start At (string) or Start At (null) (Start At) | |
End At (string) or End At (null) (End At) | |
Manager Id (string) or Manager Id (null) (Manager Id) | |
Description (string) or Description (null) (Description) |
{- "name": "string",
- "code": "string",
- "status": "string",
- "start_at": "string",
- "end_at": "string",
- "manager_id": "string",
- "description": "string"
}{- "id": "string",
- "workspace_id": "string",
- "name": "string",
- "code": "string",
- "status": "string",
- "start_at": "string",
- "end_at": "string",
- "manager_id": "string",
- "description": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}List all principals (access control entries) for a project.
Returns users and teams with their roles (maintainer, contributor, guest).
Example Response:
{
"data": [
{
"id": "01HQX1A2B3C4D5E6F7G8H9J0K1",
"project_id": "01HQY...",
"principal_type": "user",
"principal_id": "01HQZ...",
"role": "maintainer",
"created_at": "2025-10-09T10:00:00Z"
}
],
"pagination": {
"next_cursor": "01HQX1A2B3C4D5E6F7G8H9J0K1",
"has_more": false,
"size": 1
}
}
| project_id required | string (Project Id) |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "principal_type": "string",
- "principal_id": "string",
- "role": "string",
- "created_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Add principal to project
| project_id required | string (Project Id) |
| principal_type required | string (Principal Type) Type of principal (user or team) |
| principal_id required | string (Principal Id) ULID of user or team |
| role required | string (Role) Role (viewer, member, admin, owner) |
{- "principal_type": "string",
- "principal_id": "string",
- "role": "string"
}nullUpdate project principal role
| project_id required | string (Project Id) |
| principal_id required | string (Principal Id) |
| role required | string (Role) New role for the principal |
{- "role": "string"
}nullCreate a new WBS node
| project_id required | string (Project Id) |
Parent Id (string) or Parent Id (null) (Parent Id) | |
| type required | string (Type) |
| name required | string (Name) |
{- "name": "Planning",
- "project_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "type": "phase"
}{- "id": "string",
- "project_id": "string",
- "parent_id": "string",
- "type": "string",
- "name": "string",
- "wbs_index": "string",
- "owner_id": "string",
- "estimate_hours": 0,
- "status": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}List WBS nodes with cursor-based pagination.
Default sort is by wbs_index for hierarchical order (1, 1.1, 1.1.1, 1.2, 2, ...).
Filter[Projectid] (string) or Filter[Projectid] (null) (Filter[Projectid]) | |
Sort (string) or Sort (null) (Sort) Default: "wbs_index" Sort field (default: wbs_index for hierarchical order) | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "project_id": "string",
- "parent_id": "string",
- "type": "string",
- "name": "string",
- "wbs_index": "string",
- "owner_id": "string",
- "estimate_hours": 0,
- "status": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Get WBS node details
| wbs_id required | string (Wbs Id) |
{- "id": "string",
- "project_id": "string",
- "parent_id": "string",
- "type": "string",
- "name": "string",
- "wbs_index": "string",
- "owner_id": "string",
- "estimate_hours": 0,
- "status": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Update WBS node
| wbs_id required | string (Wbs Id) |
Parent Id (string) or Parent Id (null) (Parent Id) | |
Name (string) or Name (null) (Name) | |
Status (string) or Status (null) (Status) | |
Owner Id (string) or Owner Id (null) (Owner Id) | |
Estimate Hours (number) or Estimate Hours (null) (Estimate Hours) |
{- "parent_id": "string",
- "name": "string",
- "status": "string",
- "owner_id": "string",
- "estimate_hours": 0
}{- "id": "string",
- "project_id": "string",
- "parent_id": "string",
- "type": "string",
- "name": "string",
- "wbs_index": "string",
- "owner_id": "string",
- "estimate_hours": 0,
- "status": "string",
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Create a new task
| project_id required | string (Project Id) |
| wbs_id required | string (Wbs Id) |
| title required | string (Title) |
Description (string) or Description (null) (Description) | |
Assignee Id (string) or Assignee Id (null) (Assignee Id) | |
Estimate Hours (number) or Estimate Hours (null) (Estimate Hours) Default: 0 | |
TaskState (string) or null | |
TaskPriority (string) or null | |
Start At (string) or Start At (null) (Start At) | |
Due At (string) or Due At (null) (Due At) | |
Array of Visible In Views (strings) or Visible In Views (null) (Visible In Views) | |
Percent Done (number) or Percent Done (null) (Percent Done) Default: 0 |
{- "assignee_id": "01HQZZZZZZZZZZZZZZZZZZZZZ",
- "description": "Add JWT-based authentication with login/logout",
- "due_at": "2025-10-12T17:00:00Z",
- "estimate_hours": 8,
- "priority": "high",
- "project_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "start_at": "2025-10-10T09:00:00Z",
- "state": "todo",
- "title": "Implement user authentication",
- "wbs_id": "01HQYYYYYYYYYYYYYYYYYYYY"
}{- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "project_id": "01HQYYYYYYYYYYYYYYYYYYYY",
- "wbs_id": "01HQZZZZZZZZZZZZZZZZZZZZZ",
- "title": "Implement user authentication",
- "description": "Add JWT-based authentication with login/logout",
- "assignee_id": "01HQAAAAAAAAAAAAAAAAAAAAA",
- "estimate_hours": 8,
- "remaining_hours": 8,
- "state": "todo",
- "priority": "high",
- "start_at": "2025-10-10T09:00:00Z",
- "due_at": "2025-10-12T17:00:00Z",
- "visible_in_views": [
- "board",
- "table",
- "tree",
- "calendar",
- "gantt"
], - "percent_done": 0,
- "duration_days": 3,
- "created_at": "2025-10-09T10:00:00Z",
- "updated_at": "2025-10-09T10:00:00Z"
}List tasks with optional view filtering.
View rules:
state field (Kanban columns)start_at OR due_atstart_at AND due_at (both dates)Tasks are automatically assigned to views based on their properties. Use visible_in_views to override.
Subtasks behavior:
include_subtasks=true: Include subtasks in response (for table/tree views)include_subtasks=false (default): Parent tasks onlyExample Response:
{
"data": [
{
"id": "01HQX...",
"project_id": "01HQY...",
"wbs_id": "01HQZ...",
"title": "Implement authentication",
"state": "in_progress",
"priority": "high",
"estimate_hours": 8.0,
"remaining_hours": 4.0,
"assignee_id": "01HQW..."
}
],
"pagination": {
"next_cursor": "01HQX...",
"has_more": true,
"size": 50
}
}
Filter[Projectid] (string) or Filter[Projectid] (null) (Filter[Projectid]) | |
Filter[State] (string) or Filter[State] (null) (Filter[State]) | |
Filter[Wbsid] (string) or Filter[Wbsid] (null) (Filter[Wbsid]) | |
Filter[Assigneeid] (string) or Filter[Assigneeid] (null) (Filter[Assigneeid]) Filter by assigned user | |
TaskView (string) or Filter[View] (null) (Filter[View]) Filter tasks by view. board=requires state; calendar=requires start_at OR due_at; gantt=requires start_at AND due_at | |
| include_subtasks | boolean (Include Subtasks) Default: false Include subtasks in response. Useful for table/tree views. Never included in board/gantt views. |
Sort (string) or Sort (null) (Sort) Sort fields: priority, state, due_at, created_at, wbs_index. Prefix with - for descending | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "project_id": "01HQYYYYYYYYYYYYYYYYYYYY",
- "wbs_id": "01HQZZZZZZZZZZZZZZZZZZZZZ",
- "title": "Implement user authentication",
- "state": "in_progress",
- "priority": "high",
- "estimate_hours": 8,
- "remaining_hours": 5.5,
- "percent_done": 30
}
], - "pagination": {
- "next_cursor": "01HQAAAAAAAAAAAAAAAAAAAAA",
- "has_more": true,
- "size": 1
}
}Get task details
| task_id required | string (Task Id) |
{- "assignee_id": "01HQAAAAAAAAAAAAAAAAAAAAA",
- "created_at": "2025-10-09T10:00:00Z",
- "description": "Add JWT-based authentication with login/logout",
- "due_at": "2025-10-12T17:00:00Z",
- "duration_days": 3,
- "estimate_hours": 8,
- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "percent_done": 30,
- "priority": "high",
- "project_id": "01HQYYYYYYYYYYYYYYYYYYYY",
- "remaining_hours": 5.5,
- "start_at": "2025-10-10T09:00:00Z",
- "state": "in_progress",
- "title": "Implement user authentication",
- "updated_at": "2025-10-10T14:30:00Z",
- "visible_in_views": [
- "board",
- "table",
- "tree",
- "calendar",
- "gantt"
], - "wbs_id": "01HQZZZZZZZZZZZZZZZZZZZZZ"
}Update task
| task_id required | string (Task Id) |
Title (string) or Title (null) (Title) | |
Description (string) or Description (null) (Description) | |
Assignee Id (string) or Assignee Id (null) (Assignee Id) | |
Wbs Id (string) or Wbs Id (null) (Wbs Id) | |
Estimate Hours (number) or Estimate Hours (null) (Estimate Hours) | |
Remaining Hours (number) or Remaining Hours (null) (Remaining Hours) | |
TaskState (string) or null | |
TaskPriority (string) or null | |
Start At (string) or Start At (null) (Start At) | |
Due At (string) or Due At (null) (Due At) | |
Array of Visible In Views (strings) or Visible In Views (null) (Visible In Views) | |
Percent Done (number) or Percent Done (null) (Percent Done) |
{- "title": "string",
- "description": "string",
- "assignee_id": "string",
- "wbs_id": "string",
- "estimate_hours": 0,
- "remaining_hours": 0,
- "state": "todo",
- "priority": "low",
- "start_at": "2025-10-09T14:30:00Z",
- "due_at": "2025-10-09T14:30:00Z",
- "visible_in_views": [
- "board"
], - "percent_done": 0
}{- "assignee_id": "01HQAAAAAAAAAAAAAAAAAAAAA",
- "created_at": "2025-10-09T10:00:00Z",
- "description": "Add JWT-based authentication with login/logout",
- "due_at": "2025-10-12T17:00:00Z",
- "duration_days": 3,
- "estimate_hours": 8,
- "id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "percent_done": 30,
- "priority": "high",
- "project_id": "01HQYYYYYYYYYYYYYYYYYYYY",
- "remaining_hours": 5.5,
- "start_at": "2025-10-10T09:00:00Z",
- "state": "in_progress",
- "title": "Implement user authentication",
- "updated_at": "2025-10-10T14:30:00Z",
- "visible_in_views": [
- "board",
- "table",
- "tree",
- "calendar",
- "gantt"
], - "wbs_id": "01HQZZZZZZZZZZZZZZZZZZZZZ"
}Bulk create multiple tasks in a single request.
Features:
Idempotency-Key header to prevent duplicate creation on retryIdempotency:
Include an Idempotency-Key header (ULID or UUID) to make this operation idempotent.
If you retry with the same key, you'll get the same response without creating duplicates.
Example:
curl -X POST "$API/tasks:bulk" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: 01HQXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"tasks": [{"project_id":"...","wbs_id":"...","title":"Task 1"}]}'
required | Array of objects (Tasks) [ 1 .. 100 ] items List of 1-100 tasks to create |
{- "tasks": [
- {
- "estimate_hours": 4,
- "priority": "high",
- "project_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "title": "Setup development environment",
- "wbs_id": "01HQYYYYYYYYYYYYYYYYYYYY"
}, - {
- "estimate_hours": 8,
- "priority": "medium",
- "project_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "title": "Create database schema",
- "wbs_id": "01HQYYYYYYYYYYYYYYYYYYYY"
}
]
}{- "created": [
- {
- "created_at": "2025-10-09T14:30:00Z",
- "estimate_hours": 4,
- "id": "01HQZZZZ1ZZZZZZZZZZZZZZZZZ",
- "percent_done": 0,
- "priority": "high",
- "project_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "remaining_hours": 4,
- "state": "todo",
- "title": "Setup development environment",
- "updated_at": "2025-10-09T14:30:00Z",
- "wbs_id": "01HQYYYYYYYYYYYYYYYYYYYY"
}
], - "failed": [ ],
- "failure_count": 0,
- "success_count": 2,
- "total": 2
}Bulk update multiple tasks with the same changes.
Features:
Example:
curl -X PATCH "$API/tasks:bulk" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ids":["01HQ...","01HQ..."],"patch":{"state":"in_progress"}}'
| ids required | Array of strings (Ids) |
required | object (TaskUpdate) |
{- "ids": [
- "string"
], - "patch": {
- "title": "string",
- "description": "string",
- "assignee_id": "string",
- "wbs_id": "string",
- "estimate_hours": 0,
- "remaining_hours": 0,
- "state": "todo",
- "priority": "low",
- "start_at": "2025-10-09T14:30:00Z",
- "due_at": "2025-10-09T14:30:00Z",
- "visible_in_views": [
- "board"
], - "percent_done": 0
}
}{- "message": "string",
- "updated_count": 0,
- "requested_count": 0
}Create a subtask
| task_id required | string (Task Id) |
| title required | string (Title) |
Estimate Hours (number) or Estimate Hours (null) (Estimate Hours) Default: 0 |
{- "title": "string",
- "estimate_hours": 0
}{- "id": "string",
- "task_id": "string",
- "title": "string",
- "state": "string",
- "estimate_hours": 0,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}List subtasks for a task with pagination.
Returns all subtasks belonging to the specified task.
| task_id required | string (Task Id) |
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "id": "string",
- "task_id": "string",
- "title": "string",
- "state": "string",
- "estimate_hours": 0,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Update subtask
| subtask_id required | string (Subtask Id) |
Title (string) or Title (null) (Title) | |
State (string) or State (null) (State) | |
Estimate Hours (number) or Estimate Hours (null) (Estimate Hours) |
{- "title": "string",
- "state": "string",
- "estimate_hours": 0
}{- "id": "string",
- "task_id": "string",
- "title": "string",
- "state": "string",
- "estimate_hours": 0,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Upload a file with optional links to workspace/project/wbs/task entities.
Note on links parameter:
Due to multipart/form-data limitations, the links field must be a JSON-encoded string,
not a native array. Example: '[{"targetType":"project","targetId":"01HQ..."}]'
Example with curl:
curl -X POST "$API/files" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@document.pdf" \
-F "name=Quarterly Report" \
-F 'links=[{"targetType":"project","targetId":"01HQXXXXXXXXXXXXXXXXXXXXXX"}]'
Workspace Id (string) or Workspace Id (null) (Workspace Id) Optional workspace ID to link file to |
| file required | string <binary> (File) |
Name (string) or Name (null) (Name) | |
Mime (string) or Mime (null) (Mime) | |
| links | string (Links) Default: "[]" JSON array of links: [{"targetType":"project","targetId":"..."}] |
{- "id": "string",
- "owner_user_id": "string",
- "name": "string",
- "ext": "string",
- "mime": "string",
- "size_bytes": 0,
- "sha256": "string",
- "is_document": true,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}List files by context or filters.
Supports two modes:
filter[targetType] accepts: workspace, project, wbs, task
Context (string) or Context (null) (Context) Deprecated | |
Id (string) or Id (null) (Id) Deprecated | |
Filter[Workspaceid] (string) or Filter[Workspaceid] (null) (Filter[Workspaceid]) | |
Filter[Projectid] (string) or Filter[Projectid] (null) (Filter[Projectid]) | |
FileTargetType (string) or Filter[Targettype] (null) (Filter[Targettype]) Filter by target type: workspace, project, wbs, task | |
Filter[Targetid] (string) or Filter[Targetid] (null) (Filter[Targetid]) | |
Search (string) or Search (null) (Search) | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "id": "string",
- "owner_user_id": "string",
- "name": "string",
- "ext": "string",
- "mime": "string",
- "size_bytes": 0,
- "sha256": "string",
- "is_document": true,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Get file metadata
| file_id required | string (File Id) |
{- "id": "string",
- "owner_user_id": "string",
- "name": "string",
- "ext": "string",
- "mime": "string",
- "size_bytes": 0,
- "sha256": "string",
- "is_document": true,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Update file metadata (rename file).
Only the owner or users with editor role can update file metadata.
| file_id required | string (File Id) |
| name required | string (Name) non-empty New filename |
{- "name": "string"
}{- "id": "string",
- "owner_user_id": "string",
- "name": "string",
- "ext": "string",
- "mime": "string",
- "size_bytes": 0,
- "sha256": "string",
- "is_document": true,
- "created_at": "2025-10-09T14:30:00Z",
- "updated_at": "2025-10-09T14:30:00Z"
}Upload a new version of an existing file.
Creates a new version while preserving the original file metadata (name, links, etc.). The file content is stored separately and can be accessed via version history.
| file_id required | string (File Id) |
| file required | string <binary> (File) |
Comment (string) or Comment (null) (Comment) |
{- "id": "string",
- "file_id": "string",
- "version_number": 0,
- "sha256": "string",
- "storage_path": "string",
- "size_bytes": 0,
- "uploaded_by": "string",
- "comment": "string",
- "created_at": "2025-10-09T14:30:00Z"
}List all versions of a file with pagination.
Returns versions in descending order (newest first).
| file_id required | string (File Id) |
| size | integer (Size) [ 1 .. 200 ] Default: 50 |
After (string) or After (null) (After) |
{- "data": [
- {
- "id": "string",
- "file_id": "string",
- "version_number": 0,
- "sha256": "string",
- "storage_path": "string",
- "size_bytes": 0,
- "uploaded_by": "string",
- "comment": "string",
- "created_at": "2025-10-09T14:30:00Z"
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Get document state (latest snapshot).
Returns the current collaborative document state with version information.
| file_id required | string (File Id) |
{- "file_id": "01HQXXXXXXXXXXXXXXXXXXXXXX",
- "size_bytes": 15420,
- "snapshot_id": "v42",
- "updated_at": "2025-10-09T14:30:00Z"
}Export document to various formats (PDF, Markdown, DOCX).
Note: This is a stub implementation. Returns a placeholder response.
| file_id required | string (File Id) |
| format required | string (Format) Enum: "pdf" "md" "docx" Export format |
{- "format": "pdf"
}{- "expires_at": "2025-10-09T15:30:00Z",
- "format": "pdf",
- "size_bytes": 245678,
}Full-text search across tasks, files, docs, and other entities.
Supports filtering by entity type and context (workspace or project). Results are filtered by user access permissions.
Uses cursor-based pagination with ULID cursors.
| q required | string (Q) Search query |
Filter[Entity] (string) or Filter[Entity] (null) (Filter[Entity]) Filter by entity type: workspace, project, wbs, task, doc | |
Context (string) or Context (null) (Context) Deprecated Context type: workspace, project | |
Id (string) or Id (null) (Id) Deprecated Context ID | |
| page[size] | integer (Page[Size]) [ 1 .. 200 ] Default: 50 |
Page[After] (string) or Page[After] (null) (Page[After]) |
{- "data": [
- {
- "entity_type": "string",
- "entity_id": "string",
- "title": "string",
- "snippet": "string",
- "rank": 0
}
], - "pagination": {
- "next_cursor": "string",
- "has_more": false,
- "size": 0
}
}Generate task breakdown for a WBS node using AI.
Analyzes the WBS description and suggests tasks with effort estimates.
Rate Limiting: This endpoint is rate-limited. If you exceed the limit, you'll receive a 429 response with a Retry-After header indicating when to retry.
| wbs_id required | string (Wbs Id) WBS node ID to break down into tasks |
Description (string) or Description (null) (Description) Additional description or context |
{- "wbs_id": "string",
- "description": "string"
}{- "tasks": [
- {
- "title": "string",
- "description": "string",
- "estimate_hours": 0.1
}, - {
- "title": "string",
- "description": "string",
- "estimate_hours": 0.1
}, - {
- "title": "string",
- "description": "string",
- "estimate_hours": 0.1
}
], - "wbs_id": "string"
}Generate AI suggestions for improving a task.
Analyzes the task and provides suggestions for improvement.
Rate Limiting: This endpoint is rate-limited. If you exceed the limit, you'll receive a 429 response with a Retry-After header indicating when to retry.
| task_id required | string (Task Id) Task ID to analyze |
Context (string) or Context (null) (Context) Additional context for suggestions |
{- "task_id": "string",
- "context": "string"
}{- "suggestions": [
- "string",
- "string"
], - "task_id": "string"
}Generate effort estimate for a task using AI.
Analyzes the task complexity and provides an estimated duration with confidence level and reasoning.
Rate Limiting: This endpoint is rate-limited. If you exceed the limit, you'll receive a 429 response with a Retry-After header indicating when to retry.
| title required | string (Title) [ 1 .. 200 ] characters |
Description (string) or Description (null) (Description) | |
Array of Subtasks (strings) or Subtasks (null) (Subtasks) List of subtask titles | |
Context (string) or Context (null) (Context) |
{- "title": "string",
- "description": "string",
- "subtasks": [
- "string"
], - "context": "string"
}{- "estimate_hours": 0.1,
- "confidence": "string",
- "reasoning": "string",
- "breakdown": {
- "property1": 0,
- "property2": 0
}
}Generate Work Breakdown Structure for a project using AI.
Analyzes the project description and generates a hierarchical WBS with appropriate groups and work packages.
Rate Limiting: This endpoint is rate-limited. If you exceed the limit, you'll receive a 429 response with a Retry-After header indicating when to retry.
| project_name required | string (Project Name) non-empty |
| project_description required | string (Project Description) non-empty |
Project Type (string) or Project Type (null) (Project Type) software, construction, event, etc. | |
Array of Phases (strings) or Phases (null) (Phases) Suggested project phases |
{- "project_name": "string",
- "project_description": "string",
- "project_type": "string",
- "phases": [
- "string"
]
}{- "nodes": [
- {
- "name": "string",
- "type": "string",
- "description": "string",
- "parent_path": "string",
- "estimate_hours": 0
}
], - "reasoning": "string"
}Get AI service status and configuration.
Returns information about AI availability and current model.
{- "available": true,
- "enabled": true,
- "features": {
- "task_breakdown": true,
- "task_estimation": true,
- "wbs_generation": true
}, - "model": "mistral-small-latest",
- "provider": "Mistral AI"
}Get API metadata and feature flags.
Returns version, environment, and feature availability.
{- "version": "string",
- "env": "string",
- "database": "string",
- "fts": "string",
- "features": {
- "property1": "string",
- "property2": "string"
}, - "views": [
- "string"
]
}