{
 "openapi": "3.0.3",
 "info": {
  "title": "Bramble Projects API",
  "version": "2026-11-13",
  "description": "Bramble Projects: projects and their members and invites, work packages (tasks) with types, statuses and categories, documents, automation rules, notifications and \"my work\" across projects. Works with an API key.\n"
 },
 "servers": [
  {
   "url": "https://{org}.brambleit.cloud/api",
   "variables": {
    "org": {
     "default": "your-org"
    }
   }
  }
 ],
 "components": {
  "securitySchemes": {
   "apiKey": {
    "type": "apiKey",
    "in": "header",
    "name": "X-API-Key"
   },
   "session": {
    "type": "apiKey",
    "in": "cookie",
    "name": "sso_session"
   },
   "bearer": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "JWT"
   }
  }
 },
 "tags": [
  {
   "name": "Projects",
   "description": "Projects themselves (banner, icon, activity), your work across projects, and search."
  },
  {
   "name": "Work packages",
   "description": "The tasks in a project, with relations between them and their history."
  },
  {
   "name": "Members",
   "description": "Who's in a project and their role, and inviting people."
  },
  {
   "name": "Statuses",
   "description": "A project's workflow states."
  },
  {
   "name": "Types",
   "description": "Kinds of work package (task, bug, milestone…)."
  },
  {
   "name": "Categories & tags",
   "description": "Categories and tags for grouping work."
  },
  {
   "name": "Documents",
   "description": "Documents attached to a project."
  },
  {
   "name": "Automation rules",
   "description": "Rules that change work packages automatically when something happens."
  },
  {
   "name": "Notifications",
   "description": "Your Projects notifications."
  },
  {
   "name": "Admin",
   "description": "Projects administration and image uploads."
  }
 ],
 "paths": {
  "/v1/app/project/images/{id}": {
   "get": {
    "tags": [
     "Admin"
    ],
    "summary": "Fetch a project image (icon/banner/comment attachment) by id",
    "operationId": "get-v1-app-project-images-id",
    "description": "Fetch a project image (icon/banner/comment attachment) by id. Public endpoint, no authentication required — used directly as an `<img>` src. Registered before the license gate so it is never covered by it.\n\nRequires: None: public, or protected by a token in the address or body.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "File, page or redirect"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects": {
   "get": {
    "tags": [
     "Projects"
    ],
    "summary": "List projects the caller is a member of",
    "operationId": "get-v1-app-project-projects",
    "description": "List projects the caller is a member of. Returns every project in the caller's tenant they belong to, with member and task counts.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "projects": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "tenant_id": {
              "type": "integer"
             },
             "client_id": {
              "type": "integer",
              "nullable": true
             },
             "name": {
              "type": "string"
             },
             "slug": {
              "type": "string"
             },
             "public_id": {
              "type": "string"
             },
             "description": {
              "type": "string",
              "nullable": true
             },
             "color": {
              "type": "string",
              "nullable": true
             },
             "icon_image_id": {
              "type": "integer",
              "nullable": true
             },
             "banner_image_id": {
              "type": "integer",
              "nullable": true
             },
             "status": {
              "type": "string",
              "enum": [
               "active",
               "archived"
              ]
             },
             "created_by": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "updated_at": {
              "type": "string",
              "format": "date-time"
             },
             "archived_at": {
              "type": "string",
              "format": "date-time",
              "nullable": true
             },
             "my_role": {
              "type": "string",
              "enum": [
               "owner",
               "admin",
               "member",
               "viewer"
              ]
             },
             "member_count": {
              "type": "boolean"
             },
             "task_count": {
              "type": "boolean"
             },
             "open_count": {
              "type": "boolean"
             },
             "overdue_count": {
              "type": "boolean"
             }
            }
           }
          },
          "me": {}
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Projects"
    ],
    "summary": "Create a project. Creator becomes owner; seeds the project with default work-package types and statuses",
    "operationId": "post-v1-app-project-projects",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "project": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "description": {
          "type": "string"
         },
         "color": {}
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}": {
   "get": {
    "tags": [
     "Projects"
    ],
    "summary": "Get a single project",
    "operationId": "get-v1-app-project-projects-id",
    "description": "Get a single project. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "project": {},
          "my_role": {}
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "patch": {
    "tags": [
     "Projects"
    ],
    "summary": "Update a project's name/description/color/status/client",
    "operationId": "patch-v1-app-project-projects-id",
    "description": "Update a project's name/description/color/status/client. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "project": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "description": {
          "type": "string"
         },
         "color": {},
         "status": {
          "type": "string",
          "enum": [
           "active",
           "archived"
          ]
         },
         "client_id": {
          "type": "integer"
         }
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Projects"
    ],
    "summary": "Delete a project. Requires owner role on the project",
    "operationId": "delete-v1-app-project-projects-id",
    "description": "Delete a project. Requires owner role on the project. Cascades to all project_* rows via FK, plus explicit cleanup of comments/notifications.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/my-work": {
   "get": {
    "tags": [
     "Projects"
    ],
    "summary": "List work packages assigned to the caller across every project in their tenant",
    "operationId": "get-v1-app-project-my-work",
    "description": "List work packages assigned to the caller across every project in their tenant. Closed items are hidden by default.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "include_closed",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_packages": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "subject": {
              "type": "string"
             },
             "priority": {
              "type": "string",
              "enum": [
               "low",
               "medium",
               "high",
               "urgent"
              ]
             },
             "start_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "due_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "percent_done": {
              "type": "integer"
             },
             "status_id": {
              "type": "integer"
             },
             "type_id": {
              "type": "integer"
             },
             "project_name": {
              "type": "string"
             },
             "project_public_id": {
              "type": "string"
             },
             "project_color": {
              "type": "string",
              "nullable": true
             },
             "status_name": {
              "type": "string"
             },
             "status_color": {
              "type": "string"
             },
             "status_is_closed": {
              "type": "boolean"
             },
             "type_name": {
              "type": "string"
             },
             "type_color": {
              "type": "string"
             },
             "type_icon": {
              "type": "string"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/search": {
   "get": {
    "tags": [
     "Projects"
    ],
    "summary": "Search work packages by subject across every project the caller belongs to",
    "operationId": "get-v1-app-project-search",
    "description": "Search work packages by subject across every project the caller belongs to. Search text matched against work package subject\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {}
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_packages": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/notifications": {
   "get": {
    "tags": [
     "Notifications"
    ],
    "summary": "List the caller's cross-project notifications",
    "operationId": "get-v1-app-project-notifications",
    "description": "List the caller's cross-project notifications. Pass \"1\" or \"true\" to only return unread notifications\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "unread_only",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "notifications": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "work_package_id": {
              "type": "integer",
              "nullable": true
             },
             "user_id": {
              "type": "integer"
             },
             "actor_user_id": {
              "type": "integer",
              "nullable": true
             },
             "type": {
              "type": "string",
              "enum": [
               "assigned",
               "comment",
               "mention",
               "status_change"
              ]
             },
             "is_read": {
              "type": "boolean"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "project_name": {
              "type": "string"
             },
             "project_public_id": {
              "type": "string"
             },
             "work_package_subject": {
              "type": "string"
             },
             "actor": {}
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/notifications/unread-count": {
   "get": {
    "tags": [
     "Notifications"
    ],
    "summary": "Get the caller's unread notification count",
    "operationId": "get-v1-app-project-notifications-unread-count",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "count": {
           "type": "integer"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/notifications/{id}/read": {
   "patch": {
    "tags": [
     "Notifications"
    ],
    "summary": "Mark a notification as read",
    "operationId": "patch-v1-app-project-notifications-id-read",
    "description": "Mark a notification as read. Notification ID\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/notifications/read-all": {
   "post": {
    "tags": [
     "Notifications"
    ],
    "summary": "Mark all of the caller's notifications as read",
    "operationId": "post-v1-app-project-notifications-read-all",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/icon": {
   "post": {
    "tags": [
     "Projects"
    ],
    "summary": "Upload a project's icon image",
    "operationId": "post-v1-app-project-projects-id-icon",
    "description": "Upload a project's icon image. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "delete": {
    "tags": [
     "Projects"
    ],
    "summary": "Clear a project's icon image",
    "operationId": "delete-v1-app-project-projects-id-icon",
    "description": "Clear a project's icon image. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/banner": {
   "post": {
    "tags": [
     "Projects"
    ],
    "summary": "Upload a project's banner image",
    "operationId": "post-v1-app-project-projects-id-banner",
    "description": "Upload a project's banner image. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "delete": {
    "tags": [
     "Projects"
    ],
    "summary": "Clear a project's banner image",
    "operationId": "delete-v1-app-project-projects-id-banner",
    "description": "Clear a project's banner image. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/members": {
   "get": {
    "tags": [
     "Members"
    ],
    "summary": "List a project's members",
    "operationId": "get-v1-app-project-projects-id-members",
    "description": "List a project's members. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "members": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/available-users": {
   "get": {
    "tags": [
     "Members"
    ],
    "summary": "List tenant users not yet on this project",
    "operationId": "get-v1-app-project-projects-id-available-users",
    "description": "List tenant users not yet on this project. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "users": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/members/{userId}": {
   "patch": {
    "tags": [
     "Members"
    ],
    "summary": "Change a project member's role",
    "operationId": "patch-v1-app-project-projects-id-members-userid",
    "description": "Change a project member's role. Requires at least admin role on the project. Refuses to demote the last remaining owner.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "userId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid role"
     },
     "404": {
      "description": "Member not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "role": {
          "type": "string"
         }
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Members"
    ],
    "summary": "Remove a project member, or leave the project yourself",
    "operationId": "delete-v1-app-project-projects-id-members-userid",
    "description": "Remove a project member, or leave the project yourself. Requires viewer role when removing yourself, admin role otherwise. Refuses to remove the last remaining owner.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "userId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Project must keep at least one owner"
     },
     "404": {
      "description": "Member not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/invites": {
   "get": {
    "tags": [
     "Members"
    ],
    "summary": "List a project's pending invites",
    "operationId": "get-v1-app-project-projects-id-invites",
    "description": "List a project's pending invites. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "invites": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Members"
    ],
    "summary": "Invite an existing tenant user to a project",
    "operationId": "post-v1-app-project-projects-id-invites",
    "description": "Invite an existing tenant user to a project. Requires at least admin role on the project. The invited user must already exist in the caller's tenant (staff or guest, active).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "integer"
          },
          "token": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "user_id is required"
     },
     "404": {
      "description": "User not found in your organisation"
     },
     "409": {
      "description": "User is already a project member"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "user_id": {
          "type": "integer"
         },
         "role": {}
        },
        "required": [
         "user_id"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/invites/{inviteId}": {
   "delete": {
    "tags": [
     "Members"
    ],
    "summary": "Revoke a pending project invite",
    "operationId": "delete-v1-app-project-projects-id-invites-inviteid",
    "description": "Revoke a pending project invite. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "inviteId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/invites": {
   "get": {
    "tags": [
     "Members"
    ],
    "summary": "List pending invites addressed to the caller",
    "operationId": "get-v1-app-project-invites",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "invites": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/invites/{id}/accept": {
   "post": {
    "tags": [
     "Members"
    ],
    "summary": "Accept a pending project invite",
    "operationId": "post-v1-app-project-invites-id-accept",
    "description": "Accept a pending project invite. Invite ID\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "project_id": {
           "type": "integer"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Invite not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/invites/{id}/decline": {
   "post": {
    "tags": [
     "Members"
    ],
    "summary": "Decline a pending project invite",
    "operationId": "post-v1-app-project-invites-id-decline",
    "description": "Decline a pending project invite. Invite ID\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Invite not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/categories": {
   "get": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "List a project's work-package categories",
    "operationId": "get-v1-app-project-projects-id-categories",
    "description": "List a project's work-package categories. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "categories": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "color": {
              "type": "string"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Create a work-package category",
    "operationId": "post-v1-app-project-projects-id-categories",
    "description": "Create a work-package category. Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "category": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {}
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/categories/{catId}": {
   "patch": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Update a work-package category",
    "operationId": "patch-v1-app-project-projects-id-categories-catid",
    "description": "Update a work-package category. Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "catId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "category": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {}
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Delete a work-package category",
    "operationId": "delete-v1-app-project-projects-id-categories-catid",
    "description": "Delete a work-package category. Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "catId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/types": {
   "get": {
    "tags": [
     "Types"
    ],
    "summary": "List a project's work-package types",
    "operationId": "get-v1-app-project-projects-id-types",
    "description": "List a project's work-package types. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "types": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "color": {
              "type": "string"
             },
             "icon": {
              "type": "string"
             },
             "is_milestone": {
              "type": "boolean"
             },
             "position": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Types"
    ],
    "summary": "Create a work-package type",
    "operationId": "post-v1-app-project-projects-id-types",
    "description": "Create a work-package type. Requires at least admin role on the project. Appended to the end of the type list.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "type": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {},
         "icon": {},
         "is_milestone": {
          "type": "boolean"
         }
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/types/{typeId}": {
   "patch": {
    "tags": [
     "Types"
    ],
    "summary": "Update a work-package type",
    "operationId": "patch-v1-app-project-projects-id-types-typeid",
    "description": "Update a work-package type. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "typeId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "type": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {},
         "icon": {},
         "is_milestone": {
          "type": "boolean"
         },
         "position": {
          "type": "integer"
         }
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Types"
    ],
    "summary": "Delete a work-package type",
    "operationId": "delete-v1-app-project-projects-id-types-typeid",
    "description": "Delete a work-package type. Requires at least admin role on the project. Refused if any non-deleted work package still uses this type.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "typeId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "409": {
      "description": "Re-type or delete work packages using this type first"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/statuses": {
   "get": {
    "tags": [
     "Statuses"
    ],
    "summary": "List a project's statuses (also used as the Board's columns)",
    "operationId": "get-v1-app-project-projects-id-statuses",
    "description": "List a project's statuses (also used as the Board's columns). Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "statuses": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "position": {
              "type": "integer"
             },
             "color": {
              "type": "string"
             },
             "is_default": {
              "type": "boolean"
             },
             "is_closed": {
              "type": "boolean"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Statuses"
    ],
    "summary": "Create a status/board column",
    "operationId": "post-v1-app-project-projects-id-statuses",
    "description": "Create a status/board column. Requires at least admin role on the project. Appended to the end of the status list; setting is_default unsets it on every other status.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {},
         "is_closed": {
          "type": "boolean"
         },
         "is_default": {
          "type": "boolean"
         }
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/statuses/{statusId}": {
   "patch": {
    "tags": [
     "Statuses"
    ],
    "summary": "Update a status/board column",
    "operationId": "patch-v1-app-project-projects-id-statuses-statusid",
    "description": "Update a status/board column. Requires at least admin role on the project. Setting is_default unsets it on every other status.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "statusId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {},
         "position": {
          "type": "integer"
         },
         "is_closed": {
          "type": "boolean"
         },
         "is_default": {
          "type": "boolean"
         }
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Statuses"
    ],
    "summary": "Delete a status/board column",
    "operationId": "delete-v1-app-project-projects-id-statuses-statusid",
    "description": "Delete a status/board column. Requires at least admin role on the project. Refused if any non-deleted work package is still in this status.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "statusId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "409": {
      "description": "Move or delete work packages in this status first"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/versions": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "List a project's versions (Roadmap)",
    "operationId": "get-v1-app-project-projects-id-versions",
    "description": "List a project's versions (Roadmap). Requires at least viewer role on the project. Each version includes open_count/closed_count of its work packages.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "versions": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "description": {
              "type": "string",
              "nullable": true
             },
             "start_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "due_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "status": {
              "type": "string",
              "enum": [
               "open",
               "locked",
               "closed"
              ]
             },
             "position": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "open_count": {
              "type": "number"
             },
             "closed_count": {
              "type": "number"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Work packages"
    ],
    "summary": "Create a version/roadmap milestone",
    "operationId": "post-v1-app-project-projects-id-versions",
    "description": "Create a version/roadmap milestone. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "version": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "description": {
          "type": "string"
         },
         "start_date": {
          "type": "string",
          "format": "date"
         },
         "due_date": {
          "type": "string",
          "format": "date"
         },
         "status": {
          "type": "string"
         }
        },
        "required": [
         "name"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/versions/{versionId}": {
   "patch": {
    "tags": [
     "Work packages"
    ],
    "summary": "Update a version/roadmap milestone",
    "operationId": "patch-v1-app-project-projects-id-versions-versionid",
    "description": "Update a version/roadmap milestone. Requires at least admin role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "versionId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "version": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid status"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "description": {
          "type": "string"
         },
         "start_date": {
          "type": "string",
          "format": "date"
         },
         "due_date": {
          "type": "string",
          "format": "date"
         },
         "status": {
          "type": "string"
         },
         "position": {
          "type": "integer"
         }
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Work packages"
    ],
    "summary": "Delete a version/roadmap milestone",
    "operationId": "delete-v1-app-project-projects-id-versions-versionid",
    "description": "Delete a version/roadmap milestone. Requires at least admin role on the project. Work packages referencing this version are unset (version_id set to null), not deleted.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "versionId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/tags": {
   "get": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "List a project's tags",
    "operationId": "get-v1-app-project-projects-id-tags",
    "description": "List a project's tags. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "tags": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "color": {
              "type": "string"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Create a work-package tag",
    "operationId": "post-v1-app-project-projects-id-tags",
    "description": "Create a work-package tag. Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "tag": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {}
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/tags/{tagId}": {
   "patch": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Rename or recolor a tag",
    "operationId": "patch-v1-app-project-projects-id-tags-tagid",
    "description": "Rename or recolor a tag. Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "tagId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "tag": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "color": {}
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Categories & tags"
    ],
    "summary": "Delete a tag. Requires at least member role on the project",
    "operationId": "delete-v1-app-project-projects-id-tags-tagid",
    "description": "Delete a tag. Requires at least member role on the project. Also removes it from every work package it's attached to (no FK cascade — see the migration file's comment on why).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "tagId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/automation-rules": {
   "get": {
    "tags": [
     "Automation rules"
    ],
    "summary": "A project's automation rules",
    "operationId": "get-v1-app-project-projects-id-automation-rules",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "rules": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "name": {
              "type": "string"
             },
             "enabled": {
              "type": "boolean"
             },
             "conditions": {
              "type": "object"
             },
             "actions": {
              "type": "object"
             },
             "position": {
              "type": "integer"
             },
             "created_by": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "updated_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Automation rules"
    ],
    "summary": "Admin role: higher than Tags'/ Categories' \"member\" tier, since a rule can auto-assign users or change status on every new work package, same tier as project…",
    "operationId": "post-v1-app-project-projects-id-automation-rules",
    "description": "Admin role: higher than Tags'/ Categories' \"member\" tier, since a rule can auto-assign users or change status on every new work package, same tier as project settings changes.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "rule": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "conditions": {
          "type": "array",
          "items": {}
         },
         "actions": {
          "type": "array",
          "items": {}
         }
        },
        "required": [
         "name"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/automation-rules/{ruleId}": {
   "put": {
    "tags": [
     "Automation rules"
    ],
    "summary": "Bulk-replace name/conditions/ actions in one UPDATE (no transaction needed — see the JSON-column rationale above)",
    "operationId": "put-v1-app-project-projects-id-automation-rules-ruleid",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "ruleId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "rule": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "enabled": {
          "type": "boolean"
         },
         "conditions": {
          "type": "array",
          "items": {}
         },
         "actions": {
          "type": "array",
          "items": {}
         }
        },
        "required": [
         "name"
        ]
       }
      }
     }
    }
   },
   "patch": {
    "tags": [
     "Automation rules"
    ],
    "summary": "Just the enable/disable toggle, kept separate from PUT so the list view's switch doesn't have to resend the whole conditions/actions payload",
    "operationId": "patch-v1-app-project-projects-id-automation-rules-ruleid",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "ruleId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "rule": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "enabled is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean"
         }
        },
        "required": [
         "enabled"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Automation rules"
    ],
    "summary": "Delete an automation rule",
    "operationId": "delete-v1-app-project-projects-id-automation-rules-ruleid",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "ruleId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/work-packages": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "List a project's work packages",
    "operationId": "get-v1-app-project-projects-id-work-packages",
    "description": "List a project's work packages. Requires at least viewer role on the project. Shared by the Board, Work Packages table, and Gantt views. Supports filtering.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "status_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "category_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "type_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "version_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "priority",
      "in": "query",
      "required": false,
      "schema": {}
     },
     {
      "name": "assignee",
      "in": "query",
      "required": false,
      "schema": {}
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_packages": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "type_id": {
              "type": "integer"
             },
             "status_id": {
              "type": "integer"
             },
             "parent_id": {
              "type": "integer",
              "nullable": true
             },
             "version_id": {
              "type": "integer",
              "nullable": true
             },
             "category_id": {
              "type": "integer",
              "nullable": true
             },
             "subject": {
              "type": "string"
             },
             "description": {
              "type": "string",
              "nullable": true
             },
             "priority": {
              "type": "string",
              "enum": [
               "low",
               "medium",
               "high",
               "urgent"
              ]
             },
             "start_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "due_date": {
              "type": "string",
              "format": "date",
              "nullable": true
             },
             "percent_done": {
              "type": "integer"
             },
             "position": {
              "type": "integer"
             },
             "created_by": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "updated_at": {
              "type": "string",
              "format": "date-time"
             },
             "completed_at": {
              "type": "string",
              "format": "date-time",
              "nullable": true
             },
             "deleted_at": {
              "type": "string",
              "format": "date-time",
              "nullable": true
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Work packages"
    ],
    "summary": "Create a work package",
    "operationId": "post-v1-app-project-projects-id-work-packages",
    "description": "Create a work package. Requires at least member role on the project. Falls back to the project's first non-milestone type and default status if not specified.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_package": {
           "type": "object",
           "properties": {
            "tag_ids": {
             "type": "array",
             "items": {
              "type": "integer"
             }
            },
            "assignee_ids": {
             "type": "array",
             "items": {
              "type": "integer"
             }
            }
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "subject is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "subject": {
          "type": "string"
         },
         "description": {
          "type": "string"
         },
         "type_id": {
          "type": "integer"
         },
         "status_id": {
          "type": "integer"
         },
         "parent_id": {
          "type": "integer"
         },
         "version_id": {
          "type": "integer"
         },
         "category_id": {
          "type": "integer"
         },
         "priority": {},
         "start_date": {
          "type": "string",
          "format": "date"
         },
         "due_date": {
          "type": "string",
          "format": "date"
         },
         "percent_done": {
          "type": "number"
         },
         "assignee_ids": {
          "type": "array",
          "items": {}
         },
         "tag_ids": {
          "type": "array",
          "items": {}
         }
        },
        "required": [
         "subject"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "Get a single work package",
    "operationId": "get-v1-app-project-projects-id-work-packages-wpid",
    "description": "Get a single work package. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_package": {
           "type": "object",
           "properties": {
            "assignee_ids": {
             "type": "array",
             "items": {
              "type": "integer"
             }
            },
            "tag_ids": {
             "type": "array",
             "items": {
              "type": "integer"
             }
            }
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Work package not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "patch": {
    "tags": [
     "Work packages"
    ],
    "summary": "Update a work package",
    "operationId": "patch-v1-app-project-projects-id-work-packages-wpid",
    "description": "Update a work package. Requires at least member role on the project. Reassigning triggers \"assigned\" notifications for newly-added assignees; changing status_id notifies current assignees of the status change. Rejects a parent_id change that would create a circular hierarchy.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "work_package": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid priority"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "subject": {},
         "description": {
          "type": "string"
         },
         "type_id": {
          "type": "integer"
         },
         "status_id": {
          "type": "integer"
         },
         "category_id": {
          "type": "integer"
         },
         "version_id": {
          "type": "integer"
         },
         "priority": {},
         "start_date": {
          "type": "string",
          "format": "date"
         },
         "due_date": {
          "type": "string",
          "format": "date"
         },
         "percent_done": {
          "type": "number"
         },
         "assignee_ids": {
          "type": "array",
          "items": {}
         },
         "tag_ids": {
          "type": "array",
          "items": {}
         },
         "completed": {},
         "parent_id": {
          "type": "integer"
         }
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Work packages"
    ],
    "summary": "Delete a work package (soft delete)",
    "operationId": "delete-v1-app-project-projects-id-work-packages-wpid",
    "description": "Delete a work package (soft delete). Requires at least member role on the project. Children are reparented to top-level first.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}/move": {
   "patch": {
    "tags": [
     "Work packages"
    ],
    "summary": "Move a work package between statuses/positions (Board drag-drop / reorder)",
    "operationId": "patch-v1-app-project-projects-id-work-packages-wpid-move",
    "description": "Move a work package between statuses/positions (Board drag-drop / reorder). Requires at least member role on the project. Notifies current assignees of the status change.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "status_id and position are required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "status_id": {
          "type": "integer"
         },
         "position": {
          "type": "integer"
         },
         "order": {
          "type": "array",
          "items": {}
         }
        },
        "required": [
         "status_id",
         "position"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/relations": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "List every work-package relation edge in the project",
    "operationId": "get-v1-app-project-projects-id-relations",
    "description": "List every work-package relation edge in the project. Requires at least viewer role on the project. Used by the Gantt view to draw dependency arrows without an N+1 fetch per work package.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "relations": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "work_package_id": {
              "type": "integer"
             },
             "related_work_package_id": {
              "type": "integer"
             },
             "relation_type": {
              "type": "string",
              "enum": [
               "relates",
               "blocks",
               "blocked_by",
               "precedes",
               "follows",
               "duplicates",
               "duplicated_by"
              ]
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}/relations": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "List a single work package's relations",
    "operationId": "get-v1-app-project-projects-id-work-packages-wpid-relations",
    "description": "List a single work package's relations. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "relations": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "work_package_id": {
              "type": "integer"
             },
             "related_work_package_id": {
              "type": "integer"
             },
             "relation_type": {
              "type": "string",
              "enum": [
               "relates",
               "blocks",
               "blocked_by",
               "precedes",
               "follows",
               "duplicates",
               "duplicated_by"
              ]
             },
             "created_by": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "related_subject": {
              "type": "string"
             },
             "related_status_id": {
              "type": "integer"
             },
             "related_type_id": {
              "type": "integer"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Work packages"
    ],
    "summary": "Create a relation between two work packages",
    "operationId": "post-v1-app-project-projects-id-work-packages-wpid-relations",
    "description": "Create a relation between two work packages. Requires at least member role on the project. Also creates the inverse relation on the related work package (e.g. blocks/blocked_by).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "related_id is required and must differ from the work package"
     },
     "404": {
      "description": "Related work package not found"
     },
     "409": {
      "description": "That relation already exists"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "related_id": {
          "type": "string"
         },
         "relation_type": {
          "type": "string"
         }
        },
        "required": [
         "related_id"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}/relations/{relId}": {
   "delete": {
    "tags": [
     "Work packages"
    ],
    "summary": "Delete a work-package relation",
    "operationId": "delete-v1-app-project-projects-id-work-packages-wpid-relations-relid",
    "description": "Delete a work-package relation. Requires at least member role on the project. Also deletes the corresponding inverse relation.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "relId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Relation not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}/comments": {
   "get": {
    "tags": [
     "Work packages"
    ],
    "summary": "List a work package's comments",
    "operationId": "get-v1-app-project-projects-id-work-packages-wpid-comments",
    "description": "List a work package's comments. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "comments": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Work packages"
    ],
    "summary": "Add a comment to a work package",
    "operationId": "post-v1-app-project-projects-id-work-packages-wpid-comments",
    "description": "Add a comment to a work package. Requires at least member role on the project. Notifies assignees/creator (\"comment\") and any valid @mentioned project members (\"mention\", which takes priority).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "comment": {
           "type": "object",
           "properties": {
            "user": {}
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "body is required"
     },
     "404": {
      "description": "Work package not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "body": {
          "type": "string"
         },
         "mentioned_user_ids": {
          "type": "array",
          "items": {}
         }
        },
        "required": [
         "body"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/work-packages/{wpId}/comments/{commentId}": {
   "patch": {
    "tags": [
     "Work packages"
    ],
    "summary": "Edit a work-package comment",
    "operationId": "patch-v1-app-project-projects-id-work-packages-wpid-comments-commentid",
    "description": "Edit a work-package comment. Requires at least viewer role on the project to reach the check, but only the comment's author may actually edit it.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "commentId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "comment": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "body is required"
     },
     "403": {
      "description": "You can only edit your own comments"
     },
     "404": {
      "description": "Comment not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "body": {
          "type": "string"
         }
        },
        "required": [
         "body"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Work packages"
    ],
    "summary": "Delete a work-package comment (soft delete)",
    "operationId": "delete-v1-app-project-projects-id-work-packages-wpid-comments-commentid",
    "description": "Delete a work-package comment (soft delete). Requires at least viewer role on the project to reach the check; the comment's author or an admin+ may delete it.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "wpId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "commentId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "403": {
      "description": "Insufficient permissions"
     },
     "404": {
      "description": "Comment not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/documents": {
   "get": {
    "tags": [
     "Documents"
    ],
    "summary": "List a project's documents (Wiki)",
    "operationId": "get-v1-app-project-projects-id-documents",
    "description": "List a project's documents (Wiki). Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "documents": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "parent_id": {
              "type": "integer",
              "nullable": true
             },
             "title": {
              "type": "string"
             },
             "position": {
              "type": "integer"
             },
             "created_by": {
              "type": "integer"
             },
             "updated_by": {
              "type": "integer",
              "nullable": true
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "updated_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Documents"
    ],
    "summary": "Create a document. Requires at least member role on the project",
    "operationId": "post-v1-app-project-projects-id-documents",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "document": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "title is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "title": {
          "type": "string"
         },
         "content": {},
         "parent_id": {
          "type": "integer"
         }
        },
        "required": [
         "title"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/project/projects/{id}/documents/{docId}": {
   "get": {
    "tags": [
     "Documents"
    ],
    "summary": "Get a single document, including its content",
    "operationId": "get-v1-app-project-projects-id-documents-docid",
    "description": "Get a single document, including its content. Requires at least viewer role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "docId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "document": {}
         }
        }
       }
      }
     },
     "404": {
      "description": "Document not found"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "patch": {
    "tags": [
     "Documents"
    ],
    "summary": "Update a document. Requires at least member role on the project",
    "operationId": "patch-v1-app-project-projects-id-documents-docid",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "docId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "document": {}
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "title": {
          "type": "string"
         },
         "content": {},
         "parent_id": {
          "type": "integer"
         },
         "position": {
          "type": "integer"
         }
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Documents"
    ],
    "summary": "Delete a document (soft delete)",
    "operationId": "delete-v1-app-project-projects-id-documents-docid",
    "description": "Delete a document (soft delete). Requires at least member role on the project.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "docId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/projects/{id}/activity": {
   "get": {
    "tags": [
     "Projects"
    ],
    "summary": "List a project's recent activity log",
    "operationId": "get-v1-app-project-projects-id-activity",
    "description": "List a project's recent activity log. Requires at least viewer role on the project. Returns up to the 100 most recent entries.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "activity": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "project_id": {
              "type": "integer"
             },
             "user_id": {
              "type": "integer"
             },
             "action": {
              "type": "string"
             },
             "target_type": {
              "type": "string"
             },
             "target_id": {
              "type": "integer",
              "nullable": true
             },
             "meta": {
              "type": "object",
              "nullable": true
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/admin/overview": {
   "get": {
    "tags": [
     "Admin"
    ],
    "summary": "Tenant-wide project stats overview (for BRM-Admin)",
    "operationId": "get-v1-app-project-admin-overview",
    "description": "Tenant-wide project stats overview (for BRM-Admin). Requires the GLOBAL_ADMIN role (not project membership).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects. Role: `GLOBAL_ADMIN`.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "project_count": {
           "type": "integer"
          },
          "member_count": {
           "type": "integer"
          },
          "open_tasks": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/admin/projects": {
   "get": {
    "tags": [
     "Admin"
    ],
    "summary": "List every project in the tenant (for BRM-Admin)",
    "operationId": "get-v1-app-project-admin-projects",
    "description": "List every project in the tenant (for BRM-Admin). Requires the GLOBAL_ADMIN role (not project membership).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects. Role: `GLOBAL_ADMIN`.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "projects": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "integer"
             },
             "tenant_id": {
              "type": "integer"
             },
             "client_id": {
              "type": "integer",
              "nullable": true
             },
             "name": {
              "type": "string"
             },
             "slug": {
              "type": "string"
             },
             "public_id": {
              "type": "string"
             },
             "description": {
              "type": "string",
              "nullable": true
             },
             "color": {
              "type": "string",
              "nullable": true
             },
             "icon_image_id": {
              "type": "integer",
              "nullable": true
             },
             "banner_image_id": {
              "type": "integer",
              "nullable": true
             },
             "status": {
              "type": "string",
              "enum": [
               "active",
               "archived"
              ]
             },
             "created_by": {
              "type": "integer"
             },
             "created_at": {
              "type": "string",
              "format": "date-time"
             },
             "updated_at": {
              "type": "string",
              "format": "date-time"
             },
             "archived_at": {
              "type": "string",
              "format": "date-time",
              "nullable": true
             },
             "member_count": {
              "type": "boolean"
             },
             "task_count": {
              "type": "boolean"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/project/admin/projects/{id}": {
   "patch": {
    "tags": [
     "Admin"
    ],
    "summary": "Archive or reactivate any project in the tenant (for BRM-Admin)",
    "operationId": "patch-v1-app-project-admin-projects-id",
    "description": "Archive or reactivate any project in the tenant (for BRM-Admin). Requires the GLOBAL_ADMIN role (not project membership).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: Projects. Role: `GLOBAL_ADMIN`.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid status"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "status": {
          "type": "string",
          "enum": [
           "active",
           "archived"
          ]
         }
        }
       }
      }
     }
    }
   }
  }
 }
}