{"openapi":"3.1.0","info":{"title":"Kapcal","version":"1.0","description":"Kapcal is a shared planning board: items with dates (and times), filed in categories that belong to projects, grouped in phases, linked by arrows on the workflow.\nTo put dates from a document (PDF, spreadsheet, email, picture) on a board:\n1. list_boards, then get_board to learn its categories, phases, owners and time zone.\n2. Read the document and turn each scheduled line into an item: title, category (one of the board's), start and end dates, times when the document gives them, owner, notes. Give each item a ref naming its place in the document (e.g. \"Shooting schedule / Day 12 / Sc 41\"), so a revised version of the same document updates those items instead of adding them again.\n3. preview_changes, then show the person what will be added, changed and skipped, and why.\n4. Only after they agree, apply_changes.\nNever invent a category: ask the person, then add_category if they agree. undo_import takes an import back. Nothing is ever deleted except by undo_import, which moves what an import added to the board's Trash."},"servers":[{"url":"https://kapcal.com/api/v1"}],"security":[{"key":[]}],"components":{"securitySchemes":{"key":{"type":"http","scheme":"bearer","description":"A key from Kapcal, Account → AI & API (kap_…)."}}},"paths":{"/list_boards":{"post":{"operationId":"list_boards","summary":"List boards","description":"The boards this key reaches, with your role on each and whether you can change it.","x-openai-isConsequential":false,"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/get_board":{"post":{"operationId":"get_board","summary":"Read a board","description":"A board's categories, phases, owners, time zone, today's date and recent imports. Read it before preview_changes.","x-openai-isConsequential":false,"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"board":{"type":"string","description":"The board's id or name, from list_boards. Can be left out when the key reaches only one board."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/find_items":{"post":{"operationId":"find_items","summary":"Find items","description":"Items on a board by dates, words, category, ref or status.","x-openai-isConsequential":false,"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"board":{"type":"string","description":"The board's id or name, from list_boards. Can be left out when the key reaches only one board."},"from":{"type":"string","format":"date","description":"YYYY-MM-DD"},"to":{"type":"string","format":"date","description":"YYYY-MM-DD"},"text":{"type":"string","description":"Words to look for."},"category":{"type":"string","description":"A category's full name, the end of it, or its id."},"ref":{"type":"string"},"status":{"type":"string","enum":["planned","in progress","done","cancelled"]},"timeZone":{"type":"string","description":"Show times in this zone (an IANA name such as America/Toronto) instead of the board's."},"limit":{"type":"integer","minimum":1,"maximum":300,"description":"At most this many (100 when left out)."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/preview_changes":{"post":{"operationId":"preview_changes","summary":"Preview changes","description":"What a list of items would add or change on a board, without changing anything. Show the person, then apply_changes.","x-openai-isConsequential":false,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"board":{"type":"string","description":"The board's id or name, from list_boards. Can be left out when the key reaches only one board."},"items":{"type":"array","items":{"type":"object","properties":{"ref":{"type":"string","description":"A stable label for where this line is in the document, e.g. \"Shooting schedule / Day 12 / Sc 41\" (up to 160 characters). Sending the same ref again later updates that item instead of adding another."},"id":{"type":"string","description":"To change an item already on the board: its id (from find_items). Leave it out for new items."},"title":{"type":"string","description":"Up to 200 characters. Needed for a new item."},"category":{"type":"string","description":"One of the board's categories (get_board): its full name (\"Project › Category › Subcategory\"), the end of it when only one ends that way, or its id. Needed for a new item."},"start":{"type":"string","format":"date","description":"First day, YYYY-MM-DD."},"end":{"type":"string","format":"date","description":"Last day (included), YYYY-MM-DD. Defaults to start."},"startTime":{"type":"string","description":"Time of day it starts, HH:MM (24-hour), in timeZone. Leave out for an all-day item."},"endTime":{"type":"string","description":"Time of day it ends, HH:MM, on the end day. Defaults to an hour after startTime."},"allDay":{"type":"boolean","description":"true turns an item with times into an all-day one."},"owner":{"type":"string","description":"Who it is for or who does it: a name."},"status":{"type":"string","enum":["planned","in progress","done","cancelled"]},"notes":{"type":"string","description":"Details, up to 4000 characters (location, call time, contacts…)."},"flagged":{"type":"boolean","description":"An important date, drawn so it stands out."},"weekendsOff":{"type":"boolean","description":"Runs on weekdays only (its weekends are shown faded)."},"milestone":{"type":"boolean","description":"A single key date, such as a delivery or a deadline."},"phase":{"type":"string","description":"The phase it is part of (a larger item that holds others, e.g. \"Shoot\"): the ref or title of an item in this same list, or the id, ref or title of an item on the board. Empty to take it out of its phase."},"after":{"type":"array","items":{"type":"string"},"description":"Items it follows on the workflow (it starts after they end): refs or titles in this list, or ids, refs or titles on the board."}}},"minItems":1,"maxItems":500},"source":{"type":"string","description":"The document's name, e.g. \"Shooting schedule v4.pdf\" (shown with the import)."},"timeZone":{"type":"string","description":"The zone the document's times are in, an IANA name such as America/Toronto. Defaults to the board's (get_board)."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/apply_changes":{"post":{"operationId":"apply_changes","summary":"Apply changes","description":"Apply a preview the person agreed to, as one import that undo_import can take back.","x-openai-isConsequential":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["preview"],"properties":{"preview":{"type":"string","description":"The preview id from preview_changes."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/undo_import":{"post":{"operationId":"undo_import","summary":"Undo an import","description":"Take an import back: what it added goes to the Trash, what it changed goes back.","x-openai-isConsequential":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["import"],"properties":{"import":{"type":"string","description":"The import id from apply_changes (or recentImports in get_board)."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/add_category":{"post":{"operationId":"add_category","summary":"Add a category","description":"Add a category (or get the one already called that). Only after the person agreed.","x-openai-isConsequential":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"board":{"type":"string","description":"The board's id or name, from list_boards. Can be left out when the key reaches only one board."},"name":{"type":"string","description":"Up to 60 characters."},"project":{"type":"string","description":"The project it belongs to (a name from get_board)."},"parent":{"type":"string","description":"For a subcategory: the category it goes in."},"color":{"type":"integer","minimum":0,"maximum":9,"description":"One of the board's 10 colours. Left out: the least used."}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"description":"Refused or not possible: `error` says why.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}}}}