Skip to content

Finance API

Related documentation: Finance Module Backend · Access Control Integration · Error Contract

This page documents the current Finance backend route surface at a practical level.

It is not a line-by-line dump of the Finance repo README. It focuses on the contract and runtime rules that matter for platform work.

  • runtime: Node / TypeScript backend
  • route style: src/api/**/route.ts
  • route namespace: /api/*
  • health endpoint: GET /health

Protected internal company-scoped Finance routes require:

  • valid auth
  • valid x-org
  • membership / scope from Auth
  • finance entitlement from Core

If the selected company is not commercially entitled to Finance:

  • status: 403
  • code: finance_addon_required

Vendor routes use the vendor auth flow and vendor JWT claims.

They still operate inside Finance because vendor invoice submission and related operational workflows are Finance-owned.

For many internal routes, the active company comes from:

  • x-org: <companyId>

Accepted value:

  • Core/Finance canonical company UUID
  • kisumCompanyId when linked

Finance resolves the company from Core first. Responses may enrich company/BU display fields from Core; Finance does not rely on local Prisma Company / BusinessUnit relations.

Examples:

  • GET /api/admin/companies
  • GET /api/admin/companies/{id}
  • GET /api/admin/business-units/by-company
  • GET|POST|PATCH|DELETE /api/admin/business-units
  • vendor / category / stats / audit-log / sync-error admin routes

Important rule:

  • company master writes are removed from Finance
  • business-unit master writes go through Core

Examples:

  • GET /api/bills
  • GET /api/bills/{id}
  • GET /api/bills/{id}/signed-pdf
  • POST /api/bills
  • PATCH /api/bills/{id}

These are Finance-owned expense/AP workflows.

Examples:

  • GET /api/income
  • GET /api/income/{id}
  • POST /api/income
  • PATCH /api/income/{id}
  • related income payment and summary helpers

These are Finance-owned revenue/AR workflows.

Machine Venue deposit mode:

  • POST /api/income with source=venue_deposit
  • PATCH /api/income/{id} with source=venue_deposit

Status: live

Primary caller:

  • Backend-Kisum-Venues

Purpose:

  • create or update the real Finance-side deposit invoice while reusing the normal income/Xero flow

Boundary rules:

  • machine-authenticated with Finance INTERNAL_API_KEY
  • tenant still selected with x-org
  • Venue must send a normal income-compatible payload, not a reduced pseudo-finance payload

Examples:

  • POST /api/auth/vendor/login
  • POST /api/auth/vendor/forgot-password
  • GET /api/vendor/invoices
  • GET /api/vendor/invoices/{id}
  • POST /api/vendor/upload
  • vendor profile / account / user routes

Examples:

  • GET /api/kisum/{companyId}
  • GET /api/kisum/{companyId}/events
  • GET /api/kisum/{companyId}/events/{eventId}
  • GET /api/kisum/{companyId}/events/{eventId}/invoices
  • GET /api/kisum/{companyId}/events/{eventId}/income/summary
  • GET /api/kisum/{companyId}/events/{eventId}/income/highlight
  • GET /api/kisum/event-expense/find-by-event/{id}

These remain supported compatibility/read routes.

Important current rule:

  • company resolution for these routes is now Core-first
  • they no longer trust the Finance local company compatibility row as the first resolver

Examples:

  • connect / callback
  • sync
  • accounts
  • currencies
  • taxes
  • related finance integration helpers

These remain Finance-owned.

These Finance endpoints are intentionally disabled and return 405 company_master_write_removed:

  • POST /api/admin/companies
  • PUT /api/admin/companies
  • PATCH /api/admin/companies
  • DELETE /api/admin/companies
  • POST /api/admin/companies/{id}/request-deletion

Use Core/Admin for company lifecycle.

Finance still exposes admin BU operations, but BU master truth is not local anymore.

Current behavior:

  • Finance calls Core for BU master write/read behavior
  • Finance syncs the local compatibility row afterward for finance-domain joins

Finance is not the source of truth for:

  • users
  • company memberships
  • business-unit memberships

Those come from Auth.

Membership alone is not enough for tenant Finance access.

A company can only use Finance if Core says the company has the active finance add-on / enabled module.

Finance commonly returns:

  • 400 validation errors
  • 401 unauthorized
  • 403 forbidden / no company scope / no finance entitlement
  • 404 missing resource
  • 405 removed company master write behavior
  • 409 conflict
  • 500 internal error

The two most important current Finance-specific platform cases are:

  • 403 finance_addon_required
  • 405 company_master_write_removed

When extending Finance API behavior:

  • do not add new company master write flows
  • do not add new BU master ownership in Finance
  • use Auth for user and membership truth
  • use Core for company, BU, and entitlement truth
  • only keep local compatibility rows where finance-domain persistence still requires them

For deeper implementation detail, the repo-local sources are still useful references:

  • Backend-Kisum-Finance/README_API.md
  • Backend-Kisum-Finance/README_DOCS.md
  • Backend-Kisum-Finance/README_AUTH_API.md

But this page should be treated as the docs-site summary of the current platform behavior.