API Reference - grumnuts/dosh GitHub Wiki

API Reference

All endpoints are prefixed with /api. All routes require an authenticated session cookie except where noted.

Money amounts are always integer cents (e.g. 150025 = $1500.25).


Authentication

GET /api/setup/status

Returns whether initial setup has been completed. No authentication required.

POST /api/setup/init

Creates the first user and default accounts. Only available before setup is complete. No authentication required.

Body: { username, password }

POST /api/auth/login

Creates a session. Sets a 30-day httpOnly session cookie.

Body: { username, password }

POST /api/auth/logout

Clears the session cookie.


Users

GET /api/users

Returns all users.

POST /api/users

Creates a new user.

Body: { username, password }


Settings

GET /api/settings

Returns all settings as key/value pairs.

PUT /api/settings/:key

Updates a setting.

Body: { value } — e.g. { "value": "1" } for week_start_day (0 = Sunday, 1 = Monday)


Accounts

GET /api/accounts

Returns all active accounts with calculated current balances.

POST /api/accounts

Creates an account.

Body: { name, type, starting_balance, notes?, goal_amount? }

type: transactional | savings | debt

PUT /api/accounts/:id

Updates an account.

Body: { name?, type?, notes?, goal_amount? }

PATCH /api/accounts/reorder

Bulk updates sort order.

Body: [{ id, sort_order }]

POST /api/accounts/:id/reconcile

Creates a reconciliation adjustment transaction.

Body: { actual_balance } — the real-world balance in cents


Budget

GET /api/budget/week/:weekStart

Returns the full budget for a given week. weekStart is a date string (YYYY-MM-DD) for the Sunday that starts the week.

Response includes: groups, categories with budgeted/spent/balance, covers, unallocated income.

GET /api/budget/groups

Returns all budget groups.

POST /api/budget/groups

Creates a group.

Body: { name, is_income? }

PUT /api/budget/groups/:id

Updates a group.

Body: { name?, is_income? }

DELETE /api/budget/groups/:id

Deletes a group. Only succeeds if the group has no categories.

PATCH /api/budget/groups/reorder

Bulk updates group sort order.

Body: [{ id, sort_order }]

GET /api/budget/categories

Returns all budget categories.

POST /api/budget/categories

Creates a category.

Body: { group_id, name, budgeted_amount, period, notes? }

period: weekly | fortnightly | monthly | quarterly | annually

PUT /api/budget/categories/:id

Updates a category. Changes to budgeted_amount are recorded in budget history.

Body: { name?, budgeted_amount?, period?, notes?, is_active? }

DELETE /api/budget/categories/:id

Soft-deletes a category (sets is_active = false).

PATCH /api/budget/categories/reorder

Bulk updates category sort order.

Body: [{ id, sort_order }]


Transactions

GET /api/transactions

Returns a paginated list of transactions.

Query params: account_id, category_id, start_date, end_date, search, page, limit

POST /api/transactions

Creates a transaction. Optionally include splits.

Body:

{
  "date": "2026-03-01",
  "account_id": 1,
  "payee": "Woolworths",
  "description": "",
  "amount": -8500,
  "category_id": 3,
  "type": "transaction",
  "splits": [
    { "category_id": 3, "amount": -6000, "note": "Groceries" },
    { "category_id": 7, "amount": -2500, "note": "Cleaning" }
  ]
}

If splits is provided, category_id on the parent is ignored.

PUT /api/transactions/:id

Updates a transaction.

DELETE /api/transactions/:id

Soft-deletes a transaction.

PATCH /api/transactions/bulk

Bulk reassigns or deletes transactions.

Body: { ids: number[], action: "recategorise" | "delete", category_id?: number }

GET /api/transactions/uncategorised-count

Returns count of transactions with no category assigned.


CSV Import

POST /api/import/preview

Parses a CSV file and returns rows with duplicate detection applied.

Body: multipart/form-data with file and column mapping fields.

POST /api/import/confirm

Imports selected rows. Rules are applied automatically.

Body: { account_id, rows: [...] } (rows from the preview response, filtered to selected ones)


Rules

GET /api/rules

Returns all rule groups with nested rules, conditions, and actions.

POST /api/rules/groups

Creates a rule group.

Body: { name }

PUT /api/rules/groups/:id

Updates a rule group.

POST /api/rules

Creates a rule.

Body: { group_id, name, condition_logic, is_enabled, conditions: [...], actions: [...] }

PUT /api/rules/:id

Updates a rule.

DELETE /api/rules/:id

Deletes a rule and its conditions/actions.

POST /api/rules/:id/run

Applies a single rule to all transactions.

POST /api/rules/run-all

Applies all enabled rules to all transactions.


Reports

GET /api/reports/years

Returns distinct years that have transaction data.

GET /api/reports/spending?year=YYYY

Category spending totals by month.

GET /api/reports/overspend?year=YYYY

Categories and months where spending exceeded budget.

GET /api/reports/payees?year=YYYY

Income and expense totals per payee.

GET /api/reports/in-vs-out?year=YYYY

Monthly income vs expense breakdown.

GET /api/reports/net-worth?year=YYYY

Account balances by month.

GET /api/reports/goals

Savings account balance history with goal amounts for projection.


Payees

GET /api/payees

Returns all payee names for autocomplete.


Audit

GET /api/audit

Returns paginated audit log entries.

Query params: page, limit