Skip to content

Node.js Scripts

Write standalone Node.js scripts with bkper-js for complex logic, bulk data operations, scheduled jobs, and integrations that go beyond what the CLI alone can do.

For tasks that go beyond CLI piping — complex logic, external API integration, scheduled jobs — write a Node.js script with bkper-js.

Setup

Terminal window
# Create a script project
mkdir my-bkper-script && cd my-bkper-script
npm init -y
npm install bkper-js bkper

Authenticate once via the CLI:

Terminal window
bkper auth login

The pattern

Every script follows the same structure: authenticate, get a book, do work.

import { Bkper } from 'bkper-js';
import { getOAuthToken } from 'bkper';
Bkper.setConfig({
oauthTokenProvider: async () => getOAuthToken(),
});
const bkper = new Bkper();
const book = await bkper.getBook('your-book-id');
// Your logic here

Examples

Export monthly balances

import { Bkper } from 'bkper-js';
import { getOAuthToken } from 'bkper';
import { writeFileSync } from 'fs';
Bkper.setConfig({
oauthTokenProvider: async () => getOAuthToken(),
});
const bkper = new Bkper();
const book = await bkper.getBook('your-book-id');
const report = await book.getBalancesReport('after:2025-01-01 before:2025-12-31');
const rows = report.getBalancesContainers().map((c) => ({
account: c.getName(),
balance: c.getCumulativeBalance(),
}));
writeFileSync('balances.json', JSON.stringify(rows, null, 2));
console.log(`Exported ${rows.length} balances`);

Bulk-create accounts from a spreadsheet

import { Bkper, Account } from 'bkper-js';
import { getOAuthToken } from 'bkper';
import { readFileSync } from 'fs';
Bkper.setConfig({
oauthTokenProvider: async () => getOAuthToken(),
});
const bkper = new Bkper();
const book = await bkper.getBook('your-book-id');
// Read accounts from a JSON file
const data = JSON.parse(readFileSync('accounts.json', 'utf-8'));
const accounts = data.map((acc: any) =>
new Account(book).setName(acc.name).setType(acc.type).setGroups(acc.groups)
);
const created = await book.batchCreateAccounts(accounts);
console.log(`Created ${created.length} accounts`);

Query transactions and generate a report

import { Bkper } from 'bkper-js';
import { getOAuthToken } from 'bkper';
Bkper.setConfig({
oauthTokenProvider: async () => getOAuthToken(),
});
const bkper = new Bkper();
const book = await bkper.getBook('your-book-id');
const result = await book.listTransactions('account:Expenses after:2025-01-01');
let total = 0;
for (const tx of result.getItems()) {
total += tx.getAmount();
console.log(
`${tx.getDate()} | ${tx.getDescription()} | ${tx.getAmount()}`
);
}
console.log(`\nTotal: ${total}`);

Scheduled jobs

With cron

Terminal window
# Run daily at 8am
0 8 * * * cd /path/to/script && node export.mjs

With GitHub Actions

name: Daily Export
on:
schedule:
- cron: '0 8 * * *'
jobs:
export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: node export.mjs
env:
BKPER_TOKEN: ${{ secrets.BKPER_TOKEN }}

Error handling

Wrap API calls with proper error handling:

try {
const book = await bkper.getBook('your-book-id');
// ...
} catch (error) {
if (error.code === 404) {
console.error('Book not found');
} else if (error.code === 403) {
console.error('No access to this book');
} else {
console.error('API error:', error.message);
}
process.exit(1);
}

When to use scripts vs apps

ScenarioUse
One-off data migrationScript
Scheduled export/reportScript
Reacting to book events in real timePlatform app
Custom UI for usersPlatform app
Complex multi-step workflow with external APIsScript or app, depending on trigger

Next steps