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
NEWKAPITAH 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/mcpAuthentication
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_xxxxxxxxxxxxxxxxxxxxxxxx3. Base URL
https://kapitah.com/api/public/v1All 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
Table7. 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
BalanceSheet8. Errors
401missing / invalid / expired token410token has been revoked404unknown resource or report400invalid filter / report parameter429rate-limited