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
# Create a script projectmkdir my-bkper-script && cd my-bkper-scriptnpm init -ynpm install bkper-js bkperAuthenticate once via the CLI:
bkper auth loginThe 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 hereExamples
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 fileconst 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
# Run daily at 8am0 8 * * * cd /path/to/script && node export.mjsWith GitHub Actions
name: Daily Exporton: 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
| Scenario | Use |
|---|---|
| One-off data migration | Script |
| Scheduled export/report | Script |
| Reacting to book events in real time | Platform app |
| Custom UI for users | Platform app |
| Complex multi-step workflow with external APIs | Script or app, depending on trigger |
Next steps
- bkper-js API Reference — Full SDK documentation
- CLI Scripting & Piping — For simpler tasks, the CLI may be enough
- Direct API Usage — Use the REST API from any language