Developer integrations

KAPITAH® API & MCP

Read-only access to a single company's accounting, AR, AP, inventory, and reporting data via REST or the Model Context Protocol (MCP). Designed for consultants, accountants, BI tools, and AI assistants.

MCP server — connect an AI assistant

NEW

KAPITAH exposes its read-only tools as an MCP server. Any MCP client — Claude Code, Cursor, Windsurf, or your own agent — can query live company data after you provide a token.

  • Chart of accounts, journal entries & lines
  • Customers, invoices, credit notes, receipts
  • Vendors, bills, credit notes, payments
  • Items, warehouses, stock movements, purchase/sales orders
  • Balance sheet, P&L, cash flow, trial balance, budget vs actual, tax, CFO metrics

Endpoint

https://app.kapitah.com/api/public/mcp

Authentication

Generate a read-only API token from Settings → API Tokens inside a company. The token is shown once and starts with kpt_live_…. Pass it as a Bearer token in the MCP client's headers.

Claude Code configuration

{
  "mcpServers": {
    "kapitah": {
      "url": "https://app.kapitah.com/api/public/mcp",
      "headers": {
        "Authorization": "Bearer kpt_live_xxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Replace kpt_live_xxxxxxxxxxxxxxxxxxxxxxxx with the token created above. Claude.ai users can also connect via OAuth 2.1 from the Lovable connectors panel.

1. Get a REST token

Ask a company owner or admin to generate a token from Settings → API Tokens. The token is shown only once and looks like kpt_live_….

2. Authenticate

Send the token in the Authorization header:

Authorization: Bearer kpt_live_xxxxxxxxxxxxxxxxxxxxxxxx

3. Base URL

https://kapitah.com/api/public/v1

All endpoints return JSON. All requests are scoped to the company that owns the token.

4. Available resources

Financials/accounts, /journal-entries, /journal-lines
AR/customers, /invoices, /credit-notes, /customer-receipts
AP/vendors, /bills, /vendor-credit-notes, /vendor-payments
Inventory & Ops/items, /item-categories, /warehouses, /stock-movements, /purchase-orders, /sales-orders
Reports/reports/balance-sheet, /reports/income-statement, /reports/cash-flow, /reports/trial-balance, /reports/account-activity, /reports/budget-vs-actual, /reports/tax, /reports/cash-forecast, /reports/cfo-metrics, /reports/cfo-trends
Meta/company, /healthz

5. Query parameters

  • page (default 1), limit (default 100, max 500)
  • updated_since=YYYY-MM-DD — incremental pulls
  • Resource-specific filters (e.g. status, customer_id, vendor_id, is_active)

6. Examples

curl

curl -H "Authorization: Bearer $KAPITAH_TOKEN" \
  "https://kapitah.com/api/public/v1/invoices?status=posted&limit=200&page=1"

Python (pandas)

import os, requests, pandas as pd

TOKEN = os.environ["KAPITAH_TOKEN"]
r = requests.get(
    "https://kapitah.com/api/public/v1/journal-lines",
    headers={"Authorization": f"Bearer {TOKEN}"},
    params={"limit": 500, "page": 1},
)
r.raise_for_status()
df = pd.DataFrame(r.json()["data"])
print(df.head())

Power BI (Power Query M)

let
    Token = "kpt_live_xxxxxxxxxxxxxxxxxxxxxxxx",
    Source = Json.Document(Web.Contents("https://kapitah.com/api/public/v1/invoices", [
        Headers = [ #"Authorization" = "Bearer " & Token ],
        Query   = [ limit = "500", page = "1" ]
    ])),
    Data = Source[data],
    Table = Table.FromRecords(Data)
in
    Table

7. Response shape

{
  "data": [ { ... }, { ... } ],
  "pagination": { "page": 1, "limit": 100, "total": 1240, "has_more": true }
}

Reports under /reports/… return { "data": [...] } with no pagination (each report is a single result set).

7b. Use from Excel (Power Query)

Download the pre-wired workbook from Settings → API Tokens → Excel dashboard, or build your own with this M snippet (Data → Get Data → From Other Sources → Blank Query):

let
    Token   = "kpt_live_xxxxxxxxxxxxxxxxxxxxxxxx",
    BaseUrl = "https://kapitah.com/api/public/v1",

    // Generic paginated GET — loops pages until empty.
    KapitahGet = (path as text, optional query as record) =>
        let
            Page = (n) => Json.Document(Web.Contents(BaseUrl, [
                RelativePath = path,
                Query = Record.Combine({ query ?? [], [ page = Text.From(n), limit = "500" ] }),
                Headers = [ #"Authorization" = "Bearer " & Token ]
            ])),
            Pages = List.Generate(
                () => [p = 1, r = Page(1)],
                each List.Count(_[r][data]) > 0,
                each [p = _[p] + 1, r = Page(_[p] + 1)],
                each _[r][data]
            )
        in List.Combine(Pages),

    // Reports return a single set (no pagination).
    KapitahReport = (slug as text, query as record) =>
        Json.Document(Web.Contents(BaseUrl, [
            RelativePath = "reports/" & slug,
            Query = query,
            Headers = [ #"Authorization" = "Bearer " & Token ]
        ]))[data],

    Invoices     = Table.FromRecords(KapitahGet("invoices")),
    Today        = Date.ToText(Date.From(DateTime.LocalNow()), "yyyy-MM-dd"),
    BalanceSheet = Table.FromRecords(KapitahReport("balance-sheet", [ as_of = Today ]))
in
    BalanceSheet

8. Errors

  • 401 missing / invalid / expired token
  • 410 token has been revoked
  • 404 unknown resource or report
  • 400 invalid filter / report parameter
  • 429 rate-limited
v1 is read-only. Write endpoints, webhooks, and OAuth are planned for v2.