ml-connector
XeroGoogle Sheets

Xero and Google Sheets integration

Xero runs accounting and finance for small and medium businesses. Google Sheets is where teams build custom reporting, reconciliation, and analysis workflows. Connecting Xero to Google Sheets keeps your financial data live in a spreadsheet you control, without re-keying. New invoices, bill payments, and contact changes flow directly into your sheet, mapped to the columns that matter for your business.

How Xero works

Xero exposes invoices, bills, purchase orders, payments, contacts, accounts, tracking categories, and bank transactions through the Xero Accounting API, a REST service secured by OAuth2 Authorization Code flow. Access tokens expire in 30 minutes, and refresh tokens last 60 days with offline_access scope. Xero publishes webhooks for Contact, Invoice, CreditNote, Payment, ManualJournal, PurchaseOrder, and BankTransaction CREATE and UPDATE events, though webhook payloads contain only metadata and require a follow-up GET to fetch the full record. For polling, Xero supports the If-Modified-Since header for delta sync. All requests require the Xero-tenant-id header to specify the organization, and the API rate limits to 5 concurrent calls and 60 per minute per tenant.

How Google Sheets works

Google Sheets is a general-purpose spreadsheet platform with programmatic API v4 for reading and writing cell data. Authentication uses OAuth 2.0 Authorization Code flow (user-delegated) or Service Account (server-to-server) credentials. Because Google Sheets has no native ERP entities like invoices or vendors, you define your data schema by creating sheet tabs with custom column headers. ml-connector reads and writes values using A1 notation ranges or Named Ranges. Push notifications are available via Google Drive watch channels, but channels expire hourly and require manual re-registration, so polling every 5 to 15 minutes is recommended.

What moves between them

The main flow runs from Xero into Google Sheets. ml-connector listens for Xero webhook events on Contact, Invoice, CreditNote, and Payment, and can also poll Xero on a schedule for delta sync using the If-Modified-Since header. For each incoming record, ml-connector writes the data to the sheet tabs and columns you have defined, appending new rows or updating existing ones based on a key column you specify. The direction is primarily one-way: Xero is the source of truth for financial data, and Google Sheets is the reporting and analysis target. Reference data such as account codes, contact names, and invoice numbers map directly to the columns you have created.

How ml-connector handles it

ml-connector stores your Xero OAuth2 credentials and your Google Sheets service account or user-delegated credentials encrypted in its database. On the Xero side, it handles the 30-minute access token refresh and listens for webhook events; when a webhook arrives, ml-connector immediately fetches the full record via GET to obtain all fields, because Xero webhook payloads contain only metadata. For polling, ml-connector uses the If-Modified-Since header to retrieve only changed records and avoids redundant fetches. It respects Xero's 5-concurrent-call and 60-per-minute rate limits by queueing requests and backing off on 429 responses. On the Google Sheets side, ml-connector writes data using A1 notation ranges or Named Ranges to target the exact sheet tabs and columns you have defined. If you map an invoice to columns A through G on your Invoices tab, each new invoice from Xero is written as a row with InvoiceID, Amount, DueDate, and other fields in their corresponding columns. You specify whether to append new rows or update existing rows based on a match key such as InvoiceID. Every write carries a timestamp and audit context, so you can track which records moved and when.

A real-world example

A small accounting firm manages 20 client bookkeeping engagements using Xero. The firm's accountants need daily access to each client's recent invoices, bills, and payment activity for month-end reconciliation and client reporting. Instead of logging into each Xero account individually, the firm created a Google Sheet where each tab represents a client, with columns for Invoice Number, Amount, Due Date, and Status. ml-connector pulls invoice and bill records from each client's Xero instance every 4 hours and appends new rows to the corresponding Google Sheet tab. Accountants use Google Sheets' native tools to sort, filter, and create summary reports without re-entering data. When a payment is made in Xero, the change appears in the sheet within minutes, eliminating the manual update step and the reconciliation delays it caused.

What you can do

  • Sync Xero invoices, bills, and credit notes to Google Sheets with custom column mapping you define.
  • Write Xero payment records and contact details to Google Sheets tabs with audit timestamps on every update.
  • Listen for Xero webhook events on CREATE and UPDATE, and fetch the full record payload to ensure complete data.
  • Handle Xero's 30-minute OAuth2 token refresh and 5-concurrent-call rate limits transparently.
  • Map each Xero record type to its own Google Sheet tab so you can organize invoices, payments, and contacts separately.

Questions

Does ml-connector support bidirectional sync from Google Sheets back to Xero?
No. ml-connector pulls data from Xero into Google Sheets, but does not write changes from the sheet back into Xero. Xero is treated as the source of truth for financial data, and Google Sheets is used for reporting and analysis. If you need to update Xero records, you make those changes in Xero itself.
How does ml-connector handle Xero's webhook payloads, which contain only metadata?
When a Xero webhook event arrives (for example, an Invoice CREATE event), the webhook payload contains only the resource ID and event metadata. ml-connector immediately makes a follow-up GET request to the Xero Accounting API to fetch the full Invoice record with all fields, then writes the complete data to your Google Sheet. This ensures you see all the details you need.
What happens if I change my Google Sheet column headers or add new tabs?
You can modify your Google Sheet schema at any time. ml-connector uses the column headers and tab names you have defined in your configuration to map Xero fields to the correct cells. If you rename a column or add a new tab, update your ml-connector configuration to match, and future records will write to the new locations. Existing rows in the sheet are not affected.

Related integrations

Connect Xero and Google Sheets

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started