{
  "openapi": "3.1.1",
  "info": {
    "title": "Laneboard Cumulative Flow API",
    "version": "1.0.0",
    "summary": "Cumulative flow diagram of a kanban board: cards per list for every day, plus WIP 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://laneboardcumulativeflow.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Cumulative flow diagram of a kanban board: cards per list for every day, plus WIP and throughput.",
        "description": "Rebuilds how many cards were in each list at the end of every day from the card history of a Laneboard board or a Trello export, draws the cumulative flow diagram and works out arrivals, finished cards, average work in progress and a Little’s law lead-time estimate.\n\nMethodology:\n- For every day the tool replays each card’s history (created in a list, moved, archived, restored) up to midnight UTC at the end of that day and counts the cards per list. Archived cards leave the chart on the day they were archived.\n- The chart stacks the lists with the last list (done) at the bottom, so the top edge is all cards that have arrived and the bands show where they wait.\n- Arrivals = cards created in the period; finished = cards moved into the last list in the period. Work in progress = cards in the lists between the first and the last one, averaged over the days.\n- Lead-time estimate by Little’s law: average work in progress ÷ average finished cards per day. It holds for a stable system over the period and is an estimate, not a measured time.\n\nDays are counted in UTC. At most 366 days are drawn.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "laneboard_cumulative_flow",
        "x-owner-app": "laneboard",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaneboardCumulativeFlowInput"
              },
              "examples": {
                "example1": {
                  "summary": "Sprint board, last two weeks",
                  "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",
                    "from": "2026-11-10"
                  }
                },
                "example2": {
                  "summary": "Content calendar since its first card",
                  "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"
                  }
                },
                "example3": {
                  "summary": "A Trello export in October",
                  "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",
                    "from": "2026-10-01",
                    "to": "2026-10-21"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaneboardCumulativeFlowResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "LaneboardCumulativeFlowInput": {
        "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"
          },
          "from": {
            "title": "From (date)",
            "description": "Empty = when the first card was created (at most 90 days back).",
            "type": "string",
            "format": "date"
          },
          "to": {
            "title": "To (date)",
            "description": "Empty = the “as of” date.",
            "type": "string",
            "format": "date"
          }
        },
        "required": []
      },
      "LaneboardCumulativeFlowResult": {
        "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"
              }
            }
          }
        }
      }
    }
  }
}