Everything an AI agent can do with the Xero API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints33
API version2.0
Last updated23 June 2026
Orientation

How the Xero API works.

The Xero API is how an app or AI agent works with a Xero organisation: raising an invoice, recording a payment, adding a contact, reconciling a bank transaction, or pulling a Profit and Loss report. Access is granted through an OAuth 2.0 access token and a set of scopes, like accounting.transactions or accounting.contacts, that decide which areas a call can read or write, and each request names the one organisation it acts on. Xero can also push an event when an invoice, contact, or credit note is created or updated, so an integration learns about changes without polling.

33Endpoints
8Capability groups
17Read
16Write
4Permissions
Authentication
Xero uses OAuth 2.0. An app gets an access token through the authorization-code flow (a user signs in and consents), through PKCE for apps with no server secret, or through a Custom Connection for a single organisation with no user login. The access token is a Bearer token that lasts 30 minutes, and the offline_access scope is needed to receive a refresh token. Every call also sends a Xero-tenant-id header naming which connected organisation it acts on.
Permissions
Access is governed by OAuth scopes. The Accounting API groups them by area: accounting.transactions covers invoices, bills, payments, bank transactions, and credit notes; accounting.contacts covers customers and suppliers; accounting.settings covers the chart of accounts and items; and accounting.reports.read covers reports. Each has a .read variant for read-only access, so an agent that only reads invoices can hold accounting.transactions.read. From March 2026 Xero added finer per-resource scopes, and apps created on or after 2 March 2026 must use the granular scopes; older apps have until September 2027 to migrate.
Versioning
The Accounting API is pinned at version 2.0 in the request path, so the path does not change as features are added. Changes ship through dated release notes and the developer changelog rather than a new path version, including additive fields and scope deprecations. The biggest recent change is the move to granular OAuth scopes.
Data model
The Accounting API is resource-oriented and reached at https://api.xero.com/api.xro/2.0, scoped to one organisation by the Xero-tenant-id header. A GET reads, a PUT creates new records, and a POST creates or updates records, so the same collection endpoint both inserts and edits. Resources include Invoices, Contacts, Accounts, Payments, BankTransactions, Items, CreditNotes, and read-only Reports. A change to an invoice, contact, or credit note can be pushed to a registered webhook.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Xero determines what it can reach. There is a main API for reading and writing accounting data, a hosted server that exposes Xero tools to agents, and a route for receiving events, and each is governed by the access token behind it and the permissions that token carries.

Ways to connect

Accounting API

The Accounting API answers at https://api.xero.com/api.xro/2.0 and works with JSON or XML. A call carries an OAuth 2.0 access token and a Xero-tenant-id header that names which connected organisation it acts on. A GET reads, a PUT creates new records, and a POST creates or updates records.

Best forConnecting an app or AI agent to Xero.
Governed byThe access token and the scopes it carries, scoped to one organisation by Xero-tenant-id.
Docs ↗

MCP server (Model Context Protocol)

Xero publishes a first-party Model Context Protocol server, @xeroapi/xero-mcp-server, run locally through npx. It exposes tools such as list-contacts, list-invoices, list-accounts, list-payments, create-invoice, create-contact, and create-payment. It authenticates either with a Custom Connection (a client id and secret tied to one organisation) or with a bearer token supplied at runtime.

Best forConnecting an AI agent to Xero through MCP.
Governed byThe Custom Connection credentials or bearer token and the scopes they carry.
Docs ↗

Webhooks

Xero POSTs a small JSON payload to a registered HTTPS endpoint when invoices, contacts, or credit notes are created or updated. The payload names the resource and event, and the receiver re-fetches full detail from the API. Each delivery carries an x-xero-signature header, an HMAC-SHA256 hash of the body keyed with the webhook signing key, which the receiver verifies. A new endpoint must first pass an 'intent to receive' validation.

Best forReceiving Xero change events at an app or AI agent.
Governed byThe webhook signing key behind the x-xero-signature header.
Docs ↗
Authentication

OAuth 2.0 authorization code

The standard authorization-code flow has a user sign in to Xero and consent to the requested scopes, after which the app exchanges a code for an access token and a refresh token. The access token lasts 30 minutes; the offline_access scope is needed to receive a refresh token and keep the connection alive. The token can act on every organisation the user connected, each named by the Xero-tenant-id header.

TokenOAuth 2.0 access token (Bearer), with a refresh token
Best forApps a user installs across one or more organisations.
Docs ↗

Custom Connection

A Custom Connection uses the OAuth 2.0 client-credentials flow to connect a single organisation with no user sign-in, which suits a private machine-to-machine integration. It is tied to one organisation chosen when the connection is set up, and its scopes are fixed in the app settings.

TokenOAuth 2.0 access token (Bearer) via client credentials
Best forA private integration to one organisation, with no interactive login.
Docs ↗

OAuth 2.0 with PKCE

The authorization-code flow with PKCE (Proof Key for Code Exchange) suits a mobile or single-page app that cannot keep a client secret. It adds a one-time code challenge and verifier so the code exchange is safe without a stored secret.

TokenOAuth 2.0 access token (Bearer), with a refresh token
Best forMobile and single-page apps with no server-side secret.
Docs ↗
Capability map

What an AI agent can do in Xero.

The Xero Accounting API is split into areas an agent can act on, such as invoices, contacts, payments, bank transactions, and reports. Each area has its own methods, and writes in some areas record money owed, money received, or changes to the chart of accounts.

Endpoint reference

Every Xero Accounting API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Invoices

List, read, create, and update sales invoices and purchase bills.4

Read-only access can use accounting.transactions.read instead of the read-write accounting.transactions.

Acts oninvoice
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventinvoice
Rate limitStandard limits apply

Read-only access can use accounting.transactions.read.

Acts oninvoice
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new records only; the read-only accounting.transactions.read scope cannot call it.

Acts oninvoice
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventinvoice
Rate limitStandard limits apply

A POST to the collection updates or creates; matching is by InvoiceID or InvoiceNumber.

Acts oninvoice
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventinvoice
Rate limitStandard limits apply

Contacts

List, read, create, and update the customers and suppliers in an organisation.4

Read-only access can use accounting.contacts.read.

Acts oncontact
Permission (capability)accounting.contacts
VersionAvailable since the API’s base version
Webhook eventcontact
Rate limitStandard limits apply

Read-only access can use accounting.contacts.read.

Acts oncontact
Permission (capability)accounting.contacts
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new contacts only.

Acts oncontact
Permission (capability)accounting.contacts
VersionAvailable since the API’s base version
Webhook eventcontact
Rate limitStandard limits apply

A POST to the collection updates or creates; matching is by ContactID or Name.

Acts oncontact
Permission (capability)accounting.contacts
VersionAvailable since the API’s base version
Webhook eventcontact
Rate limitStandard limits apply

Accounts (chart of accounts)

List, read, create, update, and delete the accounts that make up the chart of accounts.5

Read-only access can use accounting.settings.read.

Acts onaccount
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only access can use accounting.settings.read.

Acts onaccount
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Chart-of-accounts changes need the read-write accounting.settings scope.

Acts onaccount
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs the read-write accounting.settings scope.

Acts onaccount
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Only accounts with no transactions can be deleted; needs accounting.settings.

Acts onaccount
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Payments

List and read payments against invoices and credit notes, create a payment, and delete one.4

Read-only access can use accounting.transactions.read.

Acts onpayment
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only access can use accounting.transactions.read.

Acts onpayment
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new payments; needs the read-write accounting.transactions scope.

Acts onpayment
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Xero deletes a payment through a POST that sets Status to DELETED; needs accounting.transactions.

Acts onpayment
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Bank transactions

List, read, create, and update spent and received money transactions.4

Read-only access can use accounting.transactions.read.

Acts onbank transaction
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only access can use accounting.transactions.read.

Acts onbank transaction
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new transactions; needs the read-write accounting.transactions scope.

Acts onbank transaction
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A POST to the collection updates or creates; matching is by BankTransactionID.

Acts onbank transaction
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Items

List, read, create, update, and delete the inventory and service items in an organisation.4

Read-only access can use accounting.settings.read.

Acts onitem
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new items; needs the read-write accounting.settings scope.

Acts onitem
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs the read-write accounting.settings scope.

Acts onitem
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs the read-write accounting.settings scope.

Acts onitem
Permission (capability)accounting.settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Credit notes

List, read, create, and update credit notes.4

Read-only access can use accounting.transactions.read.

Acts oncredit note
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventcreditnote
Rate limitStandard limits apply

Read-only access can use accounting.transactions.read.

Acts oncredit note
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A PUT creates new credit notes; needs the read-write accounting.transactions scope.

Acts oncredit note
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventcreditnote
Rate limitStandard limits apply

A POST to the collection updates or creates; matching is by CreditNoteID.

Acts oncredit note
Permission (capability)accounting.transactions
VersionAvailable since the API’s base version
Webhook eventcreditnote
Rate limitStandard limits apply

Reports

Read accounting reports such as Profit and Loss, Balance Sheet, Trial Balance, and aged receivables and payables.4

All report endpoints are read-only and need accounting.reports.read.

Acts onreport
Permission (capability)accounting.reports.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only; needs accounting.reports.read.

Acts onreport
Permission (capability)accounting.reports.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only; needs accounting.reports.read.

Acts onreport
Permission (capability)accounting.reports.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires a contactID parameter. Read-only; needs accounting.reports.read.

Acts onreport
Permission (capability)accounting.reports.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Xero can notify an app or AI agent when something changes in an organisation, like an invoice or a contact being created or updated. It posts a small payload naming what changed, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
INVOICE (CREATE / UPDATE)Fires when a sales invoice or purchase bill is created or updated. The payload names the resource and event, and the receiver re-fetches the invoice from the API./Invoices
/Invoices
/Invoices
CONTACT (CREATE / UPDATE)Fires when a contact is created or updated. The payload names the resource and event, and the receiver re-fetches the contact from the API./Contacts
/Contacts
/Contacts
CREDITNOTE (CREATE / UPDATE)Fires when a credit note is created or updated. Credit note events are generally available and have their own payload schema./CreditNotes
/CreditNotes
/CreditNotes
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Xero limits how fast and how much an app or AI agent can call, through a per-minute and per-day quota counted separately for each connected organisation, plus a separate app-wide minute quota and a cap on how many requests run at once.

Request rate

Xero counts calls against three limits at once. Each connected organisation may make 60 calls per minute and 5,000 calls per day, and across all the organisations connected to one app there is a 10,000-calls-per-minute app-wide limit. A separate concurrency limit caps an app at 5 requests running at once against a single organisation. Every response carries X-MinLimit-Remaining, X-DayLimit-Remaining, and X-AppMinLimit-Remaining headers reporting what is left against each. Going over returns HTTP 429 with an X-Rate-Limit-Problem header naming which limit was hit and a Retry-After header giving the seconds to wait.

Pagination

List endpoints page through results with a page query parameter, returning up to 100 records per page, so an integration increments page until a short page comes back. Many endpoints also accept a modifiedAfter parameter (sent as the If-Modified-Since header) to fetch only records changed since a given time, which keeps a sync within the daily limit.

Request size

A page returns at most 100 records. The minute and daily counts reset on rolling windows per organisation, and the access token from an authorization-code flow lasts 30 minutes before it must be refreshed.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400ValidationException / Bad RequestThe request failed validation. The body holds an ApiException element with an ErrorNumber, a Type such as ValidationException, and per-element error messages.Read the validation messages, correct the named fields, and resend. The request is not retryable as-is.
401UnauthorizedThe access token is missing, expired, or revoked, often because a user disconnected the app from inside Xero.Refresh the token, or send the user back through authorization to reconnect.
403ForbiddenThe token is valid but the requested scope is missing, or the connection is not permitted to reach the resource.Add the missing scope to the connection and reauthorize, then retry.
404Not FoundThe resource does not exist, or it is not visible to the connected organisation named by Xero-tenant-id.Verify the resource Id and that the call targets the correct organisation.
429Too Many RequestsA rate limit was exceeded. The X-Rate-Limit-Problem header names which limit was hit (minute, daily, or app-wide minute), and a Retry-After header gives the seconds to wait.Wait the number of seconds in Retry-After, then retry, and smooth the request rate to stay under the per-minute limit.
500Internal Server ErrorAn error on Xero's side. It is rare and not caused by the request.Retry with backoff, and contact Xero support if it persists.
503Service UnavailableEither the specific organisation is temporarily offline, or a rate limit returned 503 on older endpoints. An offline organisation can last several minutes while the API itself stays up.Wait and retry after about five minutes for an offline organisation, or honour the Retry-After header for a rate limit.
Versioning & freshness

Version history.

Xero pins the Accounting API at version 2.0 in the request path and ships changes through dated release notes and a changelog rather than minting a new path version.

Version history

What changed, and when

Latest version2.0
2.0Current version
Accounting API version 2.0 (current)

The Accounting API is pinned at 2.0 in the request path at https://api.xero.com/api.xro/2.0. The path version is stable, so it does not change as features are added; changes ship through dated release notes and the developer changelog rather than a new path version. The two changes below are the most notable recent ones.

What changed
  • The path version has stayed at 2.0; additive fields and new resources are published in the release notes, not as a new version.
  • The big recent shifts are the granular OAuth scopes and credit note webhooks, dated below.
2026-03-04Feature update
Credit note webhooks reach general availability

Credit note webhook events became generally available on 4 March 2026, the first new event on Xero's Horizon eventing platform. An app can now receive a notification when a credit note is created or updated, rather than polling, alongside the existing invoice and contact events.

What changed
  • CREDITNOTE create and update events added to webhooks, with their own payload schema.
  • No breaking change for apps already subscribed to invoice and contact events.
2026-03-02Feature update
Granular OAuth scopes introduced

Xero replaced the two broad accounting scopes with a set of finer per-resource scopes, so an app can request access to just invoices, just bank transactions, or a single report rather than a whole area. Apps created on or after 2 March 2026 can only use the granular scopes; apps created before that date keep the broad scopes until September 2027, when they must have migrated.

What changed
  • accounting.transactions split into per-resource scopes such as invoices, bank transactions, and manual journals.
  • accounting.reports split so each report has its own scope.
  • Existing apps gain the granular scopes and have until September 2027 to migrate off the broad scopes.

The 2.0 path version is stable; track the changelog for additive changes and scope deprecations.

Xero developer changelog ↗
Questions

Xero API, answered.

Which OAuth scopes does the Accounting API use?+
Scopes are grouped by area. accounting.transactions covers invoices, bills, payments, bank transactions, and credit notes; accounting.contacts covers contacts; accounting.settings covers the chart of accounts and items; and accounting.reports.read covers reports. Each has a .read variant for read-only access. The offline_access scope is also needed to receive a refresh token, and openid, profile, and email return identity details about the user who connected.
What changed with granular scopes in 2026?+
Xero replaced the two broad accounting scopes with a set of finer per-resource scopes, so an app can request access to just invoices or just one report rather than a whole area. Apps created on or after 2 March 2026 can only use the granular scopes from day one. Apps created before that date keep the broad scopes until September 2027, when they must have migrated.
How do create and update work, and what's the difference between PUT and POST?+
A GET reads. A PUT to a collection like /Invoices creates new records only. A POST to the same collection creates or updates, matching existing records by their Id (or by a natural key such as InvoiceNumber or contact Name) and inserting the rest. So a sync that should never edit existing data uses PUT, and an upsert uses POST.
What are the rate limits, and what happens when I hit one?+
Each connected organisation allows 60 calls per minute and 5,000 per day, there is a 10,000-per-minute app-wide limit across all organisations, and at most 5 requests can run at once against one organisation. Every response reports what is left through X-MinLimit-Remaining, X-DayLimit-Remaining, and X-AppMinLimit-Remaining. Going over returns HTTP 429 with X-Rate-Limit-Problem naming the limit and Retry-After giving the seconds to wait.
How do I get notified of changes instead of polling?+
Webhooks deliver change events for invoices, contacts, and credit notes. A receiver URL is registered on the app, and Xero POSTs a small payload naming the resource and whether it was created or updated, after which the integration re-fetches full detail from the API. Each delivery carries an x-xero-signature HMAC-SHA256 header, checked against the webhook signing key, and a new endpoint must first pass an 'intent to receive' validation.
How does the API know which organisation to act on?+
A single access token can be connected to several Xero organisations, so each request sends a Xero-tenant-id header naming which one to act on. The set of connected organisations is read from the connections endpoint after authorization. A Custom Connection is tied to a single organisation, so its tenant is fixed.
Does Xero have an official MCP server for AI agents?+
Yes. Xero publishes a first-party Model Context Protocol server, @xeroapi/xero-mcp-server, run locally through npx. It exposes tools for listing and creating contacts, invoices, accounts, and payments, among others, and authenticates either with a Custom Connection or with a bearer token supplied at runtime. The scopes the connection holds still govern what the agent can do.
Related

More finance API guides for agents

What is Bollard AI?

Control what every AI agent can do in Xero.

Bollard AI sits between a team's AI agents and Xero. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared Xero connection.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Xero
Bookkeeping Agent
Read invoices ResourceOffReadFull use
Create payments ActionOffReadFull use
Contacts ResourceOffReadFull use
Per-agent access, set in Bollard AI, not in Xero