> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kairn.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# FinTech Expenses

> Expense submission, policy enforcement, and budget reporting — without a spreadsheet.

## The problem

Finance teams spend hours categorising expenses, chasing receipts, and building reports. Month-end is a scramble. Employees don't know their budget status until it's too late.

**What Kairn enables:** A per-employee finance agent that handles expense submission, enforces policy at point of entry, and surfaces budget status in real time — no spreadsheets, no manual review for in-policy items.

***

## Setup

**1. Define the soul with policy baked in**

```ts theme={null}
await kairn.souls.create({
  name: 'finance',
  label: 'Finance Assistant',
  soulMd: `
    You are a finance assistant for employees submitting and tracking expenses.

    Your job:
    - Help employees log and categorise expenses
    - Check whether an expense is within policy before approving
    - Answer questions about budget status and spend
    - Flag policy violations and explain what's allowed

    Behaviour rules:
    - Always check memory for the employee's budget and spend before answering
    - Apply company expense policy strictly — do not approve out-of-policy items
    - Extract structured data from natural language (amount, category, vendor, date)
    - Write every approved expense to memory immediately
    - If an expense is borderline, explain the policy and ask for a business justification
    - Never fabricate policy rules — if unsure, direct to finance@company.com

    Expense categories: travel, accommodation, meals, software, hardware, training, other
    Meal limit per day: $75
    Travel booking: must be booked 7+ days in advance unless emergency
    Hardware approval: required above $500
  `,
  defaultModel: 'anthropic/claude-sonnet-4-6',
})
```

**2. Seed employee budget context**

```ts theme={null}
async function seedEmployeeBudget(employeeId: string) {
  const employee = await hr.getEmployee(employeeId)
  const budget   = await finance.getBudget(employeeId, currentQuarter())
  const expenses = await finance.getExpenses(employeeId, currentQuarter())

  const totalSpend = expenses.reduce((sum, e) => sum + e.amountUsd, 0)
  const byCategory = groupBy(expenses, 'category')

  await kairn.memory.set(employeeId, 'default', {
    name:             employee.firstName,
    department:       employee.department,
    manager:          employee.managerName,
    quarterly_budget: String(budget.totalUsd),
    budget_remaining: String(budget.totalUsd - totalSpend),
    quarter:          currentQuarter(),
    spend_travel:     String(byCategory.travel?.reduce((s, e) => s + e.amountUsd, 0) ?? 0),
    spend_meals:      String(byCategory.meals?.reduce((s, e) => s + e.amountUsd, 0) ?? 0),
    spend_software:   String(byCategory.software?.reduce((s, e) => s + e.amountUsd, 0) ?? 0),
    spend_hardware:   String(byCategory.hardware?.reduce((s, e) => s + e.amountUsd, 0) ?? 0),
    pending_receipts: String(expenses.filter(e => !e.receiptUploaded).length),
  })
}
```

**3. Expense submission endpoint**

```ts theme={null}
// POST /api/finance/expense
export async function POST(req: Request) {
  const { employeeId, message } = await req.json()

  await seedEmployeeBudget(employeeId)

  const result = await kairn.invoke({
    agent: 'finance',
    userId: employeeId,
    input: message,
    sessionId: `finance_${employeeId}_${currentQuarter()}`,
  })

  // Sync new expenses to your finance system
  if (result.memoryDelta) {
    const newExpenses = Object.entries(result.memoryDelta)
      .filter(([key]) => key.startsWith('expense_'))

    for (const [, value] of newExpenses) {
      await finance.createExpense({ employeeId, ...JSON.parse(value as string) })
    }
  }

  return Response.json({ response: result.output })
}
```

**4. Month-end report mandate**

At month-end, every employee gets a personalised spend summary — no manual work from finance.

```ts theme={null}
async function scheduleMonthlyReports(employeeIds: string[]) {
  for (const employeeId of employeeIds) {
    await kairn.mandates.create({
      userId: employeeId,
      soul: 'finance',
      label: 'Monthly spend summary',
      taskPrompt: `
        Review this employee's quarterly spend from memory.
        Calculate:
        - Total spend vs budget (as %)
        - Spend by category with percentage of total
        - Whether they are on track for the quarter

        Write a clear summary under "monthly_report" in plain language.
        Write "budget_health" as one of: "on_track" | "watch" | "over_budget"
      `,
      trigger: {
        type: 'cron',
        cron: '0 9 1 * *', // 1st of each month at 9am UTC
      },
    })
  }
}
```

**5. Budget status widget**

```ts theme={null}
export async function getBudgetStatus(employeeId: string) {
  const memory    = await kairn.memory.get(employeeId, 'default')
  const budget    = Number(memory.quarterly_budget)
  const remaining = Number(memory.budget_remaining)
  const spent     = budget - remaining

  return {
    employeeName:   memory.name,
    quarter:        memory.quarter,
    budget,
    spent,
    remaining,
    utilisationPct: Math.round((spent / budget) * 100),
    budgetHealth:   memory.budget_health ?? 'on_track',
    monthlyReport:  memory.monthly_report ?? null,
    pendingReceipts: Number(memory.pending_receipts ?? 0),
    breakdown: {
      travel:   Number(memory.spend_travel ?? 0),
      meals:    Number(memory.spend_meals ?? 0),
      software: Number(memory.spend_software ?? 0),
      hardware: Number(memory.spend_hardware ?? 0),
    },
  }
}
```

***

## Example conversations

> [accordion] Submitting an expense
>
> ```
> Employee: Lunch with the Acme team yesterday, $68 at Nobu.
>
> Agent:    Logged — client meal at Nobu, $68 on 6 March.
>           Category: meals (client entertainment)
>
>           That's within your $75/day meal limit.
>           Remaining quarterly budget: $1,840 of $2,500.
>
>           Don't forget to upload your receipt — you have 3 pending.
>           Need anything else?
> ```

> [accordion] Policy violation
>
> ```
> Employee: I need to book flights to New York for next Tuesday.
>
> Agent:    Happy to help with that.
>
>           Quick heads-up: company travel policy requires booking
>           7+ days in advance. Next Tuesday is 6 days away, so this
>           would need a business justification for the exception.
>
>           Is this an emergency trip, or can you book for the week
>           after? If it's urgent, include a brief justification and
>           I'll flag it for your manager Sarah to approve.
> ```

> [accordion] Budget check
>
> ```
> Employee: How much do I have left this quarter?
>
> Agent:    Here's your Q1 snapshot:
>
>           Budget:    $2,500
>           Spent:     $1,820 (73%)
>           Remaining: $680
>
>           Biggest spend categories:
>           - Travel: $980 (54%)
>           - Software: $540 (30%)
>           - Meals: $300 (16%)
>
>           You're on track for the quarter. At current pace you'll
>           come in around $2,100 — $400 under budget.
> ```

***

## What this unlocks

> [card] Zero-friction expense logging
>
> Employees submit in plain English. Agent categorises, validates policy, and logs — no form to fill.

> [card] Policy enforcement at submission
>
> Violations caught before finance reviews, not after. Exceptions flagged with justification automatically.

> [card] Real-time budget visibility
>
> Every employee knows their status without asking finance. Budget data lives in memory, always current.

> [card] Automated month-end reporting
>
> Personalised summaries generated automatically. Finance team reviews exceptions only, not routine spend.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.