Developers
API reference

Changes

get/v1/changes

List changes (the change feed)

changes.listread tokenidempotent

What changed in the ledger, oldest first, over the last 30 days. To follow it, store next_cursor and pass it as cursor on the next poll: you get exactly what happened since, in order, never twice and never skipping one (a change appears only once everything before it has committed, so a long import can hold the feed back a moment, never make it jump). Without a cursor the feed starts 30 days ago. A change carries ids, not records: fetch transactions.get and the like for the current state. The same objects are delivered to webhook endpoints (webhook_endpoints.create).

Parameters

limit
integer · query
Page size, 1–200.
cursor
string | null · query
The next_cursor of the previous page.
type
array of string | null · query
Only these change types (transaction.created, transaction.updated, transaction.deleted, account.balance_updated, budget.exceeded, import.completed, job.completed). Repeat to ask for several.
X-Organization-Id
string | null · header

Returns 200 · ChangeList

data
array of Change · required
has_more
boolean · required
next_cursor
string | null · required
Example
curl -X GET "https://api.lumaledger.app/v1/changes" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"
get/v1/changes/{change_id}

Get a change

changes.getread tokenidempotent

One change by its id, for 30 days. A receiver that would rather not trust a delivery's body can fetch it here by the LumaLedger-Change-Id header instead.

Parameters

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

Returns 200 · Change

created_at
datetime · required
data
object · required
The ids the change concerns, and a few facts. By type: transaction.* → transaction_id (and previous_transaction_id when a refile re-posted it under a new id); account.balance_updated → account_id, balance (Money, as the bank reported it), as_of; budget.exceeded → category_id, period, spent and available (Money); import.completed → account_id, row_count, new_count, duplicate_count; job.completed → job_id, kind, status. Fetch the resource for the rest.
id
integer · required
Increases with every change. Deliveries are at least once: dedupe on it.
type
string · required
What happened: transaction.created, transaction.updated, transaction.deleted, account.balance_updated, budget.exceeded, import.completed, job.completed. More may be added.
Example
curl -X GET "https://api.lumaledger.app/v1/changes/{change_id}" \
  -H "Authorization: Bearer $LUMALEDGER_TOKEN"

Objects

Change

Something that happened in the ledger. The feed's items and the body of every webhook delivery are this same object.

Fields

created_at
datetime · required
data
object · required
The ids the change concerns, and a few facts. By type: transaction.* → transaction_id (and previous_transaction_id when a refile re-posted it under a new id); account.balance_updated → account_id, balance (Money, as the bank reported it), as_of; budget.exceeded → category_id, period, spent and available (Money); import.completed → account_id, row_count, new_count, duplicate_count; job.completed → job_id, kind, status. Fetch the resource for the rest.
id
integer · required
Increases with every change. Deliveries are at least once: dedupe on it.
type
string · required
What happened: transaction.created, transaction.updated, transaction.deleted, account.balance_updated, budget.exceeded, import.completed, job.completed. More may be added.

ChangeList

A page of changes, oldest first. Unlike other lists, next_cursor is set on the last page too: keep it, and pass it next time to get only what happened since.

Fields

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