API reference
Every route mounts under /api/v1/ on your own instance — http://localhost:8000/api/v1/ by default — and returns errors in one unified shape. The schema below is generated from the live OpenAPI spec and drift-checked in CI; the running app serves its own copy at /openapi.json, plus Swagger UI at /docs.
Authentication is an RFC-6750 bearer token. The dashboard itself doesn’t need one; anything else — an agent, a script, another device — does:
curl -H "Authorization: Bearer $FINANCE_API_TOKEN" \ "http://localhost:8000/api/v1/summary?month=2026-03" | jq .Issuing, scoping, and revoking tokens is covered in Agent access. To try the API before installing anything, the demo journal is served read-only at https://gettidings.com/demo/api/v1 (no auth), with its schema at https://gettidings.com/demo/api/openapi.json.
Endpoints at a glance (118 routes)
config
GET /api/v1/config— Get runtime app configuration (storage, demo mode, user_id, features)PUT /api/v1/config— Update runtime app configurationPOST /api/v1/config/test-openai— Validate an OpenAI API key and persist it to data/.env on successPOST /api/v1/config/test-s3-backup— Verify an S3 bucket is a usable attachment-backup target
ingestion
POST /api/v1/transactions— Add a transaction manually (bypasses email pipeline)POST /api/v1/transactions/upload-eml— Upload a raw .eml file and parse via the email pipeline
transactions
GET /api/v1/transactions— List active (non-deleted) transactions for a monthGET /api/v1/transactions/all— Combined active + attention + trash buckets for a monthGET /api/v1/transactions/attention— Transactions needing review (uncategorized, not ignored, not deleted)GET /api/v1/transactions/bulk— Combined transactions across multiple months (max 12)PATCH /api/v1/transactions/bulk— Update categories on many transactions in a single requestGET /api/v1/transactions/latest— Freshness probe — max DateFileName, optionally scoped to a monthGET /api/v1/transactions/trash— Soft-deleted transactions for a monthDELETE /api/v1/transactions/{tx_id}— Hard-delete a transaction (irreversible)PATCH /api/v1/transactions/{tx_id}— Partial update — category, state (active/ignored/trashed), and/or reviewedPUT /api/v1/transactions/{tx_id}/comment— Set or update the user comment on a transactionPOST /api/v1/transactions/{tx_id}/delete— Toggle the soft-delete flag (move to trash / restore)GET /api/v1/transactions/{tx_id}/detail— Full transaction record including email body and headersPUT /api/v1/transactions/{tx_id}/fields— Update editable transaction fields (company, amount, transaction_type)POST /api/v1/transactions/{tx_id}/ignore— Toggle the ignored flag on a transactionPOST /api/v1/transactions/{tx_id}/review— Mark a transaction's category as manually reviewed
categories
GET /api/v1/categories— List predefined categories
summary
GET /api/v1/summary— Monthly spending summary with previous-month comparisonGET /api/v1/summary/trend— Multi-month spending trend (2-12 months)
budget
GET /api/v1/budget/config— Get budget targets and groups for a yearPUT /api/v1/budget/config— Replace budget targets and groups for a yearGET /api/v1/budget/historical-averages— Per-category historical monthly averages over the last N monthsGET /api/v1/budget/status— YTD budget pace status with per-category and per-group breakdown
insights
GET /api/v1/insights/context— Raw context dict the AI briefing uses (for inspection / external automation)POST /api/v1/insights/generate— Kick off background AI generation of a monthly spending briefingGET /api/v1/insights/saved— List saved insight briefings for a monthGET /api/v1/insights/saved/{insight_id}— Get the markdown content of a saved insight briefingGET /api/v1/insights/status— Background generation status (idle/running/error)
overrides
GET /api/v1/overrides— List all category override rulesPOST /api/v1/overrides/consolidate— Atomically replace member overrides with a single canonical overrideGET /api/v1/overrides/duplicates— List override groups sharing a normalized merchant keyGET /api/v1/overrides/match— Preview the tiered category resolver against current overrides + aliasesGET /api/v1/overrides/suggestions— Suggest new override rules from manual category correctionsPOST /api/v1/overrides/suggestions/dismissed— Dismiss an override suggestion (it stops surfacing until a newer correction)DELETE /api/v1/overrides/suggestions/dismissed/{key}— Reverse a previous dismissal (suggestion may resurface)PUT /api/v1/overrides/{company}— Pin a company → category overrideDELETE /api/v1/overrides/{company}— Remove a company → category override
ignore-rules
GET /api/v1/ignore-rules— List all merchant auto-ignore rulesPOST /api/v1/ignore-rules— Add a merchant auto-ignore rulePOST /api/v1/ignore-rules/apply— Backfill Ignored on existing transactions matching a rule (or all rules)GET /api/v1/ignore-rules/suggestions— Suggest ignore rules from merchants you habitually ignore by handGET /api/v1/ignore-rules/suggestions/dismissed— List dismissed ignore-rule suggestions, newest firstPOST /api/v1/ignore-rules/suggestions/dismissed— Dismiss a suggested merchant so it stops being surfacedDELETE /api/v1/ignore-rules/suggestions/dismissed/{merchant}— Reverse a suggestion dismissal so the merchant may resurfaceDELETE /api/v1/ignore-rules/{pattern}— Remove a merchant auto-ignore rule
category-management
POST /api/v1/categories— Add a category, optionally placing it in a budget groupGET /api/v1/categories/icons— Map of user-set category icon overridesPUT /api/v1/categories/icons— Set or update a category's icon overrideDELETE /api/v1/categories/icons— Remove a category's icon override (revert to default)GET /api/v1/categories/managed— List categories with their group memberships and versionDELETE /api/v1/categories/{name}— Delete a category, optionally reassigning its transactionsPUT /api/v1/categories/{name}/group— Move a category to a different budget group, or remove from all groupsGET /api/v1/categories/{name}/usage— Counts of transactions, overrides, and budget membership for a categoryPUT /api/v1/categories/{old_name}— Rename a category and cascade across overrides, budget, transactions
groups
GET /api/v1/groups— Get budget category groups for a yearPUT /api/v1/groups— Replace budget category groups for a year
search
GET /api/v1/transactions/export— Stream filtered transactions as CSVGET /api/v1/transactions/search— Cross-month transaction search with filtersPOST /api/v1/transactions/search-by-filter— Cross-month transaction search with array-shaped filters (POST body)
statements
POST /api/v1/statements/import— Execute import/enrich/update actions for statement transactionsPOST /api/v1/statements/upload— Upload a PDF statement, parse, and reconcile against transactionsPOST /api/v1/statements/{statement_id}/reparse— Re-parse a statement PDF, preserving prior user edits
statements-crud
GET /api/v1/statements— List all uploaded statementsGET /api/v1/statements/{statement_id}— Get a statement with all its parsed transactionsDELETE /api/v1/statements/{statement_id}— Delete a statement and its parsed transactionsGET /api/v1/statements/{statement_id}/download— Download the original PDF for a statementPATCH /api/v1/statements/{statement_id}/transactions— Bulk-update statement transaction actionsPATCH /api/v1/statements/{statement_id}/transactions/{row_id}— Update a single statement transaction's action (auto-save), keyed by row_id
attachments
GET /api/v1/attachments— List attachments, optionally filtered by link status and kindPOST /api/v1/attachments— Upload a receipt or document, optionally linked to a transactionDELETE /api/v1/attachments/{attachment_id}— Delete an attachment and its file from diskGET /api/v1/attachments/{attachment_id}/candidates— Rank the transactions a parsed receipt might explainGET /api/v1/attachments/{attachment_id}/file— Download the attachment file, served inline with our stored content-typePOST /api/v1/attachments/{attachment_id}/link— Link an attachment to a transaction, or unlink itPOST /api/v1/attachments/{attachment_id}/parse— Parse a receipt attachment with the configured AI providerGET /api/v1/transactions/{tx_id}/attachments— List attachments linked to a transaction
income-statement
GET /api/v1/income-statement— Annual income vs. expenses view with projection and savings rate
tax
GET /api/v1/tax-pack— Calendar-year tax pack: claim-line totals with per-transaction evidenceGET /api/v1/tax-pack/export— Download the year's tax pack as a zip of CSVs plus evidence filesPOST /api/v1/tax-pack/items— Force a transaction into a claim line, or exclude it from oneDELETE /api/v1/tax-pack/items/{tx_id}— Clear a per-transaction tax overrideGET /api/v1/tax-pack/lines— Selectable claim lines for the include-override picker
merchants
GET /api/v1/merchants/intelligence— Recurring-charge detection, price-change alerts, committed burn rate
journal
GET /api/v1/journal— Day-grouped transaction timeline for a month
daily-summaries
GET /api/v1/journal/summaries— List saved AI day summaries for a monthPOST /api/v1/journal/summaries/generate— Kick off background AI generation of day summaries for a monthGET /api/v1/journal/summaries/status— Background generation status (idle/running/error)
merchant-aliases
GET /api/v1/merchant-aliases— List all merchant aliases (raw → canonical mappings)PUT /api/v1/merchant-aliases/{raw_name}— Create or update a merchant alias (raw → canonical)DELETE /api/v1/merchant-aliases/{raw_name}— Delete a merchant alias by raw name
data
POST /api/v1/data/export— Stream a full-data backup zip (transactions + config)POST /api/v1/data/import/commit— Apply a previously-previewed import using the chosen strategyPOST /api/v1/data/import/preview— Stage a backup upload and return a dry-run dedup summaryGET /api/v1/data/s3-backup-status— Read the S3 attachment-backup config and last-run state
parse-failures
GET /api/v1/parse-failures— List quarantined parse failures (summaries only, no email body)POST /api/v1/parse-failures/retry-all— Re-run the deterministic parsers across a whole institution's quarantined backlogGET /api/v1/parse-failures/{failure_id}— Get a single quarantined parse failure, including the email bodyDELETE /api/v1/parse-failures/{failure_id}— Dismiss a quarantined parse failurePOST /api/v1/parse-failures/{failure_id}/resolve— Record a hand-entered transaction for a quarantined email and mark it resolvedPOST /api/v1/parse-failures/{failure_id}/retry— Re-run the deterministic parsers against a quarantined emailPOST /api/v1/parse-failures/{failure_id}/to-fixture— Write a scrubbed test-fixture pair from a quarantined email (dev checkout only)
auth
POST /api/v1/auth/chatgpt/disconnect— Disconnect a previously-linked ChatGPT accountPOST /api/v1/auth/chatgpt/start— Begin the ChatGPT device-code sign-in via the Codex CLIGET /api/v1/auth/chatgpt/status— Poll the ChatGPT sign-in state
webapp-auth
POST /api/v1/auth/login— Issue a webapp session cookiePOST /api/v1/auth/logout— Clear the caller's webapp session cookiePOST /api/v1/auth/set-password— Set or change the webapp password (TOFU on first set)POST /api/v1/auth/sign-out-all— Bump session_version, invalidating all existing cookies
health
GET /api/v1/health— Liveness probe with last-activity snapshot
coverage
GET /api/v1/coverage— Per-institution bank-alert cadence and passive email-capture rate
activity
GET /api/v1/activity— List agent activity ledger entries, newest firstPOST /api/v1/activity/{entry_id}/revert— Revert a single ledger entry, restoring the resource's prior stateGET /api/v1/whoami— Resolve the current caller's identity (token, session, TOFU, or dev-bypass)