A unified interface for Bkper. Use bkper in two complementary modes:
- Interactive mode — run
bkperwith no arguments to open the agent TUI - Command mode — run
bkper <command>for explicit CLI workflows, scripts, and automation
With one tool, you can build and deploy Bkper apps, and manage financial data -- books, accounts, transactions, and balances.
- Node.js >= 18
bun add -g bkpernpm i -g bkperpnpm add -g bkperyarn global add bkperbkper auth login# Interactive mode (agent TUI)
bkper# Command mode (explicit command)
bkper book listPick a book and create your first transaction:
bkper transaction create -b <bookId> --description "Office supplies 123.78"Run
bkper --helporbkper <command> --helpfor built-in documentation on any command.To build and deploy Bkper Apps, see App Management.
Use the access token for direct API calls from any tool:
# Print the current access token
TOKEN=$(bkper auth token)
# Use it with curl, httpie, or any HTTP client
curl -s -H "Authorization: Bearer $TOKEN" \
https://api.bkper.app/v5/books | jq '.items[].name'When you run bkper with no arguments in an interactive terminal, bkper starts the embedded agent TUI.
Bkper's agent mode is intentionally a thin wrapper around Pi:
- Pi provides the core agent runtime and TUI
- bkper adds Bkper-specific domain context and startup maintenance behavior
On each agent startup, bkper performs a background CLI auto-update check (same behavior as command mode).
Use Pi CLI features directly through bkper:
bkper agent -- <pi-args>Examples:
bkper agent -- -p "Summarize this repository"
bkper agent -- --model openai/gpt-4o -c
bkper agent -- install <pi-package-source>bkper agent keeps Bkper defaults (including Bkper system prompt) unless you explicitly pass --system-prompt.
For all available passthrough flags and commands, see the Pi CLI reference: https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent#cli-reference
Pi-specific extensions are loaded from Pi extension folders (for example .pi/extensions and ~/.pi/agent/extensions).
Interact with books, accounts, transactions, and balances.
All data commands that operate within a book use -b, --book <bookId> to specify the book context.
Create and manage financial books with locale-specific settings.
# List all books
bkper book list
# Get book details
bkper book get abc123
# Create a book with Brazilian settings
bkper book create --name "My Company" --fraction-digits 2 \
--date-pattern "dd/MM/yyyy" --decimal-separator COMMA \
--time-zone "America/Sao_Paulo"
# Create a book with custom properties
bkper book create --name "Project X" -p "code=PX001" -p "department=Engineering"
# Update a book
bkper book update abc123 --lock-date 2024-12-31Command reference
book list- List all books-q, --query <query>- Search query
book get <bookId>- Get a book's detailsbook create- Create a new book--name <name>- Book name (required)--fraction-digits <digits>- Number of decimal places (0-8)--date-pattern <pattern>- Date format pattern (dd/MM/yyyy,MM/dd/yyyy, oryyyy/MM/dd)--decimal-separator <separator>- Decimal separator (DOTorCOMMA)--time-zone <timezone>- IANA time zone (e.g.America/New_York,UTC)--period <period>- Period (MONTH,QUARTER, orYEAR)-p, --property <key=value>- Set a property (repeatable)
book update <bookId>- Update a book--name <name>- Book name--fraction-digits <digits>- Number of decimal places (0-8)--date-pattern <pattern>- Date format pattern (dd/MM/yyyy,MM/dd/yyyy, oryyyy/MM/dd)--decimal-separator <separator>- Decimal separator (DOTorCOMMA)--time-zone <timezone>- IANA time zone identifier (e.g.America/New_York,Europe/London,UTC)--lock-date <date>- Lock date in ISO format (yyyy-MM-dd, e.g.2024-01-31)--closing-date <date>- Closing date in ISO format (yyyy-MM-dd)--period <period>- Period (MONTH,QUARTER, orYEAR)-p, --property <key=value>- Set a property (repeatable, e.g.-p code=1010 -p branch=NYC; empty value deletes the property)
Manage your chart of accounts within a book.
# List all accounts
bkper account list -b abc123
# Get an account by name
bkper account get "Bank Account" -b abc123
# Create an asset account
bkper account create -b abc123 --name "Bank Account" --type ASSET --groups "Current Assets"
# Update an account
bkper account update "Bank Account" -b abc123 --type LIABILITY
# Archive an account
bkper account update "Old Account" -b abc123 --archived true
# Delete an account
bkper account delete "Old Account" -b abc123Command reference
account list -b <bookId>- List accounts in a bookaccount get <nameOrId> -b <bookId>- Get an accountaccount create -b <bookId>- Create a new account--name <name>- Account name (required)--type <type>- Account type (ASSET,LIABILITY,INCOMING,OUTGOING)--description <description>- Account description--groups <groups>- Comma-separated group names-p, --property <key=value>- Set a property (repeatable)
account update <nameOrId> -b <bookId>- Update an account--name <name>- Account name--type <type>- Account type (ASSET,LIABILITY,INCOMING,OUTGOING)--archived <true|false>- Archive status-p, --property <key=value>- Set a property (repeatable, merges with existing)
account delete <nameOrId> -b <bookId>- Delete an account
Organize accounts into hierarchical groups for structured reporting.
# List all groups (shows hierarchy)
bkper group list -b abc123
# Create a group
bkper group create -b abc123 --name "Current Assets"
# Create a child group
bkper group create -b abc123 --name "Cash" --parent "Current Assets"
# Update a group
bkper group update "Cash" -b abc123 --hidden true
# Delete a group
bkper group delete "Cash" -b abc123Command reference
group list -b <bookId>- List groups in a bookgroup get <nameOrId> -b <bookId>- Get a groupgroup create -b <bookId>- Create a new group--name <name>- Group name (required)--parent <parent>- Parent group name or ID--hidden- Hide the group-p, --property <key=value>- Set a property (repeatable)
group update <nameOrId> -b <bookId>- Update a group--name <name>- Group name--hidden <true|false>- Hide status-p, --property <key=value>- Set a property (repeatable, merges with existing)
group delete <nameOrId> -b <bookId>- Delete a group
Record, query, and manage financial transactions.
# Create a draft transaction
bkper transaction create -b abc123 --description "Office supplies"
# Create a complete transaction
bkper transaction create -b abc123 --date 2025-01-15 --amount 100.50 \
--from "Bank Account" --to "Office Supplies" --description "Printer paper"
# List transactions for a full year (on:YYYY)
bkper transaction list -b abc123 -q "on:2025"
# List transactions for a month (on:YYYY-MM)
bkper transaction list -b abc123 -q "on:2025-01"
# List with custom properties included
bkper transaction list -b abc123 -q "account:Sales" -p
# Update a transaction
bkper transaction update tx_456 -b abc123 --amount 120.00 --description "Printer paper (corrected)"
# Post a draft transaction
bkper transaction post tx_456 -b abc123
# Check (reconcile) a transaction
bkper transaction check tx_456 -b abc123
# Trash a transaction
bkper transaction trash tx_456 -b abc123
# Merge two duplicate transactions
bkper transaction merge tx_123 tx_456 -b abc123Command reference
transaction list -b <bookId> -q <query>- List transactions matching a query (auto-paginates through all results)-p, --properties- Include custom properties in the output
transaction create -b <bookId>- Create a transaction--date <date>- Transaction date--amount <amount>- Transaction amount--description <description>- Transaction description--from <from>- Credit account (source)--to <to>- Debit account (destination)--url <url>- URL (repeatable)--remote-id <remoteId>- Remote ID (repeatable)-p, --property <key=value>- Set a property (repeatable, empty value deletes)
transaction update [transactionId] -b <bookId>- Update a transaction (or batch update via stdin)--date <date>- Transaction date--amount <amount>- Transaction amount--description <description>- Transaction description--from <from>- Credit account (source)--to <to>- Debit account (destination)--url <url>- URL (repeatable, replaces all)--update-checked- Also update checked transactions-p, --property <key=value>- Set a property (repeatable, empty value deletes)
transaction post <id> -b <bookId>- Post a draft transactiontransaction check <id> -b <bookId>- Check a transactiontransaction trash <id> -b <bookId>- Trash a transactiontransaction merge <id1> <id2> -b <bookId>- Merge two transactions
Query account balances and group totals.
# List balances for a specific date (point-in-time)
bkper balance list -b abc123 -q "on:2025-12-31"
# Monthly balance evolution of one account during 2025
bkper balance list -b abc123 -q "account:'<accountName>' after:2025-01-01 before:2026-01-01 by:m" --expanded 2Command reference
balance list -b <bookId> -q <query>- List balances--expanded <level>- Expand groups to specified depth (0+)
Use the same query language across Bkper web app, CLI, and Google Sheets integrations.
on:supports different granularities:on:2025→ full yearon:2025-01→ full monthon:2025-01-31→ specific day
after:is inclusive andbefore:is exclusive.- Full year 2025:
after:2025-01-01 before:2026-01-01
- Full year 2025:
- For point-in-time statements (typically permanent accounts
ASSET/LIABILITY), preferon:orbefore:. - For activity statements over a period (typically non-permanent accounts
INCOMING/OUTGOING), preferafter:+before:. - For statement-level analysis, prefer filtering by the report root group. Root names vary by book.
# Balance Sheet snapshot (point-in-time)
bkper balance list -b abc123 -q "group:'<balanceSheetRootGroup>' before:2026-01-01"
# P&L activity over 2025
bkper balance list -b abc123 -q "group:'<profitAndLossRootGroup>' after:2025-01-01 before:2026-01-01"Organize books into collections.
# Create a collection
bkper collection create --name "My Collection"
# Add books to a collection
bkper collection add-book col_789 -b abc123 -b def456
# List all collections
bkper collection list
# Remove a book from a collection
bkper collection remove-book col_789 -b abc123
# Delete a collection
bkper collection delete col_789Command reference
collection list- List all collectionscollection get <collectionId>- Get a collectioncollection create- Create a new collection--name <name>- Collection name (required)
collection update <collectionId>- Update a collection--name <name>- Collection name
collection delete <collectionId>- Delete a collectioncollection add-book <collectionId>- Add books to a collection-b, --book <bookId>- Book ID (repeatable)
collection remove-book <collectionId>- Remove books from a collection-b, --book <bookId>- Book ID (repeatable)
All commands support three output formats via the --format global flag:
| Format | Flag | Best for |
|---|---|---|
| Table | --format table (default) |
Human reading in the terminal |
| JSON | --format json |
Programmatic access, single-item detail |
| CSV | --format csv |
LLM consumption, spreadsheets, list reports |
# Table output (default)
bkper account list -b abc123
# JSON output
bkper account list -b abc123 --format json
# CSV output -- raw data, no truncation, RFC 4180
bkper account list -b abc123 --format csvCSV output details:
- RFC 4180 compliant -- proper quoting, CRLF line endings, no truncation
- All metadata included -- IDs, properties, hidden properties, URLs, and timestamps are enabled
- Raw values -- dates stay in ISO format, numbers are unformatted (no locale formatting)
- Single-item commands (e.g.
account get,transaction create) fall back to JSON since CSV adds no value for non-tabular data
LLM-first output guidance (important):
When command output will be loaded into an LLM context (chat, prompt, memory, or agent reasoning), prefer:
--format csvfor list commands (balance list,transaction list,account list, etc.).--format jsonfor single-item commands (get,create,update) and CLI-to-CLI pipelines.
CSV is significantly more token-efficient than JSON for tabular data, and for wide balance outputs it can reduce token usage by up to 95%.
Quick rule:
- LLM consumption of lists/reports → CSV
- Programmatic processing / pipelines → JSON
- Human terminal reading → Table
Write commands (account create, group create, transaction create) accept JSON data piped via stdin for batch operations. The transaction update command also accepts stdin for batch updates. The input format follows the Bkper API Types exactly -- a single JSON object or an array of objects.
# Create transactions
echo '[{
"date": "2025-01-15",
"amount": "100.50",
"creditAccount": {"name": "Bank Account"},
"debitAccount": {"name": "Office Supplies"},
"description": "Printer paper",
"properties": {"invoice": "INV-001"}
}]' | bkper transaction create -b abc123
# Create accounts
echo '[{"name":"Cash","type":"ASSET"},{"name":"Revenue","type":"INCOMING"}]' | \
bkper account create -b abc123
# Create groups
echo '[{"name":"Fixed Costs","hidden":true}]' | \
bkper group create -b abc123
# Pipe from a script
python export_bank.py | bkper transaction create -b abc123The input follows the exact bkper.Transaction, bkper.Account, or bkper.Group type from the Bkper API Types. Custom properties go inside the properties object.
The --property CLI flag can override or delete properties from the stdin payload:
echo '[{"name":"Cash","type":"ASSET"}]' | \
bkper account create -b abc123 -p "region=LATAM"Batch output: results are output as a flat JSON array, matching the same format as list commands:
bkper account create -b abc123 < accounts.json
# Output: [{"id":"acc-abc","name":"Cash",...}, {"id":"acc-def","name":"Revenue",...}]Piping between commands:
All JSON output is designed to be piped directly as stdin to other commands. The output of any list or batch create command can feed directly into a create or update command:
# Copy all accounts from one book to another
bkper account list -b $BOOK_A --format json | bkper account create -b $BOOK_B
# Copy all groups from one book to another
bkper group list -b $BOOK_A --format json | bkper group create -b $BOOK_B
# Copy transactions matching a query
bkper transaction list -b $BOOK_A -q "after:2025-01-01" --format json | \
bkper transaction create -b $BOOK_B
# Clone a full chart of accounts: groups, then accounts, then transactions
bkper group list -b $SOURCE --format json | bkper group create -b $DEST
bkper account list -b $SOURCE --format json | bkper account create -b $DEST
bkper transaction list -b $SOURCE -q "after:2025-01-01" --format json | \
bkper transaction create -b $DEST
# Batch update: list transactions, modify, and pipe back to update
bkper transaction list -b $BOOK -q "after:2025-01-01" --format json | \
jq '[.[] | .description = "Updated: " + .description]' | \
bkper transaction update -b $BOOK
# Batch update: add a property to all matching transactions
bkper transaction list -b $BOOK -q "account:Expenses" --format json | \
bkper transaction update -b $BOOK -p "reviewed=true"
# Batch update checked transactions
bkper transaction list -b $BOOK -q "is:checked after:2025-01-01" --format json | \
bkper transaction update -b $BOOK --update-checked -p "migrated=true"Writable fields reference
Only the fields below are meaningful when creating or updating resources via stdin. For batch updates, items must include an id field. Other read-only fields (createdAt, updatedAt, etc.) are ignored.
Transaction (bkper.Transaction)
| Field | Type | Notes |
|---|---|---|
id |
string |
Required for batch updates, ignored on create |
date |
string |
ISO format yyyy-MM-dd |
amount |
string |
Decimal format ####.## (string, not number) |
creditAccount |
{"name":"..."} or {"id":"..."} |
Reference to an existing account |
debitAccount |
{"name":"..."} or {"id":"..."} |
Reference to an existing account |
description |
string |
Free-text description |
urls |
string[] |
Attached URLs (e.g. receipts) |
remoteIds |
string[] |
External IDs to prevent duplicates |
properties |
{"key": "value", ...} |
Custom key/value properties |
Account (bkper.Account)
| Field | Type | Notes |
|---|---|---|
name |
string |
Account name (required) |
type |
string |
ASSET, LIABILITY, INCOMING, or OUTGOING |
credit |
boolean |
Credit nature (true) or debit (false) |
archived |
boolean |
Archive the account on creation |
permanent |
boolean |
Permanent accounts (e.g. bank accounts, customers) |
groups |
[{"name":"..."}, ...] |
Groups to assign by name or id |
properties |
{"key": "value", ...} |
Custom key/value properties |
Group (bkper.Group)
| Field | Type | Notes |
|---|---|---|
name |
string |
Group name (required) |
hidden |
boolean |
Hide from transactions main menu |
parent |
{"name":"..."} or {"id":"..."} |
Parent group for nesting |
properties |
{"key": "value", ...} |
Custom key/value properties |
Build, deploy, and manage Bkper apps.
# Scaffold a new app from the template
bkper app init my-app
# Start the worker runtime (Miniflare + tunnel + file watching)
# In your project, use "npm run dev" to run both Vite and workers concurrently
bkper app dev
# Build worker bundles (web server + events handler)
# In your project, use "npm run build" to build both client (Vite) and workers
bkper app build
# Sync configuration and deploy to production
bkper app sync && bkper app deploy
# Deploy to development environment
bkper app deploy --preview
# Deploy only the events handler
bkper app deploy --events
# Check deployment status
bkper app statusNote:
bkper app devruns the worker runtime only — Miniflare, file watching, and the Cloudflare tunnel. The Vite client dev server is configured in the project'svite.config.tsand run separately. The project template composes both vianpm run devusingconcurrently.
# Install an app on a book
bkper app install my-app -b abc123
# Uninstall an app from a book
bkper app uninstall my-app -b abc123# Store a secret (prompts for value)
bkper app secrets put API_KEY
# List all secrets
bkper app secrets list
# Delete a secret
bkper app secrets delete API_KEYApps are configured via a bkper.yaml file in the project root. See the complete bkper.yaml reference below.
bkper.yaml reference
# =============================================================================
# bkper.yaml Reference
# =============================================================================
# This file documents all available configuration options for Bkper Apps.
# Copy the fields you need to your app's bkper.yaml file.
#
# For a minimal working template, see:
# https://github.com/bkper/bkper-app-template
# =============================================================================
# -----------------------------------------------------------------------------
# APP IDENTITY
# -----------------------------------------------------------------------------
# The app id is permanent and cannot be changed after creation.
# Use lowercase letters, numbers, and hyphens only.
id: my-app
# Display name shown in the Bkper UI
name: My App
# Brief description of what the app does
description: A Bkper app that does something useful
# -----------------------------------------------------------------------------
# BRANDING
# -----------------------------------------------------------------------------
# App logo for light mode (SVG recommended, PNG/JPG supported)
logoUrl: https://example.com/logo.svg
# App logo for dark mode (required for proper theming)
logoUrlDark: https://example.com/logo-dark.svg
# App website or documentation URL
website: https://example.com
# -----------------------------------------------------------------------------
# OWNERSHIP
# -----------------------------------------------------------------------------
# Developer/company name
ownerName: Your Name
# Owner's logo/avatar URL
ownerLogoUrl: https://example.com/owner-logo.png
# Owner's website
ownerWebsite: https://yoursite.com
# Source code repository URL
repoUrl: https://github.com/you/my-app
# Whether the repository is private
repoPrivate: true
# Mark as deprecated (hides from app listings, existing installs continue working)
deprecated: false
# -----------------------------------------------------------------------------
# ACCESS CONTROL
# -----------------------------------------------------------------------------
# Who can update the app configuration and deploy new versions.
# Comma-separated list of Bkper usernames (not emails).
# Supports domain wildcards for registered custom domains: *@yourdomain.com
developers: victor, aldo, *@bkper.com
# Who can install and use the app.
# Same format as developers. Leave empty for public apps.
users: maria, *@acme.com
# -----------------------------------------------------------------------------
# MENU INTEGRATION (optional)
# -----------------------------------------------------------------------------
# When configured, adds a menu item to Bkper's "More" menu.
# Clicking opens a popup with the specified URL.
# Production menu URL (supports variable substitution)
menuUrl: https://${id}.bkper.app?bookId=${book.id}
# Development menu URL (used when developer runs the app)
menuUrlDev: http://localhost:8787?bookId=${book.id}
# Custom menu text (defaults to app name if not specified)
menuText: Open My App
# Popup dimensions in pixels
menuPopupWidth: 500
menuPopupHeight: 300
# -----------------------------------------------------------------------------
# Menu URL Variables
# -----------------------------------------------------------------------------
# The following variables can be used in menuUrl and menuUrlDev:
#
# ${book.id} - Current book ID
# ${book.properties.xxx} - Book property value (replace xxx with property key)
# ${account.id} - Selected account ID (in account context)
# ${account.properties.xxx} - Account property value
# ${group.id} - Selected group ID (in group context)
# ${group.properties.xxx} - Group property value
# ${transactions.ids} - Comma-separated selected transaction IDs
# ${transactions.query} - Current search query
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# EVENT HANDLING (optional)
# -----------------------------------------------------------------------------
# When configured, Bkper calls your webhook URL when subscribed events occur.
# Production webhook URL
webhookUrl: https://${id}.bkper.app/events
# Development webhook URL (auto-updated by bkper app dev)
webhookUrlDev: https://<random>.trycloudflare.com/events
# API version for event payloads
apiVersion: v5
# Events to subscribe to (remove events you don't need)
events:
# Transaction
- TRANSACTION_CREATED
- TRANSACTION_POSTED
- TRANSACTION_CHECKED
- TRANSACTION_UNCHECKED
- TRANSACTION_UPDATED
- TRANSACTION_DELETED
- TRANSACTION_RESTORED
# Account
- ACCOUNT_CREATED
- ACCOUNT_UPDATED
- ACCOUNT_DELETED
# Group
- GROUP_CREATED
- GROUP_UPDATED
- GROUP_DELETED
# File
- FILE_CREATED
- FILE_UPDATED
# Query
- QUERY_CREATED
- QUERY_UPDATED
- QUERY_DELETED
# Comment
- COMMENT_CREATED
- COMMENT_DELETED
# Collaborator
- COLLABORATOR_ADDED
- COLLABORATOR_UPDATED
- COLLABORATOR_REMOVED
# Integration
- INTEGRATION_CREATED
- INTEGRATION_UPDATED
- INTEGRATION_DELETED
# Book
- BOOK_CREATED
- BOOK_UPDATED
- BOOK_DELETED
- BOOK_AUDITED
# -----------------------------------------------------------------------------
# FILE PATTERNS (optional)
# -----------------------------------------------------------------------------
# For file processing apps. When a file matching these patterns is uploaded,
# a FILE_CREATED event is triggered with the file content.
filePatterns:
- '*.ofx'
- '*.csv'
# -----------------------------------------------------------------------------
# PROPERTIES SCHEMA (optional)
# -----------------------------------------------------------------------------
# Defines autocomplete suggestions for custom properties in the Bkper UI.
# Helps users discover and use the correct property keys/values for your app.
propertiesSchema:
book:
keys:
- my_app_enabled
- my_app_config
values:
- 'true'
- 'false'
group:
keys:
- my_app_category
values:
- category_a
- category_b
account:
keys:
- my_app_sync_id
transaction:
keys:
- my_app_reference
# -----------------------------------------------------------------------------
# DEPLOYMENT CONFIGURATION (optional)
# -----------------------------------------------------------------------------
# For apps deployed to Bkper's Workers for Platforms infrastructure.
deployment:
# Web handler (serves UI and API)
web:
bundle: packages/web/server/dist
# assets: packages/web/client/dist # Static assets (when supported)
# Events handler (processes webhooks)
events:
bundle: packages/events/dist
# Platform services available to your app (one per type, auto-provisioned)
# See: https://developers.cloudflare.com/kv/
services:
- KV # Key-value storageEnvironment variables:
BKPER_API_KEY-- Optional. If not set, uses the Bkper API proxy with a managed API key. Set it for direct API access with your own quotas. Follow these steps to enable.
Command reference
auth login- Authenticate with Bkper, storing credentials locallyauth logout- Remove stored credentialsauth token- Print the current OAuth access token to stdout
agent -- <pi-args...>- Run Pi CLI with Bkper defaults (system prompt/resources)
app init <name>- Scaffold a new app from the templateapp list- List all apps you have access toapp sync- Sync bkper.yaml configuration (URLs, description) to Bkper APIapp build- Build worker bundles for deploymentapp deploy- Deploy built artifacts to Cloudflare Workers for Platforms-p, --preview- Deploy to preview environment--events- Deploy events handler instead of web handler
app status- Show deployment statusapp undeploy- Remove app from platform-p, --preview- Remove from preview environment--events- Remove events handler instead of web handler--delete-data- Permanently delete all associated data (requires confirmation)--force- Skip confirmation prompts (use with--delete-datafor automation)
app dev- Start the worker runtime for local development--sp, --server-port <port>- Server simulation port (default:8787)--ep, --events-port <port>- Events handler port (default:8791)-w, --web- Run only the web handler-e, --events- Run only the events handler
Note:
syncanddeployare independent operations. Usesyncto update your app's URLs in Bkper (required for webhooks and menu integration). Usedeployto push code to Cloudflare. For a typical deployment workflow, run both:bkper app sync && bkper app deploy
app install <appId> -b <bookId>- Install an app on a bookapp uninstall <appId> -b <bookId>- Uninstall an app from a book
app secrets put <name>- Store a secret-p, --preview- Set in preview environment
app secrets list- List all secrets-p, --preview- List from preview environment
app secrets delete <name>- Delete a secret-p, --preview- Delete from preview environment
The getOAuthToken function returns a Promise that resolves to a valid OAuth token, for use with the bkper-js library:
import { Bkper } from 'bkper-js';
import { getOAuthToken } from 'bkper';
Bkper.setConfig({
oauthTokenProvider: async () => getOAuthToken(),
});