Developers
API reference

Accounts

get/v1/accounts

List accounts

accounts.listread tokenidempotent

Every account in the ledger's chart of accounts, including the categories transactions are filed under, with its current balance.

Parameters

limit
integer · query
Page size, 1–200.
cursor
string | null · query
The next_cursor of the previous page.
include_inactive
boolean · query
Also return closed accounts.
type
string | null · query
Only accounts of this type. expense and income are the categories transactions are filed under.
institution_id
integer | null · query
Only accounts held at this bank (see institutions.list).
X-Organization-Id
string | null · header

Returns 200 · AccountList

data
array of Account · required
has_more
boolean · required
next_cursor
string | null · required
Example
curl -X GET "https://api.lumaledger.app/v1/accounts" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/accounts

Create an account

accounts.createwrite tokenidempotent

Add an account to the chart of accounts: a bank account, a card, a loan, an equity account, or a category. It starts at a zero balance. Send an Idempotency-Key so a retry cannot create it twice.

Parameters

Idempotency-Key
string | null · header
Any unique string (a UUID is ideal). A retry with the same key returns the first attempt's response instead of doing the work twice. Keys are kept for 24 hours.
X-Organization-Id
string | null · header

Body · AccountCreate

code
string · required
Chart-of-accounts code, unique in the ledger. Must start with the type's prefix (see account_types.list): 1 asset, 2 liability, 3 equity, 4 income, 5 or 6 expense.
institution_id
integer | null
File it at this bank (see institutions.list).
is_placeholder
boolean
A grouping account that holds no postings of its own. Default: false.
name
string · required
parent_id
integer | null
Nest it under this account: a group (is_placeholder) of the same type, or, for an income or expense category, a top-level category of its type.
type
string · required
asset, liability, equity, income or expense. Pattern: ^(asset|liability|equity|income|expense)$.

Returns 201 · Account

balance
Money · required
The account's balance, positive on its normal side: what an asset holds, what a liability owes, what an expense category has spent in total.
code
string · required
Chart-of-accounts code, unique in the ledger (1010, 5190).
created_at
datetime · required
excluded_from_totals
boolean · required
Left out of net worth and other totals.
hidden
boolean · required
Hidden from lists in the app.
id
integer · required
The account id. Transactions and journal lines name it as account_id.
institution_id
integer | null · required
The bank or provider the account belongs to.
is_active
boolean · required
False once the account is closed. Its history stays in the ledger.
is_placeholder
boolean · required
A grouping account that holds no postings of its own.
low_balance_alert
LowBalanceAlert | null · required
The member is told when this account's balance drops below a threshold, and has a to-do until it is back above; null when nobody set one. Only an open asset account can carry one. Set it with accounts.update.
mask
string | null · required
The last digits of the account number, as the bank shows them.
name
string · required
normal_balance
string · required
debit or credit: the side that increases the account.
overdraft_ahead
LowBalanceShortfall | null · required
With no low_balance_alert set: the recurring bills and paychecks expected on this open asset account over the next month, and the payments of the credit cards it pays, take its balance below zero; needed is what to move in to stay at or above zero. The member sees it on their to-do list and the account's page but is never notified of it unasked: setting a low_balance_alert is how they ask. Null when the bills ahead do not, when the balance is already below zero, and whenever an alert is set (its shortfall says it then).
parent_id
integer | null · required
The parent account, for sub-accounts and subcategories.
purpose
string | null · required
business if its transactions count as business by default; null for personal.
role
string | null · required
What the account is for, when known (checking, credit_card, mortgage, …).
type
string · required
asset, liability, equity, income or expense.
unshared_at
datetime | null · required
When the bank stopped sharing this account on its connection (deselected, closed or revoked at the bank) while the connection itself keeps syncing, or null while it is shared. Its balance is frozen at the last number the bank sent. A person fixes it in the app by sharing the account again, or closes it with accounts.close.
Example
curl -X POST "https://api.lumaledger.app/v1/accounts" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "1090",
    "name": "…",
    "type": "…"
  }'
delete/v1/accounts/{account_id}

Delete an account

accounts.deletewrite tokendestructiveidempotent

Delete an account that was never used: no journal lines and no sub-accounts. An account with history cannot be deleted without unbalancing the books; close it instead (accounts.close).

Parameters

account_id
integer · path · required
X-Organization-Id
string | null · header

Returns 204 with no body.

Example
curl -X DELETE "https://api.lumaledger.app/v1/accounts/{account_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/accounts/{account_id}

Get an account

accounts.getread tokenidempotent

One account by id, closed or not.

Parameters

account_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · Account

balance
Money · required
The account's balance, positive on its normal side: what an asset holds, what a liability owes, what an expense category has spent in total.
code
string · required
Chart-of-accounts code, unique in the ledger (1010, 5190).
created_at
datetime · required
excluded_from_totals
boolean · required
Left out of net worth and other totals.
hidden
boolean · required
Hidden from lists in the app.
id
integer · required
The account id. Transactions and journal lines name it as account_id.
institution_id
integer | null · required
The bank or provider the account belongs to.
is_active
boolean · required
False once the account is closed. Its history stays in the ledger.
is_placeholder
boolean · required
A grouping account that holds no postings of its own.
low_balance_alert
LowBalanceAlert | null · required
The member is told when this account's balance drops below a threshold, and has a to-do until it is back above; null when nobody set one. Only an open asset account can carry one. Set it with accounts.update.
mask
string | null · required
The last digits of the account number, as the bank shows them.
name
string · required
normal_balance
string · required
debit or credit: the side that increases the account.
overdraft_ahead
LowBalanceShortfall | null · required
With no low_balance_alert set: the recurring bills and paychecks expected on this open asset account over the next month, and the payments of the credit cards it pays, take its balance below zero; needed is what to move in to stay at or above zero. The member sees it on their to-do list and the account's page but is never notified of it unasked: setting a low_balance_alert is how they ask. Null when the bills ahead do not, when the balance is already below zero, and whenever an alert is set (its shortfall says it then).
parent_id
integer | null · required
The parent account, for sub-accounts and subcategories.
purpose
string | null · required
business if its transactions count as business by default; null for personal.
role
string | null · required
What the account is for, when known (checking, credit_card, mortgage, …).
type
string · required
asset, liability, equity, income or expense.
unshared_at
datetime | null · required
When the bank stopped sharing this account on its connection (deselected, closed or revoked at the bank) while the connection itself keeps syncing, or null while it is shared. Its balance is frozen at the last number the bank sent. A person fixes it in the app by sharing the account again, or closes it with accounts.close.
Example
curl -X GET "https://api.lumaledger.app/v1/accounts/{account_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
patch/v1/accounts/{account_id}

Update an account

accounts.updatewrite tokenidempotent

Rename or renumber an account, move it in the tree, file it at a bank, hide it, leave it out of totals, mark it business, or set its low-balance alert. Only the fields sent change; the account is re-validated as a whole, as when it was created.

Parameters

account_id
integer · path · required
X-Organization-Id
string | null · header

Body · AccountUpdate

code
string | null
excluded_from_totals
boolean | null
Leave its balance out of net worth and other totals.
hidden
boolean | null
Hide it from lists in the app.
institution_id
integer | null
File it at this bank; null takes it out of its bank. Refused for an account a bank connection feeds, whose bank comes from the connection.
is_placeholder
boolean | null
low_balance_alert
string | null
Tell the member when the balance drops below this amount, in the account's currency ("200.00"); null stops it. Only an open asset account (a checking or savings account, a wallet) can carry one. Pattern: ^\d{1,12}(\.\d{1,2})?$.
name
string | null
parent_id
integer | null
Null takes it out of its parent.
purpose
string | null
business files its transactions as business by default; personal or null returns it to the default. Pattern: ^(personal|business)$.
type
string | null
Pattern: ^(asset|liability|equity|income|expense)$.

Returns 200 · Account

balance
Money · required
The account's balance, positive on its normal side: what an asset holds, what a liability owes, what an expense category has spent in total.
code
string · required
Chart-of-accounts code, unique in the ledger (1010, 5190).
created_at
datetime · required
excluded_from_totals
boolean · required
Left out of net worth and other totals.
hidden
boolean · required
Hidden from lists in the app.
id
integer · required
The account id. Transactions and journal lines name it as account_id.
institution_id
integer | null · required
The bank or provider the account belongs to.
is_active
boolean · required
False once the account is closed. Its history stays in the ledger.
is_placeholder
boolean · required
A grouping account that holds no postings of its own.
low_balance_alert
LowBalanceAlert | null · required
The member is told when this account's balance drops below a threshold, and has a to-do until it is back above; null when nobody set one. Only an open asset account can carry one. Set it with accounts.update.
mask
string | null · required
The last digits of the account number, as the bank shows them.
name
string · required
normal_balance
string · required
debit or credit: the side that increases the account.
overdraft_ahead
LowBalanceShortfall | null · required
With no low_balance_alert set: the recurring bills and paychecks expected on this open asset account over the next month, and the payments of the credit cards it pays, take its balance below zero; needed is what to move in to stay at or above zero. The member sees it on their to-do list and the account's page but is never notified of it unasked: setting a low_balance_alert is how they ask. Null when the bills ahead do not, when the balance is already below zero, and whenever an alert is set (its shortfall says it then).
parent_id
integer | null · required
The parent account, for sub-accounts and subcategories.
purpose
string | null · required
business if its transactions count as business by default; null for personal.
role
string | null · required
What the account is for, when known (checking, credit_card, mortgage, …).
type
string · required
asset, liability, equity, income or expense.
unshared_at
datetime | null · required
When the bank stopped sharing this account on its connection (deselected, closed or revoked at the bank) while the connection itself keeps syncing, or null while it is shared. Its balance is frozen at the last number the bank sent. A person fixes it in the app by sharing the account again, or closes it with accounts.close.
Example
curl -X PATCH "https://api.lumaledger.app/v1/accounts/{account_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
put/v1/accounts/{account_id}/balance

Set a manual account's balance

accounts.set_balancewrite tokenidempotent

Say what an account nothing syncs holds today, so the ledger catches up with the charges it cannot see. The account's opening entry is re-derived so its balance reads exactly this from today, with every posting it already has taken into account. For real asset and liability accounts only, and refused for one a bank connection feeds (its bank reports the balance).

Parameters

account_id
integer · path · required
X-Organization-Id
string | null · header

Body · BalanceSet

balance
string · required
What the account holds (asset) or owes (liability) today, in its own terms: a card with $300 on it is "300.00". Pattern: ^-?\d{1,12}(\.\d{1,2})?$.

Returns 200 · Account

balance
Money · required
The account's balance, positive on its normal side: what an asset holds, what a liability owes, what an expense category has spent in total.
code
string · required
Chart-of-accounts code, unique in the ledger (1010, 5190).
created_at
datetime · required
excluded_from_totals
boolean · required
Left out of net worth and other totals.
hidden
boolean · required
Hidden from lists in the app.
id
integer · required
The account id. Transactions and journal lines name it as account_id.
institution_id
integer | null · required
The bank or provider the account belongs to.
is_active
boolean · required
False once the account is closed. Its history stays in the ledger.
is_placeholder
boolean · required
A grouping account that holds no postings of its own.
low_balance_alert
LowBalanceAlert | null · required
The member is told when this account's balance drops below a threshold, and has a to-do until it is back above; null when nobody set one. Only an open asset account can carry one. Set it with accounts.update.
mask
string | null · required
The last digits of the account number, as the bank shows them.
name
string · required
normal_balance
string · required
debit or credit: the side that increases the account.
overdraft_ahead
LowBalanceShortfall | null · required
With no low_balance_alert set: the recurring bills and paychecks expected on this open asset account over the next month, and the payments of the credit cards it pays, take its balance below zero; needed is what to move in to stay at or above zero. The member sees it on their to-do list and the account's page but is never notified of it unasked: setting a low_balance_alert is how they ask. Null when the bills ahead do not, when the balance is already below zero, and whenever an alert is set (its shortfall says it then).
parent_id
integer | null · required
The parent account, for sub-accounts and subcategories.
purpose
string | null · required
business if its transactions count as business by default; null for personal.
role
string | null · required
What the account is for, when known (checking, credit_card, mortgage, …).
type
string · required
asset, liability, equity, income or expense.
unshared_at
datetime | null · required
When the bank stopped sharing this account on its connection (deselected, closed or revoked at the bank) while the connection itself keeps syncing, or null while it is shared. Its balance is frozen at the last number the bank sent. A person fixes it in the app by sharing the account again, or closes it with accounts.close.
Example
curl -X PUT "https://api.lumaledger.app/v1/accounts/{account_id}/balance" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "balance": "1250.00"
  }'
post/v1/accounts/{account_id}/close

Close an account

accounts.closewrite tokendestructiveidempotent

Retire an account the way the app's "Remove account" does: a closing entry dated today brings its balance to zero, it is deactivated (history before today stays), and if a bank connection feeds it, the connection stops syncing it; when it was the connection's last account, the connection itself is removed at the bank. Closing a closed account does nothing. Needs an admin, because it stops data collection for everyone in the ledger. Only an asset or liability account can be closed: a category or an equity account is refused with a 422.

Parameters

account_id
integer · path · required
X-Organization-Id
string | null · header

Returns 200 · ClosedAccount

account
Account · required
connection_removed
boolean · required
It was the last account behind a bank connection, so the connection was removed too.
Example
curl -X POST "https://api.lumaledger.app/v1/accounts/{account_id}/close" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/accounts/{account_id}/ledger

List an account's journal lines

accounts.ledgerread tokenidempotent

The account's register: every journal line posted to it, oldest first (by date, then entry, then line), each with the running balance after it. The last line's running balance is the account's balance.

Parameters

account_id
integer · path · required
limit
integer · query
Page size, 1–200.
cursor
string | null · query
The next_cursor of the previous page.
X-Organization-Id
string | null · header

Returns 200 · LedgerLineList

data
array of LedgerLine · required
has_more
boolean · required
next_cursor
string | null · required
Example
curl -X GET "https://api.lumaledger.app/v1/accounts/{account_id}/ledger" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
post/v1/accounts/{account_id}/purge

Erase an account and its history

accounts.purgewrite tokendestructive

Erase an account and everything it brought in, as if it had never been linked: its transactions, every journal entry on it (openings, closings, valuations included), balances, holdings, its connection when nothing else hangs off it, and rules that name it. Unlike accounts.close, no history is kept. The other side of a transfer into it is kept and categorized again, so the accounts that stay do not move; an entry that would move one of them is a 409 naming it (see blockers, or call with dry_run=true first). Needs an admin.

Parameters

account_id
integer · path · required
dry_run
boolean · query
Report what would go, change nothing.
X-Organization-Id
string | null · header

Returns 200 · Purge

account_ids
array of integer · required
blocker_count
integer · required
blockers
array of PurgeBlocker · required
entries
integer · required
Journal entries deleted outright.
erased
boolean · required
False on a dry run, or when blockers refused it.
released
integer · required
Transactions on accounts that stay, unpaired from a transfer into an erased account and categorized again. Their balances do not move.
transactions
integer · required
Transactions of the erased accounts.
Example
curl -X POST "https://api.lumaledger.app/v1/accounts/{account_id}/purge" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"

Objects

Account

One account in the ledger's chart of accounts: a bank account, a card, a loan, or a category such as Groceries (an expense account).

Fields

balance
Money · required
The account's balance, positive on its normal side: what an asset holds, what a liability owes, what an expense category has spent in total.
code
string · required
Chart-of-accounts code, unique in the ledger (1010, 5190).
created_at
datetime · required
excluded_from_totals
boolean · required
Left out of net worth and other totals.
hidden
boolean · required
Hidden from lists in the app.
id
integer · required
The account id. Transactions and journal lines name it as account_id.
institution_id
integer | null · required
The bank or provider the account belongs to.
is_active
boolean · required
False once the account is closed. Its history stays in the ledger.
is_placeholder
boolean · required
A grouping account that holds no postings of its own.
low_balance_alert
LowBalanceAlert | null · required
The member is told when this account's balance drops below a threshold, and has a to-do until it is back above; null when nobody set one. Only an open asset account can carry one. Set it with accounts.update.
mask
string | null · required
The last digits of the account number, as the bank shows them.
name
string · required
normal_balance
string · required
debit or credit: the side that increases the account.
overdraft_ahead
LowBalanceShortfall | null · required
With no low_balance_alert set: the recurring bills and paychecks expected on this open asset account over the next month, and the payments of the credit cards it pays, take its balance below zero; needed is what to move in to stay at or above zero. The member sees it on their to-do list and the account's page but is never notified of it unasked: setting a low_balance_alert is how they ask. Null when the bills ahead do not, when the balance is already below zero, and whenever an alert is set (its shortfall says it then).
parent_id
integer | null · required
The parent account, for sub-accounts and subcategories.
purpose
string | null · required
business if its transactions count as business by default; null for personal.
role
string | null · required
What the account is for, when known (checking, credit_card, mortgage, …).
type
string · required
asset, liability, equity, income or expense.
unshared_at
datetime | null · required
When the bank stopped sharing this account on its connection (deselected, closed or revoked at the bank) while the connection itself keeps syncing, or null while it is shared. Its balance is frozen at the last number the bank sent. A person fixes it in the app by sharing the account again, or closes it with accounts.close.

AccountCreate

An account in the chart of accounts, numbered by you. For a bank account or card typed in by hand, institutions.create_account picks the code and the kind for you; for a category, categories.create.

Fields

code
string · required
Chart-of-accounts code, unique in the ledger. Must start with the type's prefix (see account_types.list): 1 asset, 2 liability, 3 equity, 4 income, 5 or 6 expense.
institution_id
integer | null
File it at this bank (see institutions.list).
is_placeholder
boolean
A grouping account that holds no postings of its own. Default: false.
name
string · required
parent_id
integer | null
Nest it under this account: a group (is_placeholder) of the same type, or, for an income or expense category, a top-level category of its type.
type
string · required
asset, liability, equity, income or expense. Pattern: ^(asset|liability|equity|income|expense)$.

AccountList

A page of accounts, in id order.

Fields

data
array of Account · required
has_more
boolean · required
next_cursor
string | null · required

AccountUpdate

Only the fields sent are changed.

Fields

code
string | null
excluded_from_totals
boolean | null
Leave its balance out of net worth and other totals.
hidden
boolean | null
Hide it from lists in the app.
institution_id
integer | null
File it at this bank; null takes it out of its bank. Refused for an account a bank connection feeds, whose bank comes from the connection.
is_placeholder
boolean | null
low_balance_alert
string | null
Tell the member when the balance drops below this amount, in the account's currency ("200.00"); null stops it. Only an open asset account (a checking or savings account, a wallet) can carry one. Pattern: ^\d{1,12}(\.\d{1,2})?$.
name
string | null
parent_id
integer | null
Null takes it out of its parent.
purpose
string | null
business files its transactions as business by default; personal or null returns it to the default. Pattern: ^(personal|business)$.
type
string | null
Pattern: ^(asset|liability|equity|income|expense)$.

BalanceSet

Fields

balance
string · required
What the account holds (asset) or owes (liability) today, in its own terms: a card with $300 on it is "300.00". Pattern: ^-?\d{1,12}(\.\d{1,2})?$.

ClosedAccount

Fields

account
Account · required
connection_removed
boolean · required
It was the last account behind a bank connection, so the connection was removed too.

LedgerLine

One posting to the account, with the balance it left behind.

Fields

amount
Money · required
Always positive; direction says which side.
date
date · required
description
string · required
direction
string · required
debit or credit.
id
integer · required
The journal line id.
running_balance
Money · required
The account's balance after this line, positive on its normal side, counting every earlier line whatever page it is on.
source
string · required
Where the entry came from: plaid, import, manual, …
statement_line
string | null · required
The line as the bank printed it on the statement (SQ *BLUE BOTTLE 0412 OAKLAND CA). Null on an entry nobody imported.
transaction_id
integer · required
The journal entry the line belongs to (transactions.get takes it).

LedgerLineList

A page of an account's journal lines, oldest first.

Fields

data
array of LedgerLine · required
has_more
boolean · required
next_cursor
string | null · required

LowBalanceAlert

"Tell me when this account drops below …".

Fields

below
boolean · required
The balance is under the threshold right now.
below_since
datetime | null · required
When the balance was seen dropping below the threshold, which is when the member was notified; null while it is at or above it.
shortfall
LowBalanceShortfall | null · required
The recurring bills and paychecks expected on the account over the next month, and the payments of the credit cards it pays (bills first on a day), take the balance under the threshold; the member is notified once and has a to-do while it stands. Null when they do not, and while the balance is already below.
threshold
Money · required
Alert when the balance drops below this.

LowBalanceShortfall

The recurring bills and paychecks expected on the account over the next month take its balance under the alert's threshold.

Fields

bill_amount
Money · required
That bill's usual amount; for a card, what paying it in full takes.
bill_kind
string · required
recurring: a charge the recurring detector found. card_payment: a credit card this account paid last, expected to be paid in full by its due date.
bill_name
string · required
The expected bill that takes it under: a recurring charge's name, or the name of the credit card whose payment it is.
lowest
Money · required
The lowest the balance is projected to reach over the month.
needed
Money · required
What to move in now to stay at or above the threshold all month.
short_on
date · required
The first day the balance is projected under the threshold.

Money

An amount and its currency. `amount` is a base-10 string with two decimal places and an optional leading minus sign. Parse it with a decimal type, not a float.

Fields

amount
string · required
Pattern: ^-?\d+\.\d{2}$.
currency
string · required
ISO 4217 code. Pattern: ^[A-Z]{3}$.

Purge

What erasing takes (`dry_run`) or took.

Fields

account_ids
array of integer · required
blocker_count
integer · required
blockers
array of PurgeBlocker · required
entries
integer · required
Journal entries deleted outright.
erased
boolean · required
False on a dry run, or when blockers refused it.
released
integer · required
Transactions on accounts that stay, unpaired from a transfer into an erased account and categorized again. Their balances do not move.
transactions
integer · required
Transactions of the erased accounts.

PurgeBlocker

Fields

date
string | null
id
integer · required
kind
string · required
entry: a journal entry (id is its transaction id) that also moves an account being kept. child_account: a sub-account of one being erased.
label
string · required