Projects API

REST endpoints for the Projects module — projects, sprints, tasks, time entries.

Endpoints

MethodPathPurpose
GET/api/projectsList projects. Filters: status, owner_id, q.
POST/api/projectsCreate.
GET/PATCH/DELETE/api/projects/{id}CRUD.
GET/api/projects/{id}/sprintsList sprints for a project.
POST/api/projects/{id}/sprintsCreate a sprint.
PATCH/api/projects/{id}/sprints/{sprintId}Update (status transitions emit `projects.sprint.started
GET/api/projects/{id}/tasksList tasks. Filters: status, assigned_to, sprint_id, parent_id.
POST/api/projects/{id}/tasksCreate.
GET/PATCH/DELETE/api/projects/{id}/tasks/{taskId}CRUD.
POST/api/projects/{id}/tasks/reorderBulk reorder cards on the kanban.
GET/api/projects/{id}/time-entriesList time entries. Filters: user_id, task_id, date range.
POST/api/projects/{id}/time-entriesLog time.
GET/api/projects/{id}/time-entries/runningCurrently-running timer for the caller.

Key entity shapes

Task

{
  "id": "uuid",
  "tenant_id": "uuid",
  "project_id": "uuid",
  "sprint_id": "uuid?",
  "title": "string",
  "description": "string?",
  "status": "todo | in_progress | review | done",
  "assigned_to": "uuid?",
  "story_points": 0,
  "position": 0,
  "parent_id": "uuid?"
}

Sprint

{
  "id": "uuid",
  "project_id": "uuid",
  "name": "string",
  "goal": "string?",
  "status": "planning | active | completed",
  "start_date": "iso-8601",
  "end_date": "iso-8601",
  "capacity_points": 0
}

Permissions

Seeded slugs: projects.projects.read|create|update|delete, projects.tasks.read|create|update|delete. Sprint and time-entry endpoints gate on projects.projects.* + projects.tasks.* overlays — there are no separate seeded slugs for them. Project membership (owner/manager/member/viewer) is an additional overlay that further restricts access per project.

Events

  • projects.project.created|updated|deleted
  • projects.task.created|updated|completed|deleted
  • projects.sprint.started|completed

OpenAPI

Full schema at /api/openapi.json.