Can an AI agent run your books? Grading the ledgers.
Xero tested in production use (regraded 2026-09-28); QuickBooks tested on an Intuit sandbox (regraded 2026-09-28); Digits tested on its developer sandbox and Kick over its hosted MCP server (2026-09-26), both web apps tried 2026-09-28. Puzzle is read from its developer documentation while API access is pending, so its grade is from documentation only and marked unverified. Right of reply: Xero (2026-09-29 and 10-01), Intuit (2026-09-29 and 09-30) and Digits (2026-10-05) have answered, and their answers are in the rows below; Kick did not respond by October 5; Puzzle has not answered an access request sent 2026-09-27.
A continuous close only works if an agent can reach the work through the API. We graded the platforms a seed-stage company actually chooses between, on the capabilities that block or unblock agentic operation. Facts below the line, one grade above it.
- ✓ An agent can do this
- ◖ Partial: works with caveats
- ✗ Blocked: a person has to do it
- n/t Not tried yet
| Platform | Agentic Readiness |
Bank feed via API |
Reconciliation state |
Journal entries |
Webhooks / events |
Evidence & attachments |
Reports & GL detail |
Agent in the web app |
Price at seed stage |
|---|---|---|---|---|---|---|---|---|---|
| XeroTested in production, regraded 2026-09-28; confirmed by Xero 2026-10-01 | C+ | ◖ | ◖ | ✓ | ◖ | ✓ | ◖ | ✗ | $20–80/mo |
| QuickBooks OnlineTested on sandbox, regraded 2026-10-01; confirmed by Intuit 2026-09-30 | C+ | ✗ | ◖ | ◖ | ◖ | ✓ | ✓ | ✓ | $38–275/mo |
| PuzzleDocumented 2026-09-26; graded from documentation 2026-10-15, unverified | C− | ◖ | ✗ | ◖ | ✗ | ✓ | ◖ | n/t | $25–150/mo |
| DigitsTested on sandbox, 2026-09-26; confirmed by Digits 2026-10-05 | C+ | ◖ | ✗ | ✓ | ◖ | ◖ | ✓ | ✓ | $65–250/mo |
| KickTested over MCP, 2026-09-26; no reply from Kick by 2026-10-05 | B− | ◖ | ◖ | ✓ | ◖ | ◖ | ✓ | ✓ | $0–300/mo |
The evidence, row by row
What each mark rests on, with the date it was observed. Tested means we did it ourselves, through the API or in the vendor's web app; documented means the vendor's own documentation says so.
XeroC+
10 of 18: both blocking columns partial, two passes, three partial, and sign-in refused to an agent browser. Down from B minus on 2026-09-28 when the web-app column was added. Every claim confirmed by Xero 2026-10-01; no mark changed.
- ◖ Bank feed via API
- Posted bank transactions read and write by API, but pending statement lines are not exposed on the custom connection (BankStatement report returns 401) and feed gaps are invisible; the scrape workaround is fragile. Xero confirmed 2026-10-01 that statement lines are readable only through its Finance and Bank Feeds APIs, which are limited to banks and regulated lenders, so no app of any type can read them
- ◖ Reconciliation state
- IsReconciled is readable on every bank transaction, but nothing reconciles, unreconciles or reads statement-line status by API; the weekly OK click stays in the UI. Confirmed by Xero 2026-10-01, which added that the statement line a transaction is reconciled to cannot be retrieved
- ✓ Journal entries
- Manual journals post with tracking (proved in production); no auto-reversing journal, so reversals post explicitly; AR and AP control accounts take credit notes, not journals. Confirmed by Xero 2026-10-01: the reversal is a separate call, and AR or AP is reversed with a credit note allocated to the invoice
- ◖ Webhooks / events
- Webhooks cover contacts and invoices only; nothing for bank transactions, statement lines or reconciliation. Confirmed by Xero 2026-10-01
- ✓ Evidence & attachments
- Attachments upload and link by API, including on reconciled bank transactions (done daily in production). Confirmed by Xero 2026-10-01
- ◖ Reports & GL detail
- P&L, balance sheet, trial balance and P&L by tracking category by API; the full general ledger (Journals endpoint) is not granted on the custom connection and is reconstructed from transactions, or exported from the UI. Xero answered 2026-09-29 and 10-01: the Journals endpoint is a premium feature, open only to a standard web app on Xero's Advanced tier (or an approved internal-use app) after Xero's annual security assessment, and custom connections made since 29 April 2026 cannot have it. So the full ledger is reachable, but behind a review a company's own connection does not get
- ✗ Agent in the web app
- Tested 2026-09-08 and 2026-09-28: the login page loads in an agent browser, but submitting the sign-in returns an Access Denied page from Xero's bot protection; the browser names itself as an agent in its user agent. So the steps Xero leaves to the web app (bank rules, the reconcile click, lock dates) cannot be done by an agent at all, even through the browser. Xero confirmed 2026-10-01 that bank rules and lock dates are web-app only and that there is no supported way for an agent to use the signed-in web app, with no exceptions to its security controls
QuickBooks OnlineC+
10 of 18: bank feed blocked, reconciliation state partial (readable, not writable), three passes including the web app, two partial. Up from C on 2026-10-01: Intuit pointed to a cleared-status filter, and our test showed reconciliation status is readable on every row of the transaction list report. Confirmed by Intuit 2026-09-29 to 09-30.
- ✗ Bank feed via API
- Bank-feed lines are not exposed by API; sandboxes carry no feed, so this mark is documented, not tested. Confirmed by Intuit 2026-09-30: not available, by design
- ◖ Reconciliation state
- Readable, not writable. No transaction record carries a reconciled or cleared field and the reconciliation report returns 400 (tested 2026-09-26; Intuit 2026-09-30: there is no reconciliation API). But the transaction list report carries a cleared column on every row (R for reconciled, C for cleared) and filters by it: tested 2026-10-01 by marking a deposit cleared in the web app and reading C back through the API. Reconciling and clearing themselves stay in the UI
- ◖ Journal entries
- Tested 2026-09-26 to 09-27: journals post to bank accounts and (with a customer or vendor on the line) to AR and AP, but a class on a journal line is accepted and silently dropped while class tracking is off in Preferences, which cannot be switched on by API; the reference number is capped at 21 characters; no reversing flag, so the reversal is posted explicitly. Confirmed by Intuit 2026-09-29 to 09-30: the dropped class is by design and only a company admin can switch class tracking on, so an app has to warn; a journal can be neither reversed nor voided, only offset; 21 characters is QuickBooks' general reference cap
- ◖ Webhooks / events
- Tested 2026-09-26 to 09-28: change data capture returned 1,422 objects in one call; webhooks delivered a create, update and delete 0 to 14 seconds after each write, signed, carrying ids only; 31 subscribable entities and none for bank feeds or reconciliation. Confirmed by Intuit 2026-09-30
- ✓ Evidence & attachments
- Tested 2026-09-26: receipt uploaded and linked to a Purchase by API
- ✓ Reports & GL detail
- Tested 2026-09-26 to 09-27: GeneralLedger and TransactionList reports, P&L by month, query access to every transaction type; card purchases cannot be filtered by the account that paid them (the query returns 400, not queryable; Intuit could not confirm this one specifically, 2026-09-30), so that scan runs client-side
- ✓ Agent in the web app
- Tested 2026-09-27 to 09-28: signed in and worked in an agent browser and in a scripted Chrome (sandbox company, developer portal, community forum)
PuzzleC−
6 of 18, from documentation only and unverified: feed partial, reconciliation none, journals partial, webhooks none, attachments pass, reports partial; the web app was not tried because there is no account while the partner application is pending. Puzzle has not answered the access request of 2026-09-27. Regraded when API access allows a test or Puzzle confirms or corrects the facts.
- ◖ Bank feed via API
- Feed lines readable with a status (Finalized / NotFinalized / NotCategorized); POST transactions imports into partner-created accounts, not into a Plaid-connected feed. documented 2026-09-26 from developer docs; not yet tested
- ✗ Reconciliation state
- No reconciled or matched field on transactions or accounts; no reconcile endpoint. documented 2026-09-26 from developer docs; not yet tested
- ◖ Journal entries
- Journal entries with class and segment per line; bank accounts allowed on one line only; entries immutable, an update auto-creates a reversal; no reversing option or idempotency key. documented 2026-09-26 from developer docs; not yet tested
- ✗ Webhooks / events
- No webhooks in the documentation; polling by createdAfter on journal entries only. documented 2026-09-26 from developer docs; not yet tested
- ✓ Evidence & attachments
- Receipt, bill or invoice attached to a transaction or a journal entry by base64 upload. documented 2026-09-26 from developer docs; not yet tested
- ◖ Reports & GL detail
- Income statement, balance sheet, cash activity, trial balance; no general-ledger detail report, reconstruct from transactions by account. documented 2026-09-26 from developer docs; not yet tested
- n/t Agent in the web app
- Not tried: the login page loads in an agent browser, but there is no account to sign in with while the partner application is pending
DigitsC+
Tested 2026-09-26 to 09-28, 10 of 18: web app works in an agent browser; feed partial, reconciliation none, journals pass, reports pass; webhooks documented only. Free Connect API, self-serve OAuth app, hosted read-only MCP, 180 req/min. Every claim confirmed by Digits 2026-10-05; no mark changed.
- ◖ Bank feed via API
- Tested 2026-09-26: ledger entries readable with full category and counterparty and the writing app named as the source; no field marks a line pending; writes go only into the app's own Source, never a bank feed; the chart has an Uncategorized Expense bucket to post into. Confirmed by Digits 2026-10-05: there is no pending state and no separate feed; new data is categorized into the ledger as it arrives
- ✗ Reconciliation state
- Tested 2026-09-26: no match or reconciliation field on any entry or transaction; matching and unmatching stay in the UI. Confirmed by Digits 2026-10-05, which called it subject to change
- ✓ Journal entries
- Tested 2026-09-26: a balanced two-line transaction referenced by category id posted to the ledger in about 15 seconds, including to a bank-type category, and reads back whole with its lines; no reversing option (void is for bills and invoices only), so the reversal is your own mirror entry; labels need UI setup, ids do not. Confirmed by Digits 2026-10-05: no single-call reversal, and a reversing entry is written through Sync Transactions with debits and credits inverted
- ◖ Webhooks / events
- HMAC-signed webhooks in private beta; event catalog is bills and bill payments only. documented 2026-09-26 from developer docs; not yet tested. Confirmed by Digits 2026-10-05, with more event types to come before a wider release
- ◖ Evidence & attachments
- Tested 2026-09-26: receipt upload to the vault returned a document id; no way to link it to a chosen transaction, matching is Digits' own. Digits 2026-10-05: linking a receipt to a chosen transaction by API is on its roadmap
- ✓ Reports & GL detail
- Tested 2026-09-26: P&L, trial balance and balance sheet by API; 155-category chart; entry-level query serves as GL detail
- ✓ Agent in the web app
- Tested 2026-09-28: signed in and worked in an agent browser; the developer dashboard, firm client grid and demo client all opened normally
KickB−
12 of 18. Tested 2026-09-26 over the hosted MCP server, web app 2026-09-28 on a free-plan firm workspace: reconciliation state readable, journals pass with auto-reversal, reports pass; feed untested for lack of a connected bank; audit log with actor and diff, and rules by API, as extras. Kick was asked to confirm on 2026-09-28 and had not responded by October 5.
- ◖ Bank feed via API
- Tested 2026-09-26: transactions_query and financial_accounts_query answer with bank description, source type and account, and create_manual exists behind a preview token; no bank was connected, so feed lines themselves were not read
- ◖ Reconciliation state
- Tested 2026-09-26: reconciliation_query reads history and per-account summary and never reconciles; the reconcile step stays in the UI
- ✓ Journal entries
- Tested 2026-09-26: a journal posted through the preview-and-confirm flow, and reversedAt produced the reversal entry automatically; recurring rules on the same payload; list, get and delete all worked
- ◖ Webhooks / events
- Documented: Svix webhooks with one event, a Plaid connection disconnecting; not exercised
- ◖ Evidence & attachments
- Tested 2026-09-26: documents_act request_upload issued an upload preview for a PNG and the transaction-link tool is present; upload and link not completed
- ✓ Reports & GL detail
- Tested 2026-09-26: profit and loss, balance sheet, trial balance and account transactions by reports_query with the ledger id resolved by context_resolve
- ✓ Agent in the web app
- Tested 2026-09-28: signed in with Google and worked in an agent browser at desktop width (narrow windows get a not-on-mobile screen)
Right of reply
Each vendor is invited to confirm or correct the claims in its row. Corrections are made here with the date and the source, and a vendor that confirms is marked as confirmed. Xero confirmed every claim in its row (support cases, 2026-09-29 and 10-01). Intuit's developer group confirmed the QuickBooks row on its developer forum (2026-09-29 and 09-30), and pointed to a cleared-status filter we had missed; our test confirmed it, which moved QuickBooks from C to C+ on 2026-10-01. Digits confirmed every claim in its row on 2026-10-05 (developer relations, by email), adding that a reversing entry can be written through its sync endpoint with debits and credits inverted and that linking a receipt to a chosen transaction is on its roadmap; no mark changed. Kick was asked on 2026-09-28 and had not responded by October 5. Puzzle has not answered an access request sent 2026-09-27, so its row is graded from its documentation and marked unverified until it can be tested. Grades are redone quarterly as the APIs change; this sheet is dated so you can tell how old each mark is.
Why these five
Two rows are what most small businesses already run (QuickBooks Online holds roughly four fifths of the US small-business install base; Xero is the usual alternative), and three are the best AI-native ledgers priced inside the seed-stage band, under about $300 a month per entity: Puzzle, Digits and Kick. The graduate tier is real but out of scope for this lens: Rillet (about $28K a year on buyer data), Campfire (about $25K all-in for a startup tier), DualEntry, Everest Systems and DOSS all price for companies past seed. They get their own sheet when a client grows into them. Selection made 2026-09-26.
What the documentation says about the AI-native three
All three expose the bank-feed lines to a program, which QuickBooks does not, and on the documentation none of the three exposes reconciliation state, which puts them behind QuickBooks and Xero, where an agent can at least read it, on the column that weighs most. Their journal endpoints are narrower than QuickBooks': Puzzle allows one bank line per entry and has no reversing option, Digits accepts source transactions that it then categorizes itself rather than a direct posting, Kick documents no control-account rules. Webhooks are thin everywhere. Where they pull ahead is access: Digits gives any customer a free OAuth app, a hosted MCP server and 180 requests a minute; Kick puts an MCP server and CLI on its free plan; Puzzle's API is still partner-only by application. So the AI-native advantage on this sheet is not that an agent can reach more of the close; it is that the ledger does more of the close itself and lets you watch. Kick is the exception after testing: over its MCP server on a free plan it reads reconciliation state, posts auto-reversing journals, exposes its rules and an audit log with actor and diff, which puts it at B minus, the top of this sheet.
How the grade is built
Each platform is scored on the seven capabilities above, weighted toward the two that block a continuous close outright: bank feed access and reconciliation state. A check scores 2, partial 1, blocked 0, and the two blocking columns count double, for 18 points: 11 or 12 is B minus, 9 or 10 is C plus, 7 or 8 is C, 5 or 6 is C minus. The seventh column, added 2026-09-28, asks whether an agent can sign in to the vendor's own web app in a browser that says it is an agent. It matters because every step a ledger leaves out of its API has to be done somewhere: if the web app refuses the agent too, that step becomes a person's job with no way around it. A check requires the capability to work through the public API without UI intervention. Rows marked tested reflect hands-on API work; documented rows reflect vendor documentation and are re-verified before each regrade. Grades as of October 2026; regraded quarterly as vendor APIs change. Xero notes from the 2026-09-26 regrade: the earlier bank-feed check was wrong, since pending statement lines are not reachable on the connection in use and feed gaps are invisible; reconciliation state is readable but the reconcile itself is a click; journals moved up to a pass because they post with tracking, with the same explicit-reversal caveat as QuickBooks; the full general ledger is a scope question still open. QuickBooks notes from the 2026-09-26 test: the books-close date and class-tracking settings are readable but a write is accepted and ignored, so they stay UI steps; class references on purchase lines persist even with class tracking switched off; transfers delete and receipts attach by API; a sparse update on a card purchase must repeat its payment type or it is rejected. Xero regrade, 2026-09-28: its sign-in refuses an agent browser (first seen 2026-09-08, again 2026-09-28), while QuickBooks, Digits and Kick all let the same browser in, which takes Xero from B minus to C plus. QuickBooks regrade, 2026-09-28, after running the close loop on the sandbox: journals move from a pass to partial because a class on a journal line is silently dropped while class tracking is off (purchase lines keep theirs), which takes the grade from C plus to C; webhooks were tested and deliver ordinary record changes within seconds, with nothing for feeds or reconciliation. Vendor replies, 2026-09-29 to 10-01: one mark changed. Intuit pointed to a cleared-status filter on the transaction list report; tested 2026-10-01, the report carries reconciliation status on every row, so QuickBooks reconciliation state moves from blocked to partial and the grade from C to C+. Every other mark held. Xero closed both open questions: statement lines are for banks only, and the full ledger needs a premium app and a security assessment. Intuit confirmed that the books-close date is read-only by design, and that the id QuickBooks stamps on records it changes itself is an internal system actor that no API resolves, so who changed a record cannot be learned by API (the audit log has no API). Vendor replies, 2026-10-05: Digits confirmed every claim in its row; no mark changed. Kick did not respond. Puzzle, 2026-10-15: the held grade is published from the documentation at C minus (6 of 18) and marked unverified, since Puzzle had not answered and its API stays partner-only.