Reconciliation

Everything upstream of this reports success on the strength of a 200 from your ledger. A bill deleted by your accountant the following week, or edited to a different total, leaves no trace at all in inletAP — the export said it posted, and it did.

Reconciliation is the only thing in the product that goes back and looks. Each night it reads the bills we posted out of your ledger again and records what is actually there, so the month you close is the month your books hold.

Nothing is written back. A run is read-only against your ledger, in every mode, including when you start one by hand.

Which plans include it

Starter and above. A Free workspace is never queued for a nightly run, and the button on the settings screen refuses with the name of the plan you are on. See plans and limits.

It also needs a connected ledger. QuickBooks Online and Xero are both read; a CSV or SFTP destination delivers a file and posts to nobody's books, so there is nothing about it to reconcile.

When it runs

The nightly sweep fires at 05:20 UTC, and produces one run per connected ledger in the workspace. That time is early enough that a difference is waiting in somebody's inbox before the working day starts, and late enough that the previous evening's export batches have long finished posting — a run overlapping them would read a bill your ledger had accepted but not yet handed back, and report it missing.

You can also start one by hand. Open Settings → Connectors, find the Reconciliation card, and choose Reconcile now. That is an Admin or Controller Approver action; reading the runs is open to everybody. The answer is not immediate: a run is minutes of requests against your ledger, so the button says the run will appear in the list when it finishes rather than pretending to report a result.

What it compares

Every bill inletAP believes it posted to that ledger in the last thirty days, which covers a monthly close with room to spare, capped at the thousand most recent. For each one it asks the ledger for the bill by the id recorded when the post succeeded, and compares.

The comparison is per bill and, for an invoice that fanned out into several bills, per invoice as well. Both are needed: every bill of a split invoice can match its own target amount while the invoice as a whole is short a whole company.

Amounts agree when they are within a cent of each other. That is the same tolerance the export layer applies when it posts, so reconciliation cannot flag a difference the export deliberately allowed, or miss one it was policing.

What counts as a difference

ReasonWhat happened
Not foundThe ledger returned nothing for that id. The bill was created and is not there.
Amount differsThe ledger holds that bill at a different total, or holds no total we can read.
VoidedThe bill is still in the ledger and has been voided there.

A voided bill is checked for before the amounts, because voiding zeroes the lines: tested on the total it would read as an amount mismatch and hide the one thing a person needs to know.

Separately, a split invoice whose bills do not add up to the invoice total is reported in the run's summary line, in a sentence of its own. Folding it into the bill counts would say "4 of 12 bills did not match" about an invoice where every single bill matched.

Two things deliberately do not count:

  • A bill whose own total inletAP never read matches on presence alone. There is no figure to compare, the bill demonstrably exists, and putting it in front of a person with nothing to act on would waste their time.
  • A bill the ledger returned but could not be valued counts as a mismatch, not a match. "We could not check" must never render as "checked and fine".

And one thing it cannot do: it only looks at what inletAP posted. A bill somebody keyed into your ledger by hand is invisible to it, because there is no export item to start from.

Where you look at the result

The Reconciliation card on Settings → Connectors lists recent runs, newest first. Each row carries the time, which ledger it checked, a one-line summary, the counts, and a badge:

  • Clean — every posted bill matched.
  • Differences — at least one did not. View differences opens the list.
  • Failed — the ledger could not be read, so nothing was checked.

A failed run shows no counts at all, and that is the point of telling it apart. Its counters were never written by anything that read your ledger, so printing "0 matched, 0 unmatched" would tell a controller their books agree when nobody looked. The note on the row is the reason the read failed, and it is the only true thing on it.

View differences lists the bills that did not match — the invoice, the ledger's own id, what we expected, what the ledger has, and the reason. Matched bills are not in that list: a hundred agreeing rows would bury the three that need work. One caveat to read past: the reason column is worded for QuickBooks, so a Xero run says "Not found in QuickBooks" when it means Xero.

The email

A run that finds differences sends one, to everybody in the workspace who has A reconciliation run finds differences switched on. A clean run sends nothing, and so does a failed one.

The subject names the count and the ledger — "Reconciliation found 3 differences in QuickBooks Online". The body carries the run, how many bills matched, how many did not, the run's summary line, and up to five examples, each linking to the invoice it is about. The full list stays on the run itself. See email notifications.

What to do about a difference

Nothing is retried for you, and that is a decision rather than a missing feature. inletAP's defence against double-posting a bill is an identifier minted before the first attempt and replayed only for that same attempt; a fresh post of a document whose bill we cannot see would mint a new one. So if the bill does exist and our read simply failed to return it, an automatic retry posts the bill a second time. Double-paying a payable is worse than a line in a report, so a run reports and a person decides.

Start in your ledger rather than here, because that is where the change was made:

  • Amount differs. Somebody edited the bill after it posted. Decide which figure is right. If it is the ledger's, the invoice in inletAP is the stale copy; if it is the invoice's, correct the bill where it lives.
  • Voided. Somebody voided the bill deliberately. The invoice in inletAP still reads as exported, because it was.
  • Not found. Check first that it really is gone, rather than moved into another company or hidden by a filter. inletAP will not create it again: an export item that carries the ledger's own id claims that document for that ledger permanently, so it is never planned into another batch, and a retry is offered only on a batch that failed — which this one did not. Putting the bill back is a job in your ledger.
  • A split invoice that does not add up. Look at each company's bill in turn. The usual causes are a target that never posted, a document re-split between two batches, and a connection switched off so its share went somewhere else.

When the run failed rather than found something, the note says why the ledger could not be read. That is usually a connection that needs reconnecting under Settings → Connectors — and until it is, the nightly run has nothing to tell you.

See also