{
  "openapi": "3.1.0",
  "info": {
    "title": "Clear Mint Essentials API",
    "version": "1.0.0",
    "summary": "REST API surface for the Clear Mint Essentials personal-finance app.",
    "description": "The **Clear Mint Essentials** API documents the product's feature set: banking & accounts, transactions,\nearnings, bills & expenses, statement import (OFX / CSV / PDF, bank & credit-card), subscription detection,\nreports (cash flow, financial outlook, monthly summary), reconciliation, exports, and profile/settings.\n\n### Architecture (fully serverless)\nClear Mint Essentials runs with **no self-managed server**: a static front-end on a CDN, a few\nstateless serverless functions (scale-to-zero), and **Supabase** (managed Postgres cloud) for storage.\nYour data is held securely in the cloud, encrypted at rest, isolated per user by Row-Level Security.\nMost work (statement parsing, calculations) happens in your browser; serverless functions are used only\nfor the few tasks that need a secret or heavier parsing.\n\n### Endpoint status\nEvery operation is tagged with an `x-clearmint-status` extension:\n- **live** — an implemented HTTP endpoint (e.g. health check, statement import, checkout).\n- **modeled** — documents an Essentials data resource the app manages (persisted via the user's\n  synced financial state). These describe the resource shape and contract.\n\n### Authentication\nAuthenticated endpoints expect a Supabase access token as a Bearer token: `Authorization: Bearer <token>`.\n\n### Scope\nThis API covers **Clear Mint Essentials only**. Premium / full Clear Mint capabilities — AI assistant,\nFamily Vault, investments, estate planning, advanced wealth forecasting, live open-banking connections,\nand the full admin platform — are **not** part of Essentials and are intentionally excluded.",
    "termsOfService": "https://clearmintessentials.com/terms",
    "contact": {
      "name": "Clear Mint Essentials Support",
      "email": "support@clearmintessentials.com",
      "url": "https://clearmintessentials.com/help"
    },
    "license": {
      "name": "Proprietary — © Clear Mint Essentials",
      "url": "https://clearmintessentials.com/terms"
    }
  },
  "externalDocs": {
    "description": "Help Center & guides",
    "url": "https://clearmintessentials.com/help"
  },
  "servers": [
    {
      "url": "https://clearmintessentials.app",
      "description": "Primary production domain"
    },
    {
      "url": "https://clearmintessentials.com",
      "description": "Production domain (redirects to .app)"
    },
    {
      "url": "https://clearmintessentials.ca",
      "description": "Canada production domain (redirects to .app)"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Health",
      "description": "Service status."
    },
    {
      "name": "Authentication",
      "description": "Sign-in session & the current user."
    },
    {
      "name": "Banking",
      "description": "Bank accounts and credit cards (manual entry + imported)."
    },
    {
      "name": "Transactions",
      "description": "Bank & credit-card transactions, with monthly filtering."
    },
    {
      "name": "Earnings",
      "description": "Income sources and one-off earnings."
    },
    {
      "name": "Bills & Expenses",
      "description": "Recurring bills and one-time expenses."
    },
    {
      "name": "Subscriptions",
      "description": "Recurring subscriptions detected from your transactions."
    },
    {
      "name": "Import",
      "description": "Upload & parse OFX / CSV / PDF bank & credit-card statements."
    },
    {
      "name": "Reports",
      "description": "Cash flow, financial outlook, monthly summary, and exports."
    },
    {
      "name": "Reconciliation",
      "description": "Reconcile an account against a statement balance."
    },
    {
      "name": "Billing",
      "description": "Subscription checkout (Stripe)."
    },
    {
      "name": "Profile",
      "description": "User profile and settings."
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "operationId": "getHealth",
        "summary": "Health check",
        "description": "Returns service status. No authentication required.",
        "security": [],
        "x-clearmint-status": "live",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "example": {
                  "ok": true,
                  "service": "clearmint-essentials",
                  "time": "2026-06-28T17:00:00.000Z"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/session": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "operationId": "getSession",
        "summary": "Current session",
        "description": "Returns the authenticated user resolved from the Bearer access token.",
        "x-clearmint-status": "modeled",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/accounts": {
      "get": {
        "tags": [
          "Banking"
        ],
        "operationId": "listAccounts",
        "summary": "List bank accounts",
        "description": "Returns the bank accounts for the authenticated user.",
        "x-clearmint-status": "modeled",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Account"
                  }
                },
                "example": [
                  {
                    "id": "acc_8f2a",
                    "name": "Everyday Chequing ····4021",
                    "bank": "RBC Royal Bank",
                    "type": "Chequing",
                    "last4": "4021",
                    "opening": 1500,
                    "balance": 2380.55,
                    "currency": "CAD"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Banking"
        ],
        "operationId": "createAccount",
        "summary": "Create account",
        "description": "Creates a account (manual entry).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/accounts/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "get": {
        "tags": [
          "Banking"
        ],
        "operationId": "getAccount",
        "summary": "Get account",
        "x-clearmint-status": "modeled",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "patch": {
        "tags": [
          "Banking"
        ],
        "operationId": "updateAccount",
        "summary": "Update account",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Banking"
        ],
        "operationId": "deleteAccount",
        "summary": "Delete account",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/cards": {
      "get": {
        "tags": [
          "Banking"
        ],
        "operationId": "listCards",
        "summary": "List credit cards",
        "description": "Returns the credit cards for the authenticated user.",
        "x-clearmint-status": "modeled",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Card"
                  }
                },
                "example": [
                  {
                    "id": "card_31bd",
                    "name": "Aeroplan Visa Infinite",
                    "issuer": "TD",
                    "last4": "7788",
                    "balance": 642.18,
                    "limit": 8000,
                    "currency": "CAD"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Banking"
        ],
        "operationId": "createCard",
        "summary": "Create credit card",
        "description": "Creates a credit card (manual entry).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/cards/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "get": {
        "tags": [
          "Banking"
        ],
        "operationId": "getCard",
        "summary": "Get credit card",
        "x-clearmint-status": "modeled",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "patch": {
        "tags": [
          "Banking"
        ],
        "operationId": "updateCard",
        "summary": "Update credit card",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Card"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Banking"
        ],
        "operationId": "deleteCard",
        "summary": "Delete credit card",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/transactions": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "operationId": "listTransactions",
        "summary": "List transactions",
        "description": "Returns bank and credit-card transactions for the authenticated user. Filter by `month` for the monthly view (previous/next-month navigation), by `accountId`/`cardId`, or by `type`.",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          },
          {
            "name": "accountId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Limit to one bank account."
          },
          {
            "name": "cardId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Limit to one credit card."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "debit",
                "credit"
              ]
            },
            "description": "Money out (debit) or in (credit)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transaction"
                  }
                },
                "example": [
                  {
                    "id": "tx_1a2b",
                    "date": "2026-06-12",
                    "desc": "Tim Hortons",
                    "dr": 4.85,
                    "cr": 0,
                    "cat": "Dining",
                    "account": "Everyday Chequing ····4021",
                    "source": "ofx"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Transactions"
        ],
        "operationId": "createTransaction",
        "summary": "Create transaction",
        "description": "Adds a manual bank or credit-card transaction.",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/transactions/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "patch": {
        "tags": [
          "Transactions"
        ],
        "operationId": "updateTransaction",
        "summary": "Update transaction",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Transactions"
        ],
        "operationId": "deleteTransaction",
        "summary": "Delete transaction",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/parse-statement": {
      "post": {
        "tags": [
          "Import"
        ],
        "operationId": "parseStatement",
        "summary": "Upload & parse a statement",
        "description": "Uploads a bank or credit-card statement and returns the parsed transactions plus statement metadata. Supports **OFX/QFX**, **CSV**, and **PDF** files. Used by the in-app import flow (bank statement, credit-card statement). The parsed result is previewed and then committed client-side with duplicate detection.",
        "x-clearmint-status": "live",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The statement file (.ofx, .qfx, .csv, .pdf)."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "bank",
                      "cc"
                    ],
                    "description": "Whether this is a bank or credit-card statement."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParseStatementResult"
                },
                "example": {
                  "ok": true,
                  "kind": "ofx",
                  "transactions": [
                    {
                      "date": "2026-06-12",
                      "desc": "Tim Hortons",
                      "dr": 4.85,
                      "cr": 0
                    }
                  ],
                  "meta": {
                    "last4": "4021",
                    "bankId": "RBC",
                    "acctType": "CHECKING",
                    "currency": "CAD"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/earnings": {
      "get": {
        "tags": [
          "Earnings"
        ],
        "operationId": "listEarnings",
        "summary": "List earnings",
        "description": "Returns the earnings for the authenticated user. Use `month` to filter to a single month (powers the monthly view and previous/next-month navigation).",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Earning"
                  }
                },
                "example": [
                  {
                    "id": "ern_77",
                    "source": "Acme Payroll",
                    "amount": 3200,
                    "frequency": "Biweekly",
                    "cat": "Salary",
                    "date": "2026-06-15"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Earnings"
        ],
        "operationId": "createEarning",
        "summary": "Create earning",
        "description": "Creates a earning (manual entry).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EarningInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Earning"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/earnings/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "patch": {
        "tags": [
          "Earnings"
        ],
        "operationId": "updateEarning",
        "summary": "Update earning",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EarningInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Earning"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Earnings"
        ],
        "operationId": "deleteEarning",
        "summary": "Delete earning",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/bills": {
      "get": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "listBills",
        "summary": "List recurring bills",
        "description": "Returns the recurring bills for the authenticated user. Use `month` to filter to a single month (powers the monthly view and previous/next-month navigation).",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Bill"
                  }
                },
                "example": [
                  {
                    "id": "bill_4",
                    "name": "Hydro",
                    "amount": 95.4,
                    "frequency": "Monthly",
                    "cat": "Utilities",
                    "dueDate": "2026-06-20"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "createBill",
        "summary": "Create bill",
        "description": "Creates a bill (manual entry).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BillInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bill"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/bills/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "patch": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "updateBill",
        "summary": "Update bill",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BillInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bill"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "deleteBill",
        "summary": "Delete bill",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/expenses": {
      "get": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "listExpenses",
        "summary": "List one-time expenses",
        "description": "Returns the one-time expenses for the authenticated user. Use `month` to filter to a single month (powers the monthly view and previous/next-month navigation).",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Expense"
                  }
                },
                "example": [
                  {
                    "id": "exp_9",
                    "vendor": "IKEA",
                    "amount": 219.99,
                    "cat": "Home",
                    "date": "2026-06-08"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "createExpense",
        "summary": "Create expense",
        "description": "Creates a expense (manual entry).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/expenses/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ResourceId"
        }
      ],
      "patch": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "updateExpense",
        "summary": "Update expense",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "tags": [
          "Bills & Expenses"
        ],
        "operationId": "deleteExpense",
        "summary": "Delete expense",
        "x-clearmint-status": "modeled",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/subscriptions": {
      "get": {
        "tags": [
          "Subscriptions"
        ],
        "operationId": "listSubscriptions",
        "summary": "List detected subscriptions",
        "description": "Returns recurring subscriptions automatically detected from your bank and credit-card transactions (merchant + cadence + typical amount).",
        "x-clearmint-status": "modeled",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                },
                "example": [
                  {
                    "name": "Netflix",
                    "amount": 20.99,
                    "cadence": "Monthly",
                    "cat": "Entertainment",
                    "lastCharged": "2026-06-03",
                    "monthly": 20.99
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/reports/summary": {
      "get": {
        "tags": [
          "Reports"
        ],
        "operationId": "getMonthlySummary",
        "summary": "Dashboard monthly summary",
        "description": "Income, expenses, and net for a month — the figures behind the dashboard tiles.",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonthlySummary"
                },
                "example": {
                  "month": "2026-06",
                  "income": 6400,
                  "expenses": 3910.32,
                  "net": 2489.68
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/reports/cash-flow": {
      "get": {
        "tags": [
          "Reports"
        ],
        "operationId": "getCashFlow",
        "summary": "Cash flow view",
        "description": "Money in vs money out and the running net for the selected month (the Cash Flow view).",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CashFlow"
                },
                "example": {
                  "month": "2026-06",
                  "moneyIn": 6400,
                  "moneyOut": 3910.32,
                  "net": 2489.68
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/reports/financial-outlook": {
      "get": {
        "tags": [
          "Reports"
        ],
        "operationId": "getFinancialOutlook",
        "summary": "Financial outlook",
        "description": "A forward-looking projection of net cash position based on recurring earnings, bills and expenses.",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "name": "months",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 24,
              "default": 12
            },
            "description": "How many months to project."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinancialOutlook"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/reports/export": {
      "get": {
        "tags": [
          "Reports"
        ],
        "operationId": "exportReport",
        "summary": "Export a report",
        "description": "Exports a report as CSV or PDF for download.",
        "x-clearmint-status": "modeled",
        "parameters": [
          {
            "name": "report",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "transactions",
                "cash-flow",
                "summary",
                "subscriptions"
              ]
            },
            "description": "Which report to export."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "pdf"
              ],
              "default": "csv"
            }
          },
          {
            "$ref": "#/components/parameters/MonthFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "The exported file.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/api/reconcile": {
      "post": {
        "tags": [
          "Reconciliation"
        ],
        "operationId": "reconcileAccount",
        "summary": "Reconcile an account",
        "description": "Computes `opening + Σcredits − Σdebits` for an account and compares it to a stated statement balance (basic reconciliation).",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconcileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconcileResult"
                },
                "example": {
                  "opening": 1500,
                  "sumIn": 4200,
                  "sumOut": 3319.45,
                  "computed": 2380.55,
                  "stated": 2380.55,
                  "reconciled": true,
                  "delta": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/stripe/checkout": {
      "post": {
        "tags": [
          "Billing"
        ],
        "operationId": "createCheckoutSession",
        "summary": "Start a subscription checkout",
        "description": "Creates a Stripe Checkout session for the Clear Mint Essentials subscription ($7.99/mo or $79/yr CAD, 30-day free trial) and returns the redirect URL.",
        "x-clearmint-status": "live",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutSession"
                },
                "example": {
                  "ok": true,
                  "url": "https://checkout.stripe.com/c/pay/cs_live_…"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/profile": {
      "get": {
        "tags": [
          "Profile"
        ],
        "operationId": "getProfile",
        "summary": "Get profile & settings",
        "x-clearmint-status": "modeled",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "patch": {
        "tags": [
          "Profile"
        ],
        "operationId": "updateProfile",
        "summary": "Update profile & settings",
        "x-clearmint-status": "modeled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supabase access token. Send as `Authorization: Bearer <token>`."
      }
    },
    "parameters": {
      "MonthFilter": {
        "name": "month",
        "in": "query",
        "required": false,
        "description": "Filter to a single month, `YYYY-MM`. Powers the monthly view and previous/next-month navigation.",
        "schema": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}$",
          "example": "2026-06"
        }
      },
      "ResourceId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Resource id.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was malformed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "Invalid request body"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid access token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "Authentication required"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource was not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "Not found"
            }
          }
        }
      },
      "ValidationError": {
        "description": "The request failed validation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "amount must be a number"
            }
          }
        }
      },
      "ServerError": {
        "description": "Unexpected server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": "Internal error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "service": {
            "type": "string"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Session": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          },
          "plan": {
            "type": "string",
            "enum": [
              "trial",
              "essentials"
            ],
            "description": "Subscription state."
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "bank": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "Chequing",
              "Savings",
              "Money Market",
              "Other"
            ]
          },
          "last4": {
            "type": "string"
          },
          "opening": {
            "type": "number"
          },
          "balance": {
            "type": "number",
            "description": "Current balance (computed from opening + transactions)."
          },
          "currency": {
            "type": "string",
            "default": "CAD"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "AccountInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "bank": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "Chequing",
              "Savings",
              "Money Market",
              "Other"
            ]
          },
          "last4": {
            "type": "string"
          },
          "opening": {
            "type": "number",
            "default": 0
          },
          "currency": {
            "type": "string",
            "default": "CAD"
          }
        }
      },
      "Card": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "last4": {
            "type": "string"
          },
          "balance": {
            "type": "number"
          },
          "limit": {
            "type": "number"
          },
          "currency": {
            "type": "string",
            "default": "CAD"
          }
        }
      },
      "CardInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "last4": {
            "type": "string"
          },
          "balance": {
            "type": "number",
            "default": 0
          },
          "limit": {
            "type": "number",
            "default": 0
          },
          "currency": {
            "type": "string",
            "default": "CAD"
          }
        }
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "desc": {
            "type": "string",
            "description": "Merchant / description."
          },
          "dr": {
            "type": "number",
            "description": "Debit (money out)."
          },
          "cr": {
            "type": "number",
            "description": "Credit (money in)."
          },
          "cat": {
            "type": "string",
            "description": "Category."
          },
          "account": {
            "type": "string"
          },
          "card": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "ofx",
              "csv",
              "pdf"
            ],
            "description": "How the transaction entered Essentials."
          },
          "pending": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "date",
          "desc"
        ]
      },
      "TransactionInput": {
        "type": "object",
        "required": [
          "date",
          "desc"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "desc": {
            "type": "string"
          },
          "dr": {
            "type": "number",
            "default": 0
          },
          "cr": {
            "type": "number",
            "default": 0
          },
          "cat": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "cardId": {
            "type": "string"
          }
        }
      },
      "ParseStatementResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "kind": {
            "type": "string",
            "enum": [
              "ofx",
              "csv",
              "pdf"
            ]
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "last4": {
                "type": "string"
              },
              "bankId": {
                "type": "string"
              },
              "acctType": {
                "type": "string"
              },
              "currency": {
                "type": "string"
              },
              "creditLimit": {
                "type": "number"
              }
            }
          }
        }
      },
      "Earning": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "One-time",
              "Weekly",
              "Biweekly",
              "Semi-monthly",
              "Monthly",
              "Quarterly",
              "Yearly"
            ]
          },
          "cat": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "EarningInput": {
        "type": "object",
        "required": [
          "source",
          "amount"
        ],
        "properties": {
          "source": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "One-time",
              "Weekly",
              "Biweekly",
              "Semi-monthly",
              "Monthly",
              "Quarterly",
              "Yearly"
            ],
            "default": "Monthly"
          },
          "cat": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "Bill": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "Weekly",
              "Biweekly",
              "Semi-monthly",
              "Monthly",
              "Quarterly",
              "Yearly"
            ]
          },
          "cat": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "BillInput": {
        "type": "object",
        "required": [
          "name",
          "amount"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "frequency": {
            "type": "string",
            "default": "Monthly"
          },
          "cat": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "Expense": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "vendor": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "cat": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "ExpenseInput": {
        "type": "object",
        "required": [
          "vendor",
          "amount"
        ],
        "properties": {
          "vendor": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "cat": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "cadence": {
            "type": "string",
            "enum": [
              "Weekly",
              "Biweekly",
              "Monthly",
              "Quarterly",
              "Yearly"
            ]
          },
          "cat": {
            "type": "string"
          },
          "lastCharged": {
            "type": "string",
            "format": "date"
          },
          "monthly": {
            "type": "number",
            "description": "Normalized monthly cost."
          }
        }
      },
      "MonthlySummary": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-06"
          },
          "income": {
            "type": "number"
          },
          "expenses": {
            "type": "number"
          },
          "net": {
            "type": "number"
          }
        }
      },
      "CashFlow": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string"
          },
          "moneyIn": {
            "type": "number"
          },
          "moneyOut": {
            "type": "number"
          },
          "net": {
            "type": "number"
          }
        }
      },
      "FinancialOutlook": {
        "type": "object",
        "properties": {
          "months": {
            "type": "integer"
          },
          "projection": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "month": {
                  "type": "string"
                },
                "income": {
                  "type": "number"
                },
                "expenses": {
                  "type": "number"
                },
                "net": {
                  "type": "number"
                },
                "cumulative": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "ReconcileRequest": {
        "type": "object",
        "required": [
          "accountId"
        ],
        "properties": {
          "accountId": {
            "type": "string"
          },
          "opening": {
            "type": "number"
          },
          "statedBalance": {
            "type": "number",
            "description": "Closing balance printed on the statement."
          }
        }
      },
      "ReconcileResult": {
        "type": "object",
        "properties": {
          "opening": {
            "type": "number"
          },
          "sumIn": {
            "type": "number"
          },
          "sumOut": {
            "type": "number"
          },
          "computed": {
            "type": "number"
          },
          "stated": {
            "type": "number"
          },
          "reconciled": {
            "type": "boolean"
          },
          "delta": {
            "type": "number"
          }
        }
      },
      "CheckoutRequest": {
        "type": "object",
        "required": [
          "billing"
        ],
        "properties": {
          "plan": {
            "type": "string",
            "enum": [
              "essentials"
            ],
            "default": "essentials"
          },
          "billing": {
            "type": "string",
            "enum": [
              "monthly",
              "annual"
            ]
          }
        }
      },
      "CheckoutSession": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Stripe Checkout redirect URL."
          }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string"
          },
          "plan": {
            "type": "string",
            "enum": [
              "trial",
              "essentials"
            ]
          },
          "currency": {
            "type": "string",
            "default": "CAD"
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ProfileInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          }
        }
      }
    }
  }
}
