{
 "openapi": "3.0.3",
 "info": {
  "title": "Bramble To Do API",
  "version": "2026-11-13",
  "description": "Bramble To Do: shared lists, their members, and tasks with due dates, priorities and repeats. 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": "Lists & tasks",
   "description": "Lists, their members, and the tasks in them."
  }
 ],
 "paths": {
  "/v1/app/todo/lists": {
   "get": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "List the caller's ToDo lists",
    "operationId": "get-v1-app-todo-lists",
    "description": "List the caller's ToDo lists. Returns lists the caller owns or is a member of (via todo_list_members), each annotated with my_role, task_count and open_count.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "lists": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Create a list. Creator becomes the list's owner",
    "operationId": "post-v1-app-todo-lists",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "list": {
           "type": "object",
           "properties": {
            "my_role": {
             "type": "string"
            }
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "name is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "icon": {},
         "color": {}
        },
        "required": [
         "name",
         "color"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/todo/lists/{id}": {
   "patch": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Update a list's name, icon, color or position",
    "operationId": "patch-v1-app-todo-lists-id",
    "description": "Update a list's name, icon, color or position. Requires editor or owner role on the list (see todo_list_members).\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "list": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "color must be a #rrggbb hex value"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "icon": {},
         "color": {},
         "position": {
          "type": "integer"
         }
        },
        "required": [
         "color"
        ]
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Delete a list. Requires owner role on the list",
    "operationId": "delete-v1-app-todo-lists-id",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "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/todo/lists/{id}/members": {
   "get": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "List a list's owner and members",
    "operationId": "get-v1-app-todo-lists-id-members",
    "description": "List a list's owner and members. Requires at least viewer role on the list.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "owner": {},
          "members": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Add a member to a list",
    "operationId": "post-v1-app-todo-lists-id-members",
    "description": "Add a member to a list. Requires editor or owner role on the list. Target user must be an active staff user in the caller's tenant.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "user_id is required"
     },
     "404": {
      "description": "User not found in your organisation"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "user_id": {
          "type": "integer"
         },
         "role": {
          "type": "string",
          "enum": [
           "viewer",
           "editor"
          ]
         }
        },
        "required": [
         "user_id"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/todo/lists/{id}/available-users": {
   "get": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "List tenant staff users not already on the list",
    "operationId": "get-v1-app-todo-lists-id-available-users",
    "description": "List tenant staff users not already on the list. Requires editor or owner role on the list. Used to populate the \"add member\" picker.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "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/todo/lists/{id}/members/{userId}": {
   "patch": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Change a member's role",
    "operationId": "patch-v1-app-todo-lists-id-members-userid",
    "description": "Change a member's role. Requires owner role on the list.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "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"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "role": {
          "type": "string",
          "enum": [
           "viewer",
           "editor"
          ]
         }
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Remove a member from a list",
    "operationId": "delete-v1-app-todo-lists-id-members-userid",
    "description": "Remove a member from a list. A caller removing themselves only needs viewer role; removing another member requires owner role.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "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"
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   }
  },
  "/v1/app/todo/lists/{id}/tasks": {
   "get": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "List a list's (non-deleted) tasks",
    "operationId": "get-v1-app-todo-lists-id-tasks",
    "description": "List a list's (non-deleted) tasks. Requires at least viewer role on the list.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "tasks": {
           "type": "array",
           "items": {}
          }
         }
        }
       }
      }
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ]
   },
   "post": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Add a task to a list",
    "operationId": "post-v1-app-todo-lists-id-tasks",
    "description": "Requires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "201": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "task": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "title is required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "title": {
          "type": "string",
          "description": "What needs doing."
         },
         "notes": {
          "type": "array",
          "items": {},
          "description": "More detail."
         },
         "status": {
          "type": "string",
          "description": "Its status."
         },
         "priority": {
          "description": "Its priority."
         },
         "due_date": {
          "type": "string",
          "format": "date",
          "description": "When it's due (`YYYY-MM-DD`)."
         },
         "recurrence": {
          "description": "How it repeats."
         }
        },
        "required": [
         "title"
        ]
       }
      }
     }
    }
   }
  },
  "/v1/app/todo/lists/{id}/tasks/{taskId}": {
   "patch": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Update a task's fields",
    "operationId": "patch-v1-app-todo-lists-id-tasks-taskid",
    "description": "Update a task's fields. Requires editor or owner role on the list. Setting status to done also stamps completed_at; any other status clears it. At least one field must be provided.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "taskId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "task": {}
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid status"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "title": {
          "type": "string"
         },
         "notes": {
          "type": "array",
          "items": {}
         },
         "status": {
          "type": "string"
         },
         "priority": {},
         "due_date": {
          "type": "string",
          "format": "date"
         },
         "recurrence": {}
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Soft-delete a task. Requires editor or owner role on the list",
    "operationId": "delete-v1-app-todo-lists-id-tasks-taskid",
    "description": "Soft-delete a task. Requires editor or owner role on the list. Sets deleted_at rather than removing the row.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "taskId",
      "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/todo/lists/{id}/tasks/{taskId}/move": {
   "patch": {
    "tags": [
     "Lists & tasks"
    ],
    "summary": "Move a task between status columns or reorder it within one",
    "operationId": "patch-v1-app-todo-lists-id-tasks-taskid-move",
    "description": "Move a task between status columns or reorder it within one. Requires editor or owner role on the list. Used for drag-and-drop. Setting status to done also stamps completed_at; any other status clears it.\n\nRequires: Signed-in session, `X-API-Key`, or a Bramble app access token (`Authorization: Bearer`). Licence: To Do.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "taskId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Success",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "status and position are required"
     }
    },
    "security": [
     {
      "apiKey": []
     },
     {
      "session": []
     },
     {
      "bearer": []
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "status": {
          "type": "string"
         },
         "position": {
          "type": "integer"
         }
        },
        "required": [
         "position"
        ]
       }
      }
     }
    }
   }
  }
 }
}