Before you close
Three reads tell you whether the month is ready:
- Is the bank feed complete?
get_period_completenessfor the month.chain_intact: truewith a non-zero line count means no line is missing. Afirst_breaknames the span and the gap in cents; import the missing window first. See the balance chain. - Is anything unworked?
get_bookkeeper_worklistcounts untriaged lines, unmatched credits and debits, purchases missing evidence, unpaired shoebox receipts and stale staged operations. A closed month with an unmatched deposit in it is legal, but it is a month you will reopen. - What will the figures be?
get_month_end_statusreturns the close state (open, closed, reopened) and a live summary of received, ex-GST, GST, receipt count and outstanding AR.
Close the month
"Close September."
run_period_close with kind: "month" and any date inside the month. The
tool computes the canonical span and label (2026-09) for you. In order:
- Every bank line in the range is tied by running balance. A break refuses
the close with
bank_completeness_failed, naming the first break's date and the gap. No row is written. - The cash figures are snapshotted into the close record and the period is marked closed.
- The response carries the snapshot and, if the covering quarter or year was already closed, notes that it is now stale.
On screen: Finance, then Periods, the month's card, "Close", then "Confirm close". If the chain is broken the screen names the break and offers "Sign off over the gap with this reason"; that sign-off is audit-logged.
Closing is idempotent per period: re-running re-snapshots the same row.
Close the quarter and the year
"Close the July to September quarter."
The same tool with kind: "quarter". Quarters follow the Australian financial
year: Q1 is July to September, Q4 is April to June. The stored label uses the
calendar year the quarter starts in, so FY2027's four quarters are 2026-Q1,
2026-Q2, 2027-Q3 and 2027-Q4. get_period_ladder returns both the stored
label (pass it back to close or reopen) and the displayLabel a human should
be told, Q1 (Jul–Sep 2026).
The ladder gate is soft: closing a quarter while a child month is open is
allowed, and the response lists open_child_months with a warning. A child
closed afterwards does not retro-lock the parent; close the months first and
the roll-up is consistent by construction.
kind: "fy" closes the financial year, named by its end year (FY27 is 1 July
2026 to 30 June 2027). A month, its quarter and the year are distinct closes
and coexist.
Cross-check against another system
If the business still runs Xero or a spreadsheet for the same period, pass
xero_peer_total_cents, the total that system reports as received. Biloh
stores the signed variance on the close row. A non-zero variance without a
variance_reason is refused with needs_variance_reason: true and the exact
figures, so a close with a material difference and no explanation cannot
exist. Omit the peer total and the close is recorded as unverified, never as
reconciled.
Read the ladder
"What is closed for this financial year?"
get_period_ladder returns the twelve months, four quarters and the FY row
with each one's state: open, closed, reopened, or stale. Stale means a
child was reopened after this period was closed; re-close it to refresh the
roll-up. Closed rows carry their frozen received and GST snapshot.
Reopen, correct, re-close
"Reopen September, a payment came in late."
reopen_period requires a reason and records who and when; that reason is the
audit trail for why a signed-off month was touched. Make the correction
(match the late deposit, settle the bill), then close again. The covering
quarter and year go stale until they are re-closed. A period pack generated
from the earlier close stays readable forever; a new one is minted as the
next version and marked as superseding it.
What a close prevents
A settlement whose paid date falls inside a closed period is refused. A bill cannot be settled into a locked month by accident, and the figures an accountant has already been given cannot drift under them.