# Agentic Finance Workflows on Xero: A CFO and Project-Lead Pattern

> Xero is the cloud ledger most growth-stage CFOs and project-led businesses actually run on. Here is how we layer agents on top — for the CFO who needs cash, runway, and margin answers in minutes, and the PM tracking live budget variance across a portfolio of projects — without ever owning the keys.

Published: 2026-04-21
Updated: 2026-04-22
Author: Archie Norman (Founder, Tallie AI)
Category: Implementation
Tags: xero, accounting-api, agentic-finance, cfo, project-management, budgets, oauth, implementation
Canonical URL: https://tallie.ai/blog/agentic-workflows-on-xero

## TL;DR

- Xero is a near-perfect substrate for agentic finance for the inverse reasons SunSystems is: a fully-typed REST surface, scoped OAuth 2.0 per write capability, webhooks for event-driven triggers, idempotent writes, and multi-tenant access from a single connection.
- The right unit of work is a `skill` mapped to one or more Accounting API endpoints — with a fixed OAuth scope set, an `Idempotency-Key` on every write, and a `Status: DRAFT` first-pass for anything that posts to the ledger. Free-form tool calls against Xero do not survive App Partner review.
- The five workflows that pay off first for a CFO and a project-led team are: a Monday-morning cash-and-runway briefing, live project P&L with budget variance, customer and project portfolio profitability, multi-entity consolidation across a single OAuth grant, and AR follow-up framed as a working-capital lever.
- Customer-controlled AI on a cloud-native ledger means a different architecture from on-prem: refresh tokens stored in the customer's secret store, the agent runtime in the customer's VPC or Tallie's segregated cloud, the LLM call routed per-task — and the App Partner data-handling story written down before a single skill ships.

---

We have written about layering agents on top of [SunSystems](/blog/agentic-workflows-on-sunsystems) — a private-hosted, XML-payload, on-prem-shaped ledger. Xero is the other end of the spectrum: cloud-native, REST-shaped, OAuth-mediated, multi-tenant from day one, and overwhelmingly the system of record for the long tail of growth-stage CFOs, project-led services and construction businesses, ecommerce brands, hospitality groups, and the accounting practices that serve them.

It is also the system where the highest-value agent workflows are not the ones AI vendors lead with. The bookkeeping pitches — bank rec, bill capture — are real and have already been spoken for. The space that has been left empty is the one a CFO actually lives in: cash and runway answers in minutes instead of Sunday evenings, live project P&L instead of month-end PDFs, customer-level profitability that is current rather than retrospective, group consolidation that runs on demand instead of in week one of next month.

This post is a sketch of the pattern we use to deliver those workflows on Xero — for a CFO, a finance manager, and a project lead — without the agent ever owning the keys, breaking the OAuth contract, or surviving past a `disconnect` from the connected-apps screen. It looks the same as the SunSystems pattern in shape and very different in plumbing.

## Why Xero is a good substrate for agents

The instinct on Xero is the inverse of SunSystems: people assume cloud-native + REST = trivial integration, and stop thinking. Xero rewards a more careful read.

There are four structural reasons Xero is unusually well-suited to agentic finance:

1. **The Accounting API is fully typed and scope-segmented.** Every meaningful object — `Invoice`, `BankTransaction`, `ManualJournal`, `Contact`, `Account`, `TrackingCategory`, `Payment`, `BatchPayment`, `CreditNote`, `Quote`, `PurchaseOrder` — has a documented, versioned schema, an explicit lifecycle (`DRAFT` → `SUBMITTED` → `AUTHORISED` → `PAID`/`VOIDED`/`DELETED` for invoices; `DRAFT` → `POSTED` for journals), and a separate read scope and write scope. Granting an agent `accounting.transactions.read` lets it see invoices and bank lines; it physically cannot create one. That is exactly the granularity an agent capability model needs.
2. **Writes are idempotent by design.** Every mutating call accepts an `Idempotency-Key` header — a UUID the client generates and Xero remembers for 24 hours. Replay the same key, get the same result; you can hammer the API on a flaky network and never produce a duplicate journal. For an agent runtime that retries on failure, this is the difference between safe and dangerous.
3. **Webhooks turn the system of record into an event source.** Subscribe to `INVOICE` or `CONTACT` events and Xero will push a signed (HMAC-SHA256) notification on create or update, scoped per tenant. An agent runtime no longer has to poll; it can react to "invoice authorised" or "contact updated" and run the right skill at the right time.
4. **Multi-tenant is native.** A single OAuth 2.0 grant can authorise an app against many Xero organisations at once, each addressed by a `Xero-tenant-id` header. For accounting practices running 50, 200, or 800 client organisations, this turns "I want to sweep every client for unallocated bank lines" from an integration project into a `for tenant in tenants:` loop.

You can build the same patterns we built for SunSystems on Xero — and you get cheaper compose-ability, real-time triggers, and free retry safety, in exchange for losing the "everything stays inside one VPC" story. That trade is worth understanding before designing skills against it.

## The wrong way to do this

The tempting first move on Xero is "give the LLM a tool that wraps `POST /Invoices` and a system prompt that says 'be careful.'" Demos beautifully. Survives no App Partner review. Falls over the first time a user says "raise an invoice for May" and the model raises twelve, because the retry policy kicked in and there was no `Idempotency-Key`.

The CFO-shaped failure modes are quieter and more dangerous. The model produces a beautiful cash narrative — anchored on a balance that was correct yesterday but ignores a £180k bank settlement that hit overnight, because nobody told the agent to refresh first. The model claims a project is on budget — using a `TrackingCategory` that was renamed last quarter and now silently excludes 30% of the costs. The model writes a board-pack paragraph that compares actuals to a budget version that was superseded six weeks ago, because the `Budgets` endpoint returns multiple versions and the skill picked the first one.

There are six failure modes that show up in week one:

- **Over-broad OAuth scopes.** The app requests `accounting.transactions` (the write scope) for everything, regardless of which skill is being run. A controller looking at the consent screen sees "this app can create, edit, and delete invoices, bills, manual journals, and bank transactions across the whole org" and quite reasonably denies it. The agent now has the keys to a kingdom it never needed to enter.
- **Unbounded mutation surface.** Without per-skill capability scoping, the model can in principle emit a `POST` against any endpoint the connection has scope for. The blast radius of one confused turn includes the chart of accounts, contact records, and the live ledger.
- **No `DRAFT` first-pass.** Free-form tool calls go straight to `Status: AUTHORISED` because the demo script wanted to show "AI posted an invoice." Real customers find out their first AI-generated invoice was sent to a customer with the wrong tax rate, and the recovery is a credit note plus a phone call.
- **No `Idempotency-Key`.** A network blip retries the call. Xero, with no idempotency key to deduplicate against, accepts it. Now there are two invoices, two emails, and one annoyed customer.
- **Stale read.** The agent answers "what is our cash position?" against a cached `BankSummary` that is six hours old; the actual answer is materially different because a wages run cleared overnight. CFOs detect this within a week and never trust the system again.
- **Silent dimension drift.** The agent uses a `TrackingOption` name in its prompt or skill config; an admin renames the option in Xero; the skill keeps emitting the old name; the project P&L now silently drops everything tagged with the new one. The number on the page is wrong by 30% and looks plausibly right.

The fix is not "a more careful prompt." It is the same shift we apply elsewhere: stop letting the model decide *what kind of action* is happening, and only let it decide *the parameters within an action*. The thinking is the same as the four-layer model we use for [LLM-generated SQL against a warehouse](/blog/warehouse-sql-safety) — extended by Xero's specific defences (scope per skill, idempotency per write, `DRAFT` per post).

## Skills, not free-form tool calls

The unit of work in our Xero deployments is a **skill**: a versioned, code-reviewed artifact that describes one finance operation, the Xero endpoints it calls, the OAuth scopes it requires, the parameters the agent is allowed to set, and the review gate that runs before any write reaches `AUTHORISED`.

A Xero skill is a small bundle, deployed alongside the agent runtime, that contains:

- **The endpoints it touches.** For example: `GET /BankTransactions` + `GET /Invoices` + `POST /BankTransactions` for a bank reconciliation skill, or `POST /Invoices` + `POST /Attachments` for an AP intake skill.
- **The exact OAuth scope set.** The bank-rec skill above runs with `accounting.transactions.read` + `accounting.contacts.read` + `accounting.transactions` (the write scope, only because of the final reconciliation step). The AR follow-up skill runs with `accounting.reports.read` + `accounting.contacts.read` only — it physically cannot post anything.
- **A scoped parameter schema.** The skill declares which fields the agent is allowed to populate (e.g. `LineItems`, `Reference`, `DueDate`, `Tracking`) and which are fixed by the skill (e.g. `BrandingThemeID`, `Status: DRAFT` on initial post, `LineAmountTypes`).
- **A `DRAFT` review gate.** Every Invoice, Bill, Credit Note, and Manual Journal is created with `Status: DRAFT` first. Xero applies its own tax calculation, GL coding, and validation against the chart of accounts, and the materialised draft is shown back to the user. Only on explicit approval does the skill `POST` again with `Status: AUTHORISED`.
- **An `Idempotency-Key` policy.** Every write carries a deterministic UUID derived from the skill run id and the operation index, so retries within 24 hours are safe.
- **A per-tenant call budget.** Xero enforces 60 calls/minute and 5,000 calls/day per tenant (10,000 for partner apps); the runtime respects this so a runaway skill cannot starve other skills against the same org.
- **A user identity contract.** The OAuth grant is held against a specific human user; their Xero permissions are the agent's permissions. A staff user with "Read Only" cannot, via the agent, mutate anything — the API rejects it server-side.
- **A deterministic audit log line.** Every skill execution writes a structured record: who asked, which skill ran, which tenant it ran against, what scopes were used, what payload was sent, what `DRAFT` came back, what the user approved, what `AUTHORISED` returned, the `Idempotency-Key` used, and which model produced any free-text fields.

Authoring a Xero skill is a half-day exercise once the pattern is in place. The Accounting API is small enough — a few dozen genuinely useful endpoints for any one customer — that the catalogue gets covered quickly.

## The five workflows that pay off first

The Xero workflows where agents earn their keep are not the ones marketed loudest. They are the ones a CFO or a project lead would build themselves if they had unlimited time. The five below are the shapes we see compound the hardest across our engagements — they go from "Sunday-evening Notion doc" or "month-end PDF" to a live answer the same week the OAuth grant is signed.

The bookkeeping layer (bank reconciliation, AP intake from Hubdoc, AR sweeps) is real and we ship it — but it is the floor, not the ceiling, and we have written it up briefly at the end. The CFO and project workflows are where the curve changes.

### 1. The CFO's Monday-morning briefing

The single most-asked-for workflow we hear from growth-stage CFOs on Xero. Most of them spend Sunday evening — or 06:00 Monday — pulling the same numbers into the same Notion page or board-pack template. None of them want to. The numbers all live in Xero already; the friction is that no single screen composes them, and every one needs context the standard reports do not provide.

The skill version, end-to-end:

- **Trigger.** Cron at 06:00 Monday in the org's timezone, or webhook on bank line settlement so the briefing always reflects what cleared overnight.
- **Reads.** `BankSummary` across every operating account (multi-currency normalised to the org's base currency at today's rate), `ProfitAndLoss` MTD and YTD against the active `Budgets` version, `AgedReceivables` and `AgedPayables` summaries, the last 13 weeks of `BankTransactions` for trend, the live `Contacts` with overdue balance > org threshold, the org's tracked `BankFeeds` for any account flagged as "operating cash".
- **Computations.** Cash position across all accounts. 13-week cash forecast composed from authorised AR (timed by each contact's historical days-to-pay), authorised AP (timed by each supplier's payment terms), recurring payroll/rent/loan-repayment lines, and the remaining budget commitments for the period. Gross and net margin trend vs the previous four weeks. DSO, DPO, and the cash conversion cycle. Top five MoM movements, called out with the specific transactions that drove them. Runway in months at the current trailing-three-month burn.
- **Output.** A one-page narrative briefing the CFO reads in four minutes. Every figure is a Xero deep link — click "AR aged > 60 days at £180k" and you are in the Xero contact view, filtered to the right two contacts, in the right currency, signed in as your own user.

A worked example. A series-B SaaS CFO with £4.2M ARR and a 22-month cash runway used to spend Sunday evening rebuilding the same picture by hand. Their Monday briefing now reads: *"Cash £6.8M (down £210k WoW, in line with the bi-monthly payroll cycle). MTD revenue £342k against £395k budget — 87% of run-rate target, gap concentrated in two stalled enterprise renewals. Top spend movement: AWS bill up £18k vs prior month, driven by a 30% increase in RDS storage on the staging account (link to bill, link to contact). AR aged > 60 days at £180k concentrated across two enterprise customers — Customer X £120k, Customer Y £60k — Customer X chase email already drafted by the AR follow-up skill, awaiting your approval. Runway 21.4 months at trailing-three-month burn — down 0.3 months on prior week."* The CFO reads it on the train. The Monday board call starts with the answer instead of the prep.

### 2. Live project P&L and budget variance

The workflow that earns the agents their place on a project-led business — agencies, construction firms, professional services, anyone running 20+ live engagements where the difference between profit and loss is whether anyone notices a cost overrun before week eight.

The standard Xero answer for project tracking is the two `TrackingCategories` (most teams use them as project + department) and, for teams on the right plan, the Xero Projects API with timesheets and per-project estimates. Both surface raw data. Neither composes a live, ranked, traffic-light view of the portfolio.

The skill, per project:

- **Reads.** All `Invoices` tagged with the project's `TrackingOption` for revenue. All `Bills` tagged with the same option for direct cost. `TimeEntries` from the Xero Projects API — converted to cost at each user's loaded rate — for labour cost when timesheets are the source of truth. The `Budgets` endpoint for the project's current-version budget allocation across revenue, cost, and margin. The project's `Estimate` from Xero Projects, if present.
- **Dimension hygiene.** The skill resolves `TrackingOption` by ID, not by name; option renames in Xero never silently break the variance number. If a tagged transaction's option ID has been deleted (rather than renamed), it surfaces in an "orphaned tagging" tray rather than disappearing from the totals.
- **Computations.** Budgeted revenue vs actual revenue with % consumed. Budgeted direct cost vs actual direct cost with % consumed. Gross margin in absolute and % terms vs the budgeted margin. Timeline progress (days elapsed vs project duration) overlaid on cost progress so a project burning 90% of budget in 50% of timeline is flagged. Unbilled revenue: time entries logged but not yet invoiced, plus milestone deliverables passed but unbilled.
- **Surface.** Every active project as one row in a portfolio view, traffic-light coloured: green (on track), amber (>75% of budget consumed faster than timeline), red (>90% consumed or already over). Click any row for the underlying Xero invoices, bills, time entries, and the proposed corrective actions ("raise £18k of unbilled time on milestone 4", "investigate £6k subcontractor bill double-tagged across projects A and C").

A worked example. An 80-person creative agency CFO running 80 active client projects: in the first weekly run, the skill flagged 12 projects where actual costs were over 90% of budget with under 60% of the work complete (the scope-creep early-warning), and 6 projects where revenue should have been recognised but no invoice had been raised — £94k of unbilled revenue surfaced and converted into Stripe-ready invoices that week. By month three, the average time from "project crosses 75% of budget" to "PM intervention" had dropped from eleven days (catching it in the month-end PDF) to one (catching it in Tuesday's portfolio view).

### 3. Customer and project portfolio profitability

The workflow that turns "we know revenue per customer" into "we know contribution margin per customer." Xero gives you the first cheaply; almost no SMB or mid-market does the second, and the answers are often surprising in directions that change the business.

The skill:

- **Trigger.** Monthly, after the prior period is locked. Or on demand for board-prep season.
- **Reads.** Twelve months of `Invoices` (revenue) grouped by `Contact` and, where applicable, by project `TrackingOption`. Twelve months of `Bills` allocated to customer-serving cost centres or projects. Direct cost-of-service estimates from a customer-defined cost-allocation model (loaded labour, infra per seat, support contact-rate × volume — the model is part of the skill config and version-controlled like any other artefact). For agencies and PS firms with Xero Projects, the per-project labour cost from `TimeEntries`.
- **Computations.** Revenue per customer (and per project). Contribution margin per customer once true cost-of-service is modelled. Pareto curve — top 10 customers as a % of revenue, of margin, of receivables risk. Customer concentration risk (top-3 share, HHI). Bottom-quartile customers ranked by negative margin — the loss-leaders the company is paying to serve. Top-quartile flagged for expansion.
- **Surface.** A ranked customer list with a margin column nobody had before, drilling into the contributing invoices, bills, and time entries. A flagged action list: "renegotiate", "graceful churn", "expand", "investigate".

A worked example. A six-person services business with £2.1M revenue: skill ranked 47 customers by contribution margin and identified 11 in the bottom quartile collectively contributing **−£42k margin** (loss-making once true cost-of-service was modelled — three of them had been on the books for years, accepted as "good logos"). Three were renegotiated upward, three were graceful churns, the rest were re-scoped. Net effect after 90 days: +£68k annualised contribution and a 4-point improvement in blended gross margin. Nothing about the data was new — it was always in Xero. The composition was new.

### 4. Multi-entity consolidation for group CFOs

Xero's multi-tenant model — one OAuth grant authorising access to many `Xero-tenant-id` orgs — is built for accounting practices, but it is the same primitive that lets a group CFO with a dozen OpCos run consolidation as a workflow rather than a project.

The skill:

- **Trigger.** Weekly cadence for the group flash, on demand for board prep, or on a `period locked` webhook from any constituent OpCo.
- **Reads.** For each tenant in the group's connected list (one OAuth grant, one consent screen, many tenants), pull `ProfitAndLoss` and `BalanceSheet` for the period, `BankSummary` for cash, the tenant's chart of accounts so the skill can map to the group reporting chart, and a customer-maintained intercompany contact-pair table (which contacts in OpCo A are intercompany counterparties of which contacts in OpCo B).
- **Computations.** Per-entity P&L, BS, and cash position normalised to the group reporting chart. Intercompany elimination using the contact-pair table — with mismatches (OpCo A's intercompany receivable does not equal OpCo B's intercompany payable for the same period) flagged as a warning, not silently netted. Group-level consolidated P&L, BS, and cash position. Per-entity contribution to group margin. Per-entity working capital trend with cash buffer days. Region or business-line cuts via consistent tracking categories applied across OpCos.
- **Surface.** A consolidated view, with every group-level number clickable down to the originating OpCo and the underlying transactions. Variance flags ranked by materiality. The intercompany mismatch tray.

A worked example. A 14-OpCo hospitality group whose monthly close used to take two weeks — manual export from each entity, manual elimination in a master spreadsheet, manual narrative for the board pack. The skill now produces the consolidated view at T+2 business days, with each line clickable down to the originating tenant. Two OpCos consistently operating below the group's 30-day cash buffer are flagged automatically every Tuesday — the CFO walks into the operating review with the answer instead of the prep work, and the conversation is about what to do about it rather than about what the number is.

### 5. AR follow-up as a working-capital lever

Aged receivables follow-up is often pitched as a clerk's task. For a CFO, it is a working-capital instrument — the difference between a 28-day and a 38-day DSO on a £6M annual revenue book is roughly £165k of permanently tied-up cash. We frame the AR skill as a CFO dashboard with chase actions underneath, not the other way round.

The skill:

- **Trigger.** Daily AR sweep at 07:00, or webhook on `INVOICE` crossing the overdue threshold.
- **Reads.** `AgedReceivablesByContact` from the Reports endpoint. For each overdue contact, twelve months of `Invoices` (paid and unpaid) and `Payments` against them, plus any `CreditNotes` and contact `Notes` indicating disputes.
- **Computations.** Per-contact: average historical days-to-pay, current overdue exposure, dispute risk, payment-behaviour segment (prompt-payer slipped, chronic-late payer, dispute, large-balance). For the CFO view: total overdue balance, expected cash inflow next 30 days if every overdue invoice is collected on its historical pattern, total in active follow-up, total in dispute, the DSO impact of clearing the dispute pile.
- **Actions.** Drafts a follow-up per segment in the org's voice with the specific invoices, due dates, and a payment link if Stripe/GoCardless are connected. Prompt-payer slips get a soft nudge; chronic-late accounts get a firm reminder with a payment plan offer; disputes route to the account owner with full context. The user approves a batch; the skill sends through the org's existing send domain, records the activity against the contact in Xero `Notes`, and schedules the next escalation.

The CFO does not sit in the chase queue. They see a working-capital pane: *"AR overdue £312k. If we collect on historical patterns: £198k inflow next 30 days, £74k next 60. £40k stuck in dispute (3 contacts) — releasing it would cut DSO by 2.4 days. Active chases: 17 emails ready for review."* The skill never marks an invoice as paid — that stays a human action. What it does is turn a 90-minute weekly clerk task into a 10-minute CFO decision and a one-click batch approve.

### Bookkeeping workflows that compound underneath

These do not headline a board pack, but they are the layer on which every CFO and PM workflow above depends — they are the reason the briefing in workflow 1 is trustworthy at 06:00 Monday.

- **Bank reconciliation co-pilot.** Xero's stock "suggestions" engine is a string match. Our skill reasons over the contact's payment history, the open invoice list, the GL code that contact's bills usually go to, and the tracking category implied by the project the line clearly relates to. A two-person agency we shipped this for went from 4 hours/week of bank reconciliation to 25 minutes, with a 96% auto-approve rate after three weeks of contact-history learning.
- **AP intake beyond Hubdoc.** Hubdoc captures bills; it does not code them, check them against supplier history, or flag the duplicates it routinely misses. The skill resolves the supplier against `Contacts`, applies the supplier's default account code and tracking category, queries the last 90 days of ACCPAY invoices for duplicate-bill risk, and posts a fully-coded `Status: DRAFT` ACCPAY invoice with the original PDF attached for review.
- **Period-close hygiene with a final lock.** A structured, runnable checklist replacing the forty-item Google Doc: pre-close sweep (unreconciled lines, draft items, suspense balances, FX revaluations, depreciation runs), adjusting `DRAFT` `ManualJournal` proposals with calculation evidence, the standard report pack with variance narrative, and finally `POST /Organisation` with `PeriodLockDate` set so post-close edits require an audited unlock. A six-person finance team using this cut their close from nine business days to four.
- **Multi-tenant advisor sweeps.** For accounting practices: the same skill across every tenant the OAuth grant authorises, in parallel, respecting per-tenant rate limits. Unallocated bank lines older than 14 days, draft invoices past issue date, drafted-and-forgotten manual journals, contacts missing default codes, GST/VAT inconsistencies, periods unlocked despite filed returns — all aggregated into one practice-wide dashboard with one-click jump into each client's Xero.

## The deployment posture that actually clears procurement

Xero is, by definition, internet-facing. The integration architecture question is not "how does the agent reach Xero" — that is `https://api.xero.com` from anywhere — but "where do the OAuth refresh tokens, the agent's working data, and the LLM call live."

We support two deployment shapes, both honouring the same control regime:

- **Customer-cloud deployment.** The agent runtime runs in a small VPC inside the customer's own cloud account (AWS, GCP, Azure). Xero refresh tokens are stored in their secret manager (Secrets Manager, Secret Manager, Key Vault), encrypted with their KMS key. Outbound calls from the runtime are restricted to `api.xero.com` and the LLM endpoint of their choice. The model call is the only thing leaving the VPC, and for sensitive workloads we route to a self-hosted open-weights model in the same VPC, with no prompt or response ever leaving.
- **Tallie-managed cloud.** The agent runtime and the per-customer working datastore run inside Tallie's managed cloud, segregated per customer. Refresh tokens are encrypted at rest under a KMS key the customer holds and can rotate; we never see the unwrapped token. The customer still picks the LLM: their own OpenAI / Anthropic / Bedrock contract, a self-hosted open-weights model in their cloud, or a model hosted by us on their behalf. Routing is per-task and reversible.

In both shapes, four things remain the same:

- **The OAuth scopes are the union of what enabled skills require, and nothing more.** The consent screen the user signs is the contract; we cannot widen it without re-consent.
- **The LLM is a customer choice.** Per task. Reversible. Including "use ours, not yours."
- **Skills, prompts, the run log, and the materialised drafts are owned by the customer**, stored where they want them — their object storage, ours, or both.
- **Disconnect from Xero's connected apps screen and every skill stops working.** The kill switch is the user's, not ours.

This is the part that matters for App Partner review and for any controller that has read a SOC 2 report end-to-end. "Customer-controlled AI" on a cloud-native ledger is a different architecture from on-prem, but the control claim — *the customer decides where the agent runs, which model it routes to, which scopes it holds, and how it touches data* — is identical.

## What this looks like on day 90

A finance team using Xero with this pattern in place is not doing AI. They are doing finance, slightly faster, with the senior people spending more time on the questions only they can answer.

The visible changes line up with the people who actually open Xero:

- **The CFO** opens a briefing pane on Monday morning instead of rebuilding it on Sunday night. Cash, runway, margin, top movements, AR risk, and the things that need their attention this week — composed from live Xero data, every figure click-through. The board pack is written from the same skill outputs and is "approve, edit, send", not "open spreadsheet, paste, format, repeat."
- **The project leads** open a portfolio view that updates as bills and invoices land, not as the month-end PDF arrives. Projects edge into amber early enough to do something about it. Unbilled work surfaces on a Tuesday, not on the close call.
- **The bookkeeper** approves batched reconciliations, drafted bills, and a chase queue that has already been segmented — and reserves their attention for the 4% of lines a human should be looking at.
- **The CTO** has a one-page architecture diagram with "scoped OAuth," "idempotent writes," "DRAFT-first," "tokens in our KMS," and "customer-chosen LLM" on it. **The auditor** has the run log: who asked, which skill ran, which scopes were used, what `DRAFT` came back, what was approved, what `Idempotency-Key` was used, and which model produced any free-text fields.

The general ledger is still in Xero. The chart of accounts has not moved. Hubdoc, Stripe, GoCardless, the payroll integration, and the practice's QBO bridge for the few non-Xero clients all work exactly as they did. Nothing was rebuilt.

That is what "AI for Xero" looks like when it is taken seriously: not a replacement for the ledger, not a marketplace app that ignores its scopes, but a thin agent layer that finally lets a structured cloud back end be operated through a 2026 interface — and lets the CFO and the PMs get the answers they would build themselves if they had unlimited time.

> **Building on Xero and want a closer look at this pattern?** This is the kind of engagement we are explicitly built for: forward-deployed engineers, customer-controlled AI runtime, skills authored against your own Accounting API surface and your own tenants. [Get early access](/#join) and we will set up an architecture call.
