API Report Card · Corporate Accounting · Methodology v1.1
Xero
Where the points came from.
Five categories, each worth a fixed share of the 100 points. A category earns the fraction of its checks it passes, times its maximum.
Functional Coverage
Design & Reliability
Access Control
Docs & AI-Ready
Access & Cost
Letter grades are absolute, never curved.
The same numeric bands apply to every platform. Nothing here is scored relative to the rest of the board.
What this means for you.
One paragraph per category, in plain language.
1 · Functional Coverage
You can read and change the accounting data your business runs on, post invoices and payments, and update contacts and accounts. What you cannot do is import bank statements or reconcile through the API; a partner bank feed or another tool does that. Plan to poll with the modified-since filter, because webhooks only cover a few record types.
2 · Design & Reliability
Stable and predictable to run in production. Rate limits, pagination, request tracing, and idempotency are all solid, and you can trace any request with support. Watch three things: dates arrive in two different formats, error shapes are not uniform, and there is no lost-update protection, so two writers can overwrite each other.
3 · Access Control
A strong point. You can safely give an app or an AI agent a limited, read-only key, and cut off access at any time. The one gap is testing: there is no true sandbox, you develop against a Demo Company, which is a separate data set but not a separate environment or key.
4 · Docs & AI-Ready
Among the best documentation in this group. A developer or an AI coding tool can build against Xero without reverse-engineering. The reference is complete, the OpenAPI spec and six official SDKs are current, and Xero ships an official MCP server for AI agents. The only soft spot is no llms.txt-style bundle.
5 · Access & Cost
You can get in the door today for free and connect your own organization at no cost beyond your Xero subscription. Costs appear only when you scale: higher call volumes, more connections, or the hands-off machine-to-machine key all move you to a paid tier.
Every check, and why it scored that way.
The same 27 checks are applied to every platform. What changes is which are N-A and what the core objects mean for that kind of software. Each mark below is quoted from the run's own report.
Category 1 · Functional Coverage
13.1 / 15Object coverage
weighted coverage ≈ 97% (33/34); no critical object absent. All core accounting objects present with role-appropriate operations; only the important "bank reconciliation" item is read-only/limited. Live reads returned Accounts (425), Contacts, Invoices (2101), BankTransactions, ManualJournals, Payments, Items, Reports. [xero_accounting.yaml; live battery]
Core operational actions
(documentation-graded) — weighted coverage ≈ 93%; no critical write workflow absent. createInvoices (PUT), createPayment (POST), updateContact (POST), createAccount (PUT) evidenced in spec; writes not live-tested (read-only connection). [xero_accounting.yaml L7605, L11964, L4499, L77]
Delete or lifecycle actions
(documentation-graded) — void/delete/reverse/archive via status changes are broadly available (Invoices Status=VOIDED/DELETED, Payments Status=DELETED, Contacts ARCHIVED, deleteAccount, deleteBankTransfers, deleteItem). [xero_accounting.yaml]
Change notification
webhooks cover only Contacts, Invoices, CreditNotes, Prepayments (+ app Subscriptions); no push for Payments, BankTransactions, Accounts, ManualJournals. Efficient incremental polling via If-Modified-Since (18 endpoints) detects the critical changes and was honored live (2000→2101 invoices, 2035→0). [xero-webhooks.yaml; xero_accounting.yaml L19841; live battery]
Category 2 · Design & Reliability
6.7 / 10Modern API conventions
resource-oriented HTTP with a versioned base URL (api.xro/2.0) and JSON (via Accept header), but non-standard verbs (PUT=create, POST=update/upsert) and XML by default. Mixed conventions. [xero_accounting.yaml; live JSON reads]
Consistent typing
legacy .NET date format /Date(1476316800000+0000)/ carried alongside ISO DateString in the same object. [xero_accounting.yaml; Xero-Java issue #171]
Structured errors
write validation returns a structured ValidationException (ErrorNumber, Type, ValidationErrors[]), but live a 404 returned plain text and a 401 returned a different JSON envelope — shapes vary across cases; no single stable machine code across all errors. [live battery; Xero-Java issue #171]
Duplicate prevention
(documentation-graded) — first-class Idempotency-Key request header (128-char) across write operations. [xero_accounting.yaml $ref idempotencyKey; xero-projects.yaml; idempotency guide]
Graceful handling under load
documented 429 + Retry-After; live responses carried X-DayLimit-Remaining, X-MinLimit-Remaining, X-AppMinLimit-Remaining. Limits: 60/min, 5000/day, 5 concurrent. [oauth2/limits; live battery]
Pagination for large collections
live Invoices?pageSize=5 returned a pagination object {page, pageSize, pageCount 421, itemCount 2101}; Contacts paged 100/page. Total-count signal present. [live battery]
Bulk or incremental export
incremental sync via If-Modified-Since works (verified live), but there is no dedicated bulk/async export path; export = paged reads filtered by modified-since. [xero_accounting.yaml; live battery]
Webhook security and delivery
(documentation-graded) — all three legs cited first-party in Xero's webhooks guide (rendered in-browser 2026-08-27): HMAC-SHA256 x-xero-signature signatures + Intent-to-Receive validation; a documented retry policy (immediate retry, then every 15 minutes for up to 24 hours, then disable + email collaborators); and consumer replay/idempotency guidance (events stored up to 31 days and replayed in order; apps must implement idempotency logic and support replayability). [developer.xero.com/documentation/guides/webhooks/overview/; xero-webhooks.yaml]
Concurrency and conflict control
no ETag/If-Match, no version field, no documented 409 conflict semantics; effectively last-write-wins via UpdatedDateUTC. [xero_accounting.yaml — absence]
Versioning and backward compatibility
version "2.0" in the path and a real deprecation process (granular-scopes migration with a Sept 2027 window; deprecation banner seen live), but the versioning contract is informal (single long-lived path version, additive-only, no version negotiation). [xero_accounting.yaml; portal Configuration banner]
Request traceability
every live response carried a Xero-Correlation-Id GUID usable with support. [live battery; xero-python issue #69]
Service availability and status transparency
status.xero.com is public with a dated incident history and scheduled maintenance, but publishes no uptime % or SLA figure. [status.xero.com]
Category 3 · Access Control
4.5 / 5Read-only credentials
read-only scopes exist and are enforced. Verified live: our read-only token returned 401 on /Journals (scope not granted) and could not write. [oauth2/scopes; live battery]
Scoped credentials
granular, per-resource scopes with read/write separation (e.g., accounting.invoices vs accounting.invoices.read). [oauth2/scopes; app Configuration scope list; live]
Multiple keys
multiple apps can be created, each with its own client_id/secret; an app supports multiple org connections. [live: My Apps, "New app"]
Rotation and revocation
self-serve secret generation ("Generate another secret", seen live), token revocation_endpoint, and DELETE /Connections to disconnect a tenant. [openid-configuration; xero-identity.yaml; live portal]
Test and production isolation
a free Demo Company exists for development (data isolated as a separate org), but there is no separate sandbox environment or separate credentials; the same app connects to demo or production. [custom-connections guide; live consent screen listed real orgs only]
Category 4 · Docs & AI-Ready
4.4 / 5Complete self-serve reference
public, example-rich reference with worked request/response examples for core endpoints (Invoices, Contacts, Payments). [developer.xero.com/documentation/api/accounting/*]
Reliable machine-consumable integration path
a maintained OpenAPI 3.0 spec (v17.0.0), six official SDKs (.NET, Java, Node/TS, PHP, Python, Ruby), and an official MCP server + agent toolkit. [github.com/XeroAPI]
AI-readable documentation
no llms.txt/llms-full.txt (both 404) and no dedicated Markdown doc corpus, but a comprehensive machine-readable OpenAPI spec (and an official MCP server) serves as an equivalent first-party AI-consumable representation. [developer.xero.com/llms.txt → 404; github.com/XeroAPI/Xero-OpenAPI]
Kept current
changelog "Last updated 14 August 2026" with dated entries, deprecation notices (granular scopes → Sept 2027), and per-SDK release notes. [developer.xero.com/changelog]
Category 5 · Access & Cost
11.3 / 15Self-serve API key
an operator signs up and creates an app and credential with no sales call or approval (verified live in My Apps). [getting-started guide; live]
Not commercially gated
a genuinely free path exists (standard app, free Starter tier, 5 connections, API included in all Xero subscriptions), so the API is not behind a premium plan; but meaningful capabilities are tier-gated: the higher rate limit (5,000 vs 1,000 calls/day/org) needs paid Core+ ($35 AUD/mo min), per-GB data-egress fees apply on paid tiers, and the machine-to-machine Custom Connections credential is a paid monthly add-on. [developer.xero.com/pricing; custom-connections guide]
What works
- A changelog kept current, with a dated deprecation window out to Sept 2027
- Granular read/write scopes, verified enforced in live testing
- Six official SDKs plus an official MCP server for AI agents
- First-class idempotency keys on writes
- A correlation id on every response that support can actually use
What to watch
- Not property management software: no properties, units, leases, or work orders
- No bank statement import or reconciliation through the API
- Webhooks cover only four record types, so you poll for the rest
- Dates come back in two different formats
- No true sandbox, only a Demo Company
The bottom line for a property manager
Xero has a strong, mature accounting API. You can build your own tools and AI agents on top of your general ledger, with good rate limits, pagination, tracing, and read-only keys you can revoke. The biggest API limits are no bank statement import or reconciliation, webhooks for only a few record types, and no lost-update protection. The biggest fit limit is that Xero is general accounting, not property management: no native properties, units, leases, or work orders, and no first-party trust or security deposit workflows. Treat Xero as an excellent accounting backend to connect to, not a replacement for a PMS, a bank, or a trust accounting system.
Check it yourself.
Both files behind this page, in full.
Xero’s full report
The complete markdown report this page is built from, including the evidence packet, the run metadata and every check in full.
Download the Xero reportThe grading file
The exact rubric behind every score on this page. Same file, every platform. Run it yourself and compare.
Download the methodologyFound a factual error in your grade?
Tell us and we will fix it. Every mark on this page traces to a specific piece of first-party evidence or a live API call, and the full report is published so you can see exactly what was checked and what it was checked against.
Confirmed factual errors are corrected immediately.
Everything else waits. We do not rescore piecemeal on request, because a board where some vendors have been re-run and others have not is not a fair comparison. Shipped improvements, changed documentation and disagreements about judgement all go into the next full rerun.
Contact us with a factual errorMethodology inspired by SaaStr’s AI Agent API Report Card. Sponsored by Column.