{
  "openapi": "3.1.1",
  "info": {
    "title": "Laneboard Board Statistics API",
    "version": "1.0.0",
    "summary": "Cards per list, label and person, overdue work, WIP limits, cycle time and throughput.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://laneboardboardstats.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Cards per list, label and person, overdue work, WIP limits, cycle time and throughput.",
        "description": "Counts a kanban board the way a team review needs it: open cards per list against WIP limits, per label and per assignee, due dates (overdue, today, soon), checklist progress, lead and cycle times from the card history, throughput and the oldest work in progress. Also exports every card as CSV.\n\nMethodology:\n- Open cards are cards that are not archived in lists that are not archived. Cards in the done list count as finished; due-date counts and per-label/per-person counts use the unfinished ones.\n- Lead time = from a card’s creation to the last time it entered the done list. Cycle time = from the first time it entered the start list (or any list after it) to that moment. Both in days, from the card history Laneboard writes on every move (or rebuilt from Trello’s actions).\n- Median, mean and 85th percentile (nearest rank) over the finished cards. Throughput = finished cards whose last move into the done list lies within 7 and 30 days up to the “as of” date (inclusive).\n- Work item age of cards between the start list and the done list = days since they first entered the start list (or a later list), counted to the end of the “as of” day.\n- Due states: overdue = due date before the “as of” day and not marked done; today; soon = within the chosen number of days after it.\n\nTimes come from the card history; cards moved before the history started (for example in old imports) only count from their first recorded step.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "laneboard_board_stats",
        "x-owner-app": "laneboard",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaneboardBoardStatsInput"
              },
              "examples": {
                "example1": {
                  "summary": "Sprint board (Laneboard template)",
                  "value": {
                    "board": "{\"format\":\"laneboard\",\"version\":1,\"name\":\"Sprint board\",\"author\":\"\",\"active\":\"sprint\",\"boards\":[{\"id\":\"sprint\",\"title\":\"Sprint 14\",\"description\":\"Two-week sprint board with a WIP limit on “In progress” and “Review”.\",\"background\":{\"color\":\"slate\",\"pattern\":\"grid\"},\"labels\":[{\"id\":\"l1\",\"name\":\"Bug\",\"color\":\"red\"},{\"id\":\"l2\",\"name\":\"Feature\",\"color\":\"blue\"},{\"id\":\"l3\",\"name\":\"Chore\",\"color\":\"grey\"},{\"id\":\"l4\",\"name\":\"Urgent\",\"color\":\"orange\"},{\"id\":\"l5\",\"name\":\"Design\",\"color\":\"purple\"}],\"members\":[{\"id\":\"m1\",\"name\":\"Ana Silva\"},{\"id\":\"m2\",\"name\":\"Ben Okafor\"},{\"id\":\"m3\",\"name\":\"Chen Wei\"},{\"id\":\"m4\",\"name\":\"Dana Kowalski\"}],\"lists\":[{\"id\":\"L1\",\"title\":\"Backlog\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c1\",\"title\":\"Export invoices as PDF\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m3\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-11T09:00:00Z\",\"history\":[{\"at\":\"2026-11-11T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]},{\"id\":\"c2\",\"title\":\"Dark mode for the settings page\",\"description\":\"\",\"labels\":[\"l2\",\"l5\"],\"members\":[],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-12T09:00:00Z\",\"history\":[{\"at\":\"2026-11-12T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]},{\"id\":\"c3\",\"title\":\"Upgrade the test runner\",\"description\":\"\",\"labels\":[\"l3\"],\"members\":[],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-13T09:00:00Z\",\"history\":[{\"at\":\"2026-11-13T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]}]},{\"id\":\"L2\",\"title\":\"Ready\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c4\",\"title\":\"Search ignores accents\",\"description\":\"Searching “Muller” does not find “Müller”.\\n\\n**Steps**\\n1. Add a customer called Müller\\n2. Search for Muller\",\"labels\":[\"l1\"],\"members\":[\"m2\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-14T09:00:00Z\",\"history\":[{\"at\":\"2026-11-14T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-18T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"}]},{\"id\":\"c5\",\"title\":\"Onboarding checklist for new teams\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m4\"],\"due\":\"2026-11-30\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-15T09:00:00Z\",\"history\":[{\"at\":\"2026-11-15T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-19T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"}]}]},{\"id\":\"L3\",\"title\":\"In progress\",\"wip\":3,\"archived\":false,\"cards\":[{\"id\":\"c6\",\"title\":\"Password reset e-mail lands in spam\",\"description\":\"Started after the mail provider switch. Check the **SPF** and **DKIM** records.\",\"labels\":[\"l1\",\"l4\"],\"members\":[\"m1\"],\"due\":\"2026-11-23\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"red\",\"checklists\":[],\"comments\":[{\"id\":\"n1\",\"author\":\"Ana Silva\",\"text\":\"DKIM selector was missing. Fix is deployed to staging.\",\"at\":\"2026-11-23T11:00:00Z\"}],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-16T09:00:00Z\",\"history\":[{\"at\":\"2026-11-16T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-17T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-21T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"}]},{\"id\":\"c7\",\"title\":\"Team calendar view\",\"description\":\"\",\"labels\":[\"l2\",\"l5\"],\"members\":[\"m3\",\"m4\"],\"due\":\"2026-11-26\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[{\"id\":\"k1\",\"title\":\"Definition of done\",\"items\":[{\"id\":\"k1i1\",\"text\":\"Design approved\",\"done\":true},{\"id\":\"k1i2\",\"text\":\"Keyboard navigation\",\"done\":true},{\"id\":\"k1i3\",\"text\":\"Screen-reader labels\",\"done\":false},{\"id\":\"k1i4\",\"text\":\"Tests\",\"done\":false}]}],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-12T09:00:00Z\",\"history\":[{\"at\":\"2026-11-12T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-15T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-20T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"}]}]},{\"id\":\"L4\",\"title\":\"Review\",\"wip\":2,\"archived\":false,\"cards\":[{\"id\":\"c8\",\"title\":\"Rate limit the login form\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m2\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-13T09:00:00Z\",\"history\":[{\"at\":\"2026-11-13T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-16T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-19T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-23T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"}]},{\"id\":\"c9\",\"title\":\"Fix flaky upload test\",\"description\":\"\",\"labels\":[\"l3\",\"l1\"],\"members\":[\"m1\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-15T09:00:00Z\",\"history\":[{\"at\":\"2026-11-15T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-18T10:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L1\"},{\"at\":\"2026-11-22T11:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"}]}]},{\"id\":\"L5\",\"title\":\"Done\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c10\",\"title\":\"Accessible date picker\",\"description\":\"\",\"labels\":[\"l2\",\"l5\"],\"members\":[\"m4\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-10T09:00:00Z\",\"history\":[{\"at\":\"2026-11-10T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-11T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-13T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-15T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-16T13:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]},{\"id\":\"c11\",\"title\":\"CSV import of contacts\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m3\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-10T09:00:00Z\",\"history\":[{\"at\":\"2026-11-10T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-12T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-14T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-17T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-18T13:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]},{\"id\":\"c12\",\"title\":\"Crash when the name is empty\",\"description\":\"\",\"labels\":[\"l1\",\"l4\"],\"members\":[\"m2\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-14T09:00:00Z\",\"history\":[{\"at\":\"2026-11-14T09:00:00Z\",\"type\":\"created\",\"list\":\"L2\"},{\"at\":\"2026-11-14T10:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-15T11:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-16T12:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]},{\"id\":\"c13\",\"title\":\"Update the privacy page\",\"description\":\"\",\"labels\":[\"l3\"],\"members\":[\"m1\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-17T09:00:00Z\",\"history\":[{\"at\":\"2026-11-17T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-19T10:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L1\"},{\"at\":\"2026-11-20T11:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-21T12:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]},{\"id\":\"c14\",\"title\":\"Faster dashboard queries\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m3\"],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-11T09:00:00Z\",\"history\":[{\"at\":\"2026-11-11T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-16T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-18T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-21T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-23T13:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]}]}],\"created\":\"2026-11-03T08:00:00Z\"}]}",
                    "asOf": "2026-11-24"
                  }
                },
                "example2": {
                  "summary": "Content calendar, work starts in “Writing”, due soon = 3 days",
                  "value": {
                    "board": "{\"format\":\"laneboard\",\"version\":1,\"name\":\"Content calendar\",\"author\":\"\",\"active\":\"content\",\"boards\":[{\"id\":\"content\",\"title\":\"Content calendar\",\"description\":\"Blog posts, videos and newsletters from idea to published.\",\"background\":{\"color\":\"sunset\",\"pattern\":\"diagonal\"},\"labels\":[{\"id\":\"l1\",\"name\":\"Blog\",\"color\":\"blue\"},{\"id\":\"l2\",\"name\":\"Video\",\"color\":\"red\"},{\"id\":\"l3\",\"name\":\"Newsletter\",\"color\":\"green\"},{\"id\":\"l4\",\"name\":\"Social\",\"color\":\"pink\"},{\"id\":\"l5\",\"name\":\"Evergreen\",\"color\":\"lime\"}],\"members\":[{\"id\":\"m1\",\"name\":\"Maya Ortiz\"},{\"id\":\"m2\",\"name\":\"Sam Lee\"}],\"lists\":[{\"id\":\"L1\",\"title\":\"Ideas\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c1\",\"title\":\"10 tips for small balconies\",\"description\":\"\",\"labels\":[\"l1\",\"l5\"],\"members\":[],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-12T09:00:00Z\",\"history\":[{\"at\":\"2026-11-12T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]},{\"id\":\"c2\",\"title\":\"Behind the scenes: our studio\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-14T09:00:00Z\",\"history\":[{\"at\":\"2026-11-14T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]},{\"id\":\"c3\",\"title\":\"Spring checklist infographic\",\"description\":\"\",\"labels\":[\"l4\"],\"members\":[],\"due\":\"\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-18T09:00:00Z\",\"history\":[{\"at\":\"2026-11-18T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"}]}]},{\"id\":\"L2\",\"title\":\"Writing\",\"wip\":2,\"archived\":false,\"cards\":[{\"id\":\"c4\",\"title\":\"How we test products\",\"description\":\"## Outline\\n- Why we test\\n- The lab\\n- Scoring\\n\\n\u003e Keep it under 1,200 words.\",\"labels\":[\"l1\"],\"members\":[\"m1\"],\"due\":\"2026-11-29\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-15T09:00:00Z\",\"history\":[{\"at\":\"2026-11-15T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-20T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"}]},{\"id\":\"c5\",\"title\":\"Monthly newsletter\",\"description\":\"\",\"labels\":[\"l3\"],\"members\":[\"m2\"],\"due\":\"2026-12-03\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[{\"id\":\"k1\",\"title\":\"Sections\",\"items\":[{\"id\":\"k1i1\",\"text\":\"Intro\",\"done\":true},{\"id\":\"k1i2\",\"text\":\"Top 3 posts\",\"done\":false},{\"id\":\"k1i3\",\"text\":\"Reader question\",\"done\":false}]}],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-19T09:00:00Z\",\"history\":[{\"at\":\"2026-11-19T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-22T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"}]}]},{\"id\":\"L3\",\"title\":\"Editing\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c6\",\"title\":\"Interview with a beekeeper\",\"description\":\"\",\"labels\":[\"l2\"],\"members\":[\"m2\"],\"due\":\"2026-11-25\",\"dueTime\":\"\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-13T09:00:00Z\",\"history\":[{\"at\":\"2026-11-13T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-17T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-22T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"}]}]},{\"id\":\"L4\",\"title\":\"Scheduled\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c7\",\"title\":\"Seed swap announcement\",\"description\":\"\",\"labels\":[\"l4\"],\"members\":[\"m1\"],\"due\":\"2026-11-27\",\"dueTime\":\"08:00\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-18T09:00:00Z\",\"history\":[{\"at\":\"2026-11-18T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-20T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-21T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-23T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"}]},{\"id\":\"c8\",\"title\":\"Composting for beginners\",\"description\":\"\",\"labels\":[\"l1\",\"l5\"],\"members\":[\"m1\"],\"due\":\"2026-11-28\",\"dueTime\":\"07:30\",\"dueDone\":false,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-10T09:00:00Z\",\"history\":[{\"at\":\"2026-11-10T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-15T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-18T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-22T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"}]}]},{\"id\":\"L5\",\"title\":\"Published\",\"wip\":0,\"archived\":false,\"cards\":[{\"id\":\"c9\",\"title\":\"Autumn planting guide\",\"description\":\"\",\"labels\":[\"l1\",\"l5\"],\"members\":[\"m1\"],\"due\":\"2026-11-20\",\"dueTime\":\"\",\"dueDone\":true,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-04T09:00:00Z\",\"history\":[{\"at\":\"2026-11-04T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-09T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-14T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-17T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-20T13:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]},{\"id\":\"c10\",\"title\":\"Newsletter: harvest edition\",\"description\":\"\",\"labels\":[\"l3\"],\"members\":[\"m2\"],\"due\":\"2026-11-16\",\"dueTime\":\"\",\"dueDone\":true,\"cover\":\"\",\"checklists\":[],\"comments\":[],\"attachments\":[],\"archived\":false,\"created\":\"2026-11-06T09:00:00Z\",\"history\":[{\"at\":\"2026-11-06T09:00:00Z\",\"type\":\"created\",\"list\":\"L1\"},{\"at\":\"2026-11-10T10:00:00Z\",\"type\":\"moved\",\"list\":\"L2\",\"from\":\"L1\"},{\"at\":\"2026-11-12T11:00:00Z\",\"type\":\"moved\",\"list\":\"L3\",\"from\":\"L2\"},{\"at\":\"2026-11-14T12:00:00Z\",\"type\":\"moved\",\"list\":\"L4\",\"from\":\"L3\"},{\"at\":\"2026-11-16T13:00:00Z\",\"type\":\"moved\",\"list\":\"L5\",\"from\":\"L4\"}]}]}],\"created\":\"2026-11-03T08:00:00Z\"}]}",
                    "asOf": "2026-11-24",
                    "startList": "Writing",
                    "soonDays": 3
                  }
                },
                "example3": {
                  "summary": "A Trello export",
                  "value": {
                    "board": "{\"id\":\"6abe13000000000000000001\",\"name\":\"Website relaunch\",\"desc\":\"Small sample board in the shape of a Trello export.\",\"closed\":false,\"shortUrl\":\"https://trello.com/b/sample\",\"idOrganization\":null,\"prefs\":{\"background\":\"green\",\"backgroundColor\":\"#519839\"},\"labels\":[{\"id\":\"6abe142c0000000000000006\",\"name\":\"Bug\",\"color\":\"red\"},{\"id\":\"6abe142c0000000000000007\",\"name\":\"Feature\",\"color\":\"blue_dark\"},{\"id\":\"6abe142c0000000000000008\",\"name\":\"Docs\",\"color\":null}],\"members\":[{\"id\":\"6a9686000000000000000009\",\"fullName\":\"Ana Pereira\",\"username\":\"anap\"},{\"id\":\"6a968600000000000000000a\",\"fullName\":\"\",\"username\":\"raj_k\"}],\"lists\":[{\"id\":\"6abe13b40000000000000004\",\"name\":\"Done\",\"closed\":false,\"pos\":3072},{\"id\":\"6abe133c0000000000000002\",\"name\":\"Ideas\",\"closed\":false,\"pos\":1024},{\"id\":\"6abe13780000000000000003\",\"name\":\"Doing\",\"closed\":false,\"pos\":2048},{\"id\":\"6abe13f00000000000000005\",\"name\":\"Parking lot\",\"closed\":true,\"pos\":4096}],\"cards\":[{\"id\":\"6abf72900000000000000065\",\"name\":\"New logo on the home page\",\"desc\":\"\",\"idList\":\"6abe13b40000000000000004\",\"pos\":1024,\"closed\":false,\"due\":\"2026-10-10T15:00:00.000Z\",\"dueComplete\":true,\"idLabels\":[\"6abe142c0000000000000007\"],\"idMembers\":[\"6a9686000000000000000009\"],\"attachments\":[],\"cover\":{\"color\":\"green\",\"idAttachment\":null}},{\"id\":\"6ac0c4100000000000000066\",\"name\":\"Contact form sends twice\",\"desc\":\"Happens on **slow** connections.\\n\\n- [x] Reproduce\\n- [ ] Fix\",\"idList\":\"6abe13780000000000000003\",\"pos\":2048,\"closed\":false,\"due\":\"2026-10-20T09:30:00.000Z\",\"dueComplete\":false,\"idLabels\":[\"6abe142c0000000000000006\"],\"idMembers\":[\"6a968600000000000000000a\"],\"attachments\":[],\"cover\":{\"color\":null,\"idAttachment\":null}},{\"id\":\"6ac215900000000000000067\",\"name\":\"Write the FAQ\",\"desc\":\"\",\"idList\":\"6abe13780000000000000003\",\"pos\":1024,\"closed\":false,\"due\":null,\"dueComplete\":false,\"idLabels\":[\"6abe142c0000000000000008\"],\"idMembers\":[],\"attachments\":[{\"id\":\"6ac375200000000000000384\",\"name\":\"Draft\",\"url\":\"https://docs.example.org/faq-draft\",\"isUpload\":false},{\"id\":\"6ac375200000000000000385\",\"name\":\"screenshot.png\",\"url\":\"https://trello.com/1/cards/x/attachments/y/download/screenshot.png\",\"isUpload\":true},{\"id\":\"6ac375200000000000000386\",\"name\":\"bad\",\"url\":\"javascript:alert(1)\",\"isUpload\":false}],\"cover\":{\"color\":null,\"idAttachment\":null}},{\"id\":\"6ac367100000000000000068\",\"name\":\"Dark mode\",\"desc\":\"\",\"idList\":\"6abe133c0000000000000002\",\"pos\":1024,\"closed\":false,\"due\":null,\"dueComplete\":false,\"idLabels\":[\"6abe142c0000000000000007\",\"unknown-label\"],\"idMembers\":[],\"attachments\":[],\"cover\":{\"color\":null,\"idAttachment\":null}},{\"id\":\"6ac4b8900000000000000069\",\"name\":\"Old banner idea\",\"desc\":\"\",\"idList\":\"6abe13f00000000000000005\",\"pos\":1024,\"closed\":false,\"due\":null,\"dueComplete\":false,\"idLabels\":[],\"idMembers\":[],\"attachments\":[],\"cover\":{\"color\":null,\"idAttachment\":null}},{\"id\":\"6ac60a10000000000000006a\",\"name\":\"Cookie notice text\",\"desc\":\"\",\"idList\":\"6abe13b40000000000000004\",\"pos\":2048,\"closed\":true,\"due\":null,\"dueComplete\":false,\"idLabels\":[\"6abe142c0000000000000008\"],\"idMembers\":[],\"attachments\":[],\"cover\":{\"color\":null,\"idAttachment\":null}}],\"checklists\":[{\"id\":\"6ac0d22000000000000002bc\",\"idCard\":\"6ac0c4100000000000000066\",\"name\":\"Fix plan\",\"pos\":1,\"checkItems\":[{\"id\":\"6ac0d22000000000000002bd\",\"name\":\"Disable button on submit\",\"state\":\"complete\",\"pos\":2},{\"id\":\"6ac0d22000000000000002be\",\"name\":\"Add a test\",\"state\":\"incomplete\",\"pos\":3}]}],\"customFields\":[{\"id\":\"6abe13000000000000000320\",\"name\":\"Effort\"}],\"actions\":[{\"id\":\"6ac8bb200000000000000258\",\"type\":\"commentCard\",\"date\":\"2026-10-09T10:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Raj K\"},\"data\":{\"text\":\"Looks great on mobile too.\",\"card\":{\"id\":\"6abf72900000000000000065\"}}},{\"id\":\"6ac777b000000000000001f4\",\"type\":\"updateCard\",\"date\":\"2026-10-08T11:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6abf72900000000000000065\"},\"listBefore\":{\"id\":\"6abe13780000000000000003\"},\"listAfter\":{\"id\":\"6abe13b40000000000000004\"}}},{\"id\":\"6ac231b000000000000001f4\",\"type\":\"updateCard\",\"date\":\"2026-10-04T11:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6abf72900000000000000065\"},\"listBefore\":{\"id\":\"6abe133c0000000000000002\"},\"listAfter\":{\"id\":\"6abe13780000000000000003\"}}},{\"id\":\"6ac4e2c000000000000001f5\",\"type\":\"updateCard\",\"date\":\"2026-10-06T12:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac0c4100000000000000066\"},\"listBefore\":{\"id\":\"6abe133c0000000000000002\"},\"listAfter\":{\"id\":\"6abe13780000000000000003\"}}},{\"id\":\"6acccbc000000000000001f9\",\"type\":\"updateCard\",\"date\":\"2026-10-12T12:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac60a10000000000000006a\"},\"listBefore\":{\"id\":\"6abe13780000000000000003\"},\"listAfter\":{\"id\":\"6abe13b40000000000000004\"}}},{\"id\":\"6ac8d74000000000000001f9\",\"type\":\"updateCard\",\"date\":\"2026-10-09T12:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac60a10000000000000006a\"},\"listBefore\":{\"id\":\"6abe133c0000000000000002\"},\"listAfter\":{\"id\":\"6abe13780000000000000003\"}}},{\"id\":\"6abf72900000000000000190\",\"type\":\"createCard\",\"date\":\"2026-10-02T09:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6abf72900000000000000065\"},\"list\":{\"id\":\"6abe133c0000000000000002\"}}},{\"id\":\"6ac0c4100000000000000191\",\"type\":\"createCard\",\"date\":\"2026-10-03T09:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac0c4100000000000000066\"},\"list\":{\"id\":\"6abe133c0000000000000002\"}}},{\"id\":\"6ac215900000000000000192\",\"type\":\"createCard\",\"date\":\"2026-10-04T09:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac215900000000000000067\"},\"list\":{\"id\":\"6abe13780000000000000003\"}}},{\"id\":\"6ac367100000000000000193\",\"type\":\"createCard\",\"date\":\"2026-10-05T09:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac367100000000000000068\"},\"list\":{\"id\":\"6abe133c0000000000000002\"}}},{\"id\":\"6ac60a100000000000000195\",\"type\":\"createCard\",\"date\":\"2026-10-07T09:00:00.000Z\",\"memberCreator\":{\"fullName\":\"Ana Pereira\"},\"data\":{\"card\":{\"id\":\"6ac60a10000000000000006a\"},\"list\":{\"id\":\"6abe133c0000000000000002\"}}}]}",
                    "asOf": "2026-10-21"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaneboardBoardStatsResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LaneboardBoardStatsInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "board": {
            "title": "Board (JSON)",
            "description": "A Laneboard project or board file (.laneboard.json), a Laneboard share snapshot, or a Trello board export (JSON).",
            "type": "string",
            "maxLength": 3000000,
            "default": ""
          },
          "boardFile": {
            "title": "Board file (optional)",
            "description": "Used instead of the pasted text when given. Upload as {filename, contentType?, contentBase64}. Max 9766 KiB. Accepts .json,application/json.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "boardName": {
            "title": "Board (projects with several boards)",
            "description": "Board title or number (1 = first). Empty = the board that was open last.",
            "type": "string",
            "maxLength": 300,
            "default": ""
          },
          "asOf": {
            "title": "As of (date)",
            "description": "The day the numbers are counted for. Empty = today.",
            "type": "string",
            "format": "date"
          },
          "soonDays": {
            "title": "Due soon = within (days)",
            "type": "integer",
            "minimum": 0,
            "maximum": 60,
            "default": 7
          },
          "startList": {
            "title": "Work starts in list",
            "description": "Cycle time starts when a card first enters this list or a later one. Empty = the second list.",
            "type": "string",
            "maxLength": 300,
            "default": ""
          },
          "doneList": {
            "title": "Done list",
            "description": "Empty = the last list.",
            "type": "string",
            "maxLength": 300,
            "default": ""
          }
        },
        "required": []
      },
      "LaneboardBoardStatsResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}