← Back to Skills Marketplace
thisisjeron

Actual Budget

by ThisIsJeron · GitHub ↗ · v1.0.2
cross-platform ⚠ suspicious
3822
Downloads
2
Stars
11
Active Installs
3
Versions
Install in OpenClaw
/install actual-budget
Description
Query and manage personal finances via the official Actual Budget Node.js API. Use for budget queries, transaction imports/exports, account management, categorization, rules, schedules, and bank sync with self-hosted Actual Budget instances.
README (SKILL.md)

Actual Budget API

Official Node.js API for Actual Budget. Runs headless — works on local budget data synced from your server.

Installation

npm install @actual-app/api

Environment Variables

Variable Required Description
ACTUAL_SERVER_URL Yes Server URL (e.g., https://actual.example.com)
ACTUAL_PASSWORD Yes Server password
ACTUAL_SYNC_ID Yes Budget Sync ID (Settings → Advanced → Sync ID)
ACTUAL_DATA_DIR No Local cache directory for budget data (defaults to cwd)
ACTUAL_ENCRYPTION_PASSWORD No E2E encryption password, if enabled
NODE_EXTRA_CA_CERTS No Path to CA certificate file for self-signed certs

Self-Signed Certificates

If your Actual Budget server uses a self-signed certificate:

  1. Recommended: Add your CA to the system trust store, or
  2. Alternative: Set NODE_EXTRA_CA_CERTS=/path/to/your-ca.pem to trust your specific CA

Avoid disabling TLS verification entirely — it exposes you to man-in-the-middle attacks.

Quick Start

const api = require('@actual-app/api');

await api.init({
  dataDir: process.env.ACTUAL_DATA_DIR || '/tmp/actual-cache',
  serverURL: process.env.ACTUAL_SERVER_URL,
  password: process.env.ACTUAL_PASSWORD,
});

await api.downloadBudget(
  process.env.ACTUAL_SYNC_ID,
  process.env.ACTUAL_ENCRYPTION_PASSWORD ? { password: process.env.ACTUAL_ENCRYPTION_PASSWORD } : undefined
);

// ... do work ...

await api.shutdown();

Core Concepts

  • Amounts are integers in cents: $50.00 = 5000, -1200 = expense of $12.00
  • Dates use YYYY-MM-DD, months use YYYY-MM
  • IDs are UUIDs — use getIDByName(type, name) to look up by name
  • Convert with api.utils.amountToInteger(123.45)12345

Common Operations

Get Budget Overview

const months = await api.getBudgetMonths();        // ['2026-01', '2026-02', ...]
const jan = await api.getBudgetMonth('2026-01');   // { categoryGroups, incomeAvailable, ... }

Accounts

const accounts = await api.getAccounts();
const balance = await api.getAccountBalance(accountId);
const newId = await api.createAccount({ name: 'Checking', type: 'checking' }, 50000); // $500 initial
await api.closeAccount(id, transferToAccountId);  // transfer remaining balance

Transactions

// Get transactions for date range
const txns = await api.getTransactions(accountId, '2026-01-01', '2026-01-31');

// Import with deduplication + rules (preferred for bank imports)
const { added, updated } = await api.importTransactions(accountId, [
  { date: '2026-01-15', amount: -2500, payee_name: 'Grocery Store', notes: 'Weekly run' },
  { date: '2026-01-16', amount: -1200, payee_name: 'Coffee Shop', imported_id: 'bank-123' },
]);

// Update a transaction
await api.updateTransaction(txnId, { category: categoryId, cleared: true });

Categories & Payees

const categories = await api.getCategories();
const groups = await api.getCategoryGroups();
const payees = await api.getPayees();

// Create
const catId = await api.createCategory({ name: 'Subscriptions', group_id: groupId });
const payeeId = await api.createPayee({ name: 'Netflix', category: catId });

Budget Amounts

await api.setBudgetAmount('2026-01', categoryId, 30000);  // budget $300
await api.setBudgetCarryover('2026-01', categoryId, true);

Rules

const rules = await api.getRules();
await api.createRule({
  stage: 'pre',
  conditionsOp: 'and',
  conditions: [{ field: 'payee', op: 'is', value: payeeId }],
  actions: [{ op: 'set', field: 'category', value: categoryId }],
});

Schedules

const schedules = await api.getSchedules();
await api.createSchedule({
  payee: payeeId,
  account: accountId,
  amount: -1500,
  date: { frequency: 'monthly', start: '2026-01-01', interval: 1, endMode: 'never' },
});

Bank Sync

await api.runBankSync({ accountId });  // GoCardless/SimpleFIN

Sync & Shutdown

await api.sync();      // push/pull changes to server
await api.shutdown();  // always call when done

ActualQL Queries

For complex queries, use ActualQL:

const { q, runQuery } = require('@actual-app/api');

// Sum expenses by category this month
const { data } = await runQuery(
  q('transactions')
    .filter({
      date: [{ $gte: '2026-01-01' }, { $lte: '2026-01-31' }],
      amount: { $lt: 0 },
    })
    .groupBy('category.name')
    .select(['category.name', { total: { $sum: '$amount' } }])
);

// Search transactions
const { data } = await runQuery(
  q('transactions')
    .filter({ 'payee.name': { $like: '%grocery%' } })
    .select(['date', 'amount', 'payee.name', 'category.name'])
    .orderBy({ date: 'desc' })
    .limit(20)
);

Operators: $eq, $lt, $lte, $gt, $gte, $ne, $oneof, $regex, $like, $notlike Splits: .options({ splits: 'inline' | 'grouped' | 'all' })

Helpers

// Look up ID by name
const acctId = await api.getIDByName('accounts', 'Checking');
const catId = await api.getIDByName('categories', 'Food');
const payeeId = await api.getIDByName('payees', 'Amazon');

// List budgets
const budgets = await api.getBudgets();  // local + remote files

Transfers

Transfers use special payees. Find transfer payee by transfer_acct field:

const payees = await api.getPayees();
const transferPayee = payees.find(p => p.transfer_acct === targetAccountId);
await api.importTransactions(fromAccountId, [
  { date: '2026-01-15', amount: -10000, payee: transferPayee.id }
]);

Split Transactions

await api.importTransactions(accountId, [{
  date: '2026-01-15',
  amount: -5000,
  payee_name: 'Costco',
  subtransactions: [
    { amount: -3000, category: groceryCatId },
    { amount: -2000, category: householdCatId },
  ]
}]);

Bulk Import (New Budget)

For migrating from another app:

await api.runImport('My-New-Budget', async () => {
  for (const acct of myData.accounts) {
    const id = await api.createAccount(acct);
    await api.addTransactions(id, myData.transactions.filter(t => t.acctId === id));
  }
});

Reference

Full API: https://actualbudget.org/docs/api/reference ActualQL: https://actualbudget.org/docs/api/actual-ql

Usage Guidance
Before installing or enabling this skill: 1) Note the metadata/manifest mismatch — SKILL.md requires sensitive env vars (server URL, password, sync id) but the registry metadata lists none. Ask the author to provide a source repository or homepage and to update the manifest to declare required credentials. 2) Verify the npm package @actual-app/api on npmjs.org or the official Actual Budget GitHub repo; inspect the package code or its provenance before running npm install. 3) Limit risk: run the package in an isolated environment or container, and prefer a dedicated, least-privilege service account or short-lived credential rather than your main password. 4) Be aware that ACTUAL_PASSWORD and ACTUAL_SYNC_ID are sensitive; ensure the platform only exposes environment variables explicitly declared and necessary. 5) If you cannot verify the author or upstream package, do not supply production credentials — ask for a vetted implementation or provide a read-only/test account. 6) If you proceed, consider setting ACTUAL_DATA_DIR explicitly to a safe location (not cwd) and carefully manage NODE_EXTRA_CA_CERTS to avoid trusting unexpected certificates.
Capability Analysis
Type: OpenClaw Skill Name: actual-budget Version: 1.0.2 The skill bundle is benign. It provides instructions and code examples for interacting with the Actual Budget API to manage personal finances. While it requires sensitive financial credentials (e.g., `ACTUAL_PASSWORD`, `ACTUAL_SYNC_ID`) via environment variables, this is necessary for its stated purpose and there is no evidence of unauthorized data exfiltration to external endpoints or access to unrelated sensitive files. The `SKILL.md` content is purely instructional and does not contain any prompt injection attempts or malicious execution patterns beyond standard `npm install` for the intended library.
Capability Assessment
Purpose & Capability
The skill's description and SKILL.md clearly require access to an Actual Budget server (ACTUAL_SERVER_URL, ACTUAL_PASSWORD, ACTUAL_SYNC_ID, etc.) which is coherent with the stated purpose. HOWEVER the registry metadata claims no required environment variables or credentials. The absence of a declared primary credential and no homepage/source for verification is inconsistent with a skill that needs sensitive server credentials.
Instruction Scope
The SKILL.md stays within the stated purpose: it documents how to install and call @actual-app/api, which operations to run (sync, import, bank sync, queries), and which env vars and paths are used. It does not instruct indiscriminate file reads or exfiltration. Minor concerns: the default data dir can be the current working directory (cwd) which could expose more local files than intended; and it instructs use of NODE_EXTRA_CA_CERTS (a path to a cert file) which means the agent/process will read that file.
Install Mechanism
This is an instruction-only skill (no install spec), which is low-risk for skill bundle installation. However, SKILL.md tells users/agents to run `npm install @actual-app/api` — that will fetch code from npm (remote dependency). Because the skill's source/homepage are unknown, you cannot verify the upstream npm package or its integrity from the skill metadata alone. Users should validate the npm package origin before installing.
Credentials
The environment variables documented in SKILL.md (ACTUAL_SERVER_URL, ACTUAL_PASSWORD, ACTUAL_SYNC_ID, optional ACTUAL_ENCRYPTION_PASSWORD, NODE_EXTRA_CA_CERTS) are appropriate for connecting to a self-hosted Actual Budget server, but they are sensitive (server password, sync id). The skill metadata did not declare any required env vars or a primary credential — a mismatch that could lead to accidental exposure of secrets if the platform provides environment access in ways the user doesn't expect.
Persistence & Privilege
The skill does not request persistent installation or elevated platform privileges (always:false). It is instruction-only and has no code files, so it will not by itself write binaries to the agent environment. The agent-autonomy defaults are unchanged; combine that with other concerns if the platform gives this skill runtime access to environment variables.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install actual-budget
  3. After installation, invoke the skill by name or use /actual-budget
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.2
Security: Removed NODE_TLS_REJECT_UNAUTHORIZED=0 recommendation. Added proper guidance for self-signed certificates using NODE_EXTRA_CA_CERTS instead.
v1.0.1
- Expanded documentation from CLI tool usage to **official Node.js API usage** - Updated environment variables and setup instructions for clarity and additional options. - Added code examples for all major financial operations (budget overview, account/transaction/category/payee management, rules, schedules, sync). - Introduced ActualQL query support with example queries and available operators. - Included advanced topics: handling transfers, split transactions, and bulk imports for new budgets. - Linked to full API and query language documentation for further reference. usi
v1.0.0
Initial release of actual-budget skill for managing personal finances. - Connects to self-hosted Actual Budget instances via CLI. - Supports importing/exporting transactions, auto-categorization, and bank statement parsing. - Allows customization through config.js for accounts, categories, and custom parsers. - Includes built-in support for multiple bank formats. - Provides safety confirmation for destructive actions like deleting all transactions.
Metadata
Slug actual-budget
Version 1.0.2
License
All-time Installs 12
Active Installs 11
Total Versions 3
Frequently Asked Questions

What is Actual Budget?

Query and manage personal finances via the official Actual Budget Node.js API. Use for budget queries, transaction imports/exports, account management, categorization, rules, schedules, and bank sync with self-hosted Actual Budget instances. It is an AI Agent Skill for Claude Code / OpenClaw, with 3822 downloads so far.

How do I install Actual Budget?

Run "/install actual-budget" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Actual Budget free?

Yes, Actual Budget is completely free (open-source). You can download, install and use it at no cost.

Which platforms does Actual Budget support?

Actual Budget is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Actual Budget?

It is built and maintained by ThisIsJeron (@thisisjeron); the current version is v1.0.2.

💬 Comments