Developers
API reference

Plaid Items

get/v1/plaid-items

List bank connections

plaid_items.listread tokenidempotent

The ledger's bank connections, with when each last synced and whether it needs a person to sign in again.

Parameters

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 · PlaidItemList

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

Sync bank connections

plaid_items.syncwrite tokenidempotent

Pull new transactions and balances from the bank, then settle the ledger: match transfers, categorize, apply your rules and post. Connections already sync by themselves when the bank says there is something new; this is the "refresh" button. Answers 202 with a Job (kind plaid_sync). Its result: items_synced, results (per connection, its counts or an error), matched, categorized, llm_categorized, rules_applied, journals_generated and notifications. A connection that fails is reported in results and does not fail the job.

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 · PlaidSync

full
boolean
Pull the whole history again instead of only what is new. Rows already in the ledger are not duplicated. Default: false.
plaid_item_id
string | null
Sync only this connection (from plaid_items.list). Omitted, every one is synced.

Returns 202 · Job

created_at
datetime · required
error
JobError | null · required
Why it failed, once failed.
finished_at
datetime | null · required
id
integer · required
kind
string · required
What the job does: import, categorize, generate_journals, reconcile, run_schedules, plaid_sync or rocket_money_import.
result
object | null · required
What the work produced, once succeeded. Its fields depend on kind and are listed on the operation that started it. Counts are integers.
status
string · required
queued, running, succeeded or failed.
Example
curl -X POST "https://api.lumaledger.app/v1/plaid-items/sync" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'

Objects

Job

Work that outlives the request that started it. Poll jobs.get until status is succeeded or failed.

Fields

created_at
datetime · required
error
JobError | null · required
Why it failed, once failed.
finished_at
datetime | null · required
id
integer · required
kind
string · required
What the job does: import, categorize, generate_journals, reconcile, run_schedules, plaid_sync or rocket_money_import.
result
object | null · required
What the work produced, once succeeded. Its fields depend on kind and are listed on the operation that started it. Counts are integers.
status
string · required
queued, running, succeeded or failed.

JobError

Fields

code
string · required
Stable error code, as in the error envelope.
message
string · required
For people, in the request's language. Never match on it.

PlaidItemList

A page of bank connections, in the order they were linked.

Fields

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

PlaidItemOut

One bank login, feeding one or more of the ledger's accounts.

Fields

bank_refreshed_at
datetime | null · required
When the data provider last reached the bank itself for this connection, new data or not; for a connection with investment accounts, the older of its transactions and its holdings. A sync can succeed while this stays old: the provider then hands back what it last fetched.
created_at
datetime · required
error_code
string | null · required
Why the last sync failed, a stable code.
holdings_error_code
string | null · required
Why fetching the investment positions failed, a stable code; set exactly when holdings_failing_since is.
holdings_failing_since
datetime | null · required
When fetching this connection's investment positions started failing while its syncs still succeed, or null while it works (or the connection has no investment account). Its positions are as of then.
institution_id
integer | null · required
The ledger's institution (the bank) it belongs to.
institution_name
string | null · required
investment_transactions_error_code
string | null · required
Why fetching the investment activity failed, a stable code; set exactly when investment_transactions_failing_since is.
investment_transactions_failing_since
datetime | null · required
When fetching this connection's investment activity (trades, dividends, deposits, fees) started failing while its syncs still succeed, or null while it works (or the connection has no investment account). Activity after then may be missing from the ledger.
last_synced_at
datetime | null · required
When our last sync succeeded.
liabilities_error_code
string | null · required
Why fetching the card and loan details failed, a stable code; set exactly when liabilities_failing_since is.
liabilities_failing_since
datetime | null · required
When fetching this connection's card and loan details (due date, minimum payment, statement balance, rates) started failing while its syncs still succeed, or null while it works (or the connection has no card or loan). Those details are as of then.
new_accounts_available_at
datetime | null · required
When the bank said it has accounts this connection does not share yet (usually a card opened after it was linked), or null when none are waiting. Their activity is not in the ledger until a person adds them in the app, which only they can do: it happens in the bank's own sign-in window.
plaid_item_id
string · required
Plaid's id for the connection. Pass it to plaid_items.sync.
stale
boolean · required
True when the connection should be syncing (active or error) but has delivered no fresh data for over two days: its balances and transactions are out of date. stale_reason says which fix applies.
stale_reason
string | null · required
Why it is stale, or null when it is not. sync_failing: our syncs are not getting through; try plaid_items.sync, and if it keeps failing error_code says why. holdings_failing: syncs bring the activity in but fetching the investment positions has failed since holdings_failing_since, so their values are frozen; try plaid_items.sync, and holdings_error_code says why. investment_transactions_failing and liabilities_failing are the same for the investment activity (trades, dividends, deposits; since investment_transactions_failing_since) and for cards' and loans' due dates, minimum payments and rates (since liabilities_failing_since). bank_silent: syncs succeed but the bank has not answered since bank_refreshed_at, so another sync will not help; it usually clears by itself, and a person can reconnect the bank in the app.
status
string · required
active, error (the last sync failed; the next one may work), login_required (a person must sign in again in the app) or revoked.

PlaidSync

Fields

full
boolean
Pull the whole history again instead of only what is new. Rows already in the ledger are not duplicated. Default: false.
plaid_item_id
string | null
Sync only this connection (from plaid_items.list). Omitted, every one is synced.