Reconciliation
/v1/reconciliation/exceptionsList reconciliation exceptions
What is waiting for review, newest first: events with no category, suspected duplicates, and balances that do not match a statement.
Parameters
limit integer · query | Page size, 1–200. |
cursor string | null · query | The next_cursor of the previous page. |
is_resolved boolean · query | Resolved ones instead of open ones. |
exception_type string | null · query | Only this exception_type. |
X-Organization-Id string | null · header |
Returns 200 · ReconciliationExceptionList
data | |
has_more boolean · required | |
next_cursor string | null · required |
curl -X GET "https://api.lumaledger.app/v1/reconciliation/exceptions" \
-H "Authorization: Bearer $LUMALEDGER_TOKEN"/v1/reconciliation/exceptions/{exception_id}/resolveResolve a reconciliation exception
Mark an exception settled, with a note saying how. Resolving one changes nothing else in the ledger: fix the cause first (categorize the event, delete the duplicate), then resolve it.
Parameters
exception_id integer · path · required | |
X-Organization-Id string | null · header |
Body · ExceptionResolve
action string | What was done, a short word kept with the note: resolved, ignored, merged, … Pattern: ^[a-z_]{1,40}$. Default: "resolved". |
note string · required | Why it is settled. |
Returns 200 · ReconciliationExceptionOut
created_at datetime · required | |
event_id integer | null · required | The financial event it is about (events.get), if one. |
exception_type string · required | category_missing, suspected_duplicate or balance_mismatch. |
group_id integer | null · required | The reconciliation group it is about, if one. |
id integer · required | |
is_resolved boolean · required | |
resolution_note string | null · required | [action] note, as it was resolved. |
severity string · required | info, warning or error. |
curl -X POST "https://api.lumaledger.app/v1/reconciliation/exceptions/{exception_id}/resolve" \
-H "Authorization: Bearer $LUMALEDGER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"note": "…"
}'/v1/reconciliation/review-queueCount what is waiting for review
The size of the review queue: open exceptions by type, and events still unposted.
Parameters
X-Organization-Id string | null · header |
Returns 200 · ReviewQueue
balance_mismatches integer · required | Open balance_mismatch exceptions. |
duplicates integer · required | Open suspected_duplicate exceptions. |
total_exceptions integer · required | |
uncategorized integer · required | Open category_missing exceptions. |
unposted integer · required | Events not yet posted to the ledger. |
curl -X GET "https://api.lumaledger.app/v1/reconciliation/review-queue" \
-H "Authorization: Bearer $LUMALEDGER_TOKEN"/v1/reconciliation/runRun the matchers
Pair transfers, card payments and pending/posted twins, and flag
suspected duplicates, across the ledger. Imports and syncs already do
this; run it after correcting things by hand. Answers 202 with a Job
(kind reconcile); its result: transfers_matched,
card_payments_matched, pending_posted_matched,
duplicates_flagged. Only rows not matched yet are touched, so running
it again is harmless.
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 |
Returns 202 · Job
created_at datetime · required | |
error | 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. |
curl -X POST "https://api.lumaledger.app/v1/reconciliation/run" \
-H "Authorization: Bearer $LUMALEDGER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"/v1/reconciliation/statementsReconcile an account against a statement
Check the ledger's balance for an account against the balance a bank
statement shows on its closing date. A statement that agrees is
recorded as the bank's balance on that date, once per account and date
(a second time is a 409 conflict); a difference opens a
balance_mismatch exception.
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 · StatementReconcile
account_id integer · required | The bank, card or loan account the statement is for. |
statement_balance string · required | The closing balance the statement shows, as a decimal string, in the account's currency: "1520.34". Pattern: ^-?\d{1,12}(\.\d{1,2})?$. |
statement_date date · required | The statement's closing date. |
Returns 201 · StatementReconciliation
account_id integer · required | |
computed_balance Money · required | The ledger's balance for the account on that date. |
difference Money · required | statement_balance minus computed_balance. |
group_id integer · required | The reconciliation group this check is recorded as. |
is_reconciled boolean · required | They agree to the cent. When not, a balance_mismatch exception is opened. |
statement_balance Money · required | |
statement_date date · required |
curl -X POST "https://api.lumaledger.app/v1/reconciliation/statements" \
-H "Authorization: Bearer $LUMALEDGER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"account_id": 1,
"statement_balance": "1520.34",
"statement_date": "2026-09-01"
}'Objects
ExceptionResolve
Fields
action string | What was done, a short word kept with the note: resolved, ignored, merged, … Pattern: ^[a-z_]{1,40}$. Default: "resolved". |
note string · required | Why it is settled. |
Job
Work that outlives the request that started it. Poll jobs.get
until status is succeeded or failed.
Fields
created_at datetime · required | |
error | 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. |
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}$. |
ReconciliationExceptionList
A page of reconciliation exceptions, newest first.
Fields
data | |
has_more boolean · required | |
next_cursor string | null · required |
ReconciliationExceptionOut
Something the matchers could not settle, waiting for a person.
Fields
created_at datetime · required | |
event_id integer | null · required | The financial event it is about (events.get), if one. |
exception_type string · required | category_missing, suspected_duplicate or balance_mismatch. |
group_id integer | null · required | The reconciliation group it is about, if one. |
id integer · required | |
is_resolved boolean · required | |
resolution_note string | null · required | [action] note, as it was resolved. |
severity string · required | info, warning or error. |
ReviewQueue
How much is waiting for a person.
Fields
balance_mismatches integer · required | Open balance_mismatch exceptions. |
duplicates integer · required | Open suspected_duplicate exceptions. |
total_exceptions integer · required | |
uncategorized integer · required | Open category_missing exceptions. |
unposted integer · required | Events not yet posted to the ledger. |
StatementReconcile
Fields
account_id integer · required | The bank, card or loan account the statement is for. |
statement_balance string · required | The closing balance the statement shows, as a decimal string, in the account's currency: "1520.34". Pattern: ^-?\d{1,12}(\.\d{1,2})?$. |
statement_date date · required | The statement's closing date. |
StatementReconciliation
Fields
account_id integer · required | |
computed_balance Money · required | The ledger's balance for the account on that date. |
difference Money · required | statement_balance minus computed_balance. |
group_id integer · required | The reconciliation group this check is recorded as. |
is_reconciled boolean · required | They agree to the cent. When not, a balance_mismatch exception is opened. |
statement_balance Money · required | |
statement_date date · required |