Reconcile Account
const url = 'https://example.com/accounts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/reconcile';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"as_of":"2026-04-15","basis":"posted","dry_run":false,"statement_balance":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/accounts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/reconcile \ --header 'Content-Type: application/json' \ --data '{ "as_of": "2026-04-15", "basis": "posted", "dry_run": false, "statement_balance": 1 }'Reconcile a checking, savings, cash or credit-card account to a statement balance (issue #268).
Purser compares the statement figure with its own balance on as_of in
the chosen basis and posts ONE adjustment for the difference, dated
as_of, to the system category expenses.reconciliation_adjustments.
The adjustment lands in the review set so a person sees it. When the ledger
already matches, nothing is posted and the clean reconcile is still
recorded. Either way reconciled_through advances and an
account.reconciled event is emitted.
Safe to retry: the same date, balance and basis returns created: false
while the ledger still matches, and 409 reconciliation_moved with the
difference once a backdated change has moved it. GET /accounts/{id}
and GET /accounts/{id}/reconciliations re-check recorded
reconciliations the same way on every read.
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
The statement date: the balance is the one at the end of this day. Today (UTC) or earlier; a future date is rejected.
Which balance the statement reports: posted (cleared rows only, the usual statement balance) or pending_inclusive (posted plus pending, the ‘current balance’ many banks show).
Return exactly what the call would do — the same computation, conflicts included — without writing anything.
Responses
Section titled “Responses”Successful Response
What the reconcile did (or, with dry_run, would do). Amounts are in
ledger sign except statement_balance, which echoes the input.
object
Example
{ "basis": "posted"}The request contradicts a recorded reconciliation. detail.code is reconciliation_moved (this exact reconciliation is recorded, but the ledger balance on that date has changed since — detail.difference = ledger minus target), reconciliation_conflict (a different balance or basis is recorded for that date), or reconciliation_out_of_order (the date is before the account’s latest reconciliation).
Validation Error
object
object
object
Example generated
{ "detail": [ { "ctx": {}, "input": "example", "loc": [ "example" ], "msg": "example", "type": "example" } ]}