Skip to content

Xero Accounting

Overview

The Xero Accounting task integrates BaseCloud CRM with Xero (cloud accounting platform), enabling OAuth-authenticated contact and invoice management across multiple organizations with automatic token refresh.

Key Features:

  • 8 Actions: create, update, get and list contacts and invoices
  • Multi-Tenant Support: Manage multiple Xero organizations
  • Auto Token Refresh: Automatic OAuth token renewal
  • Tracking Categories: Two-level project/department tracking
  • Contact Auto-Create: Automatic contact creation in invoices
  • Global Coverage: 180+ countries, 160+ currencies
  • Pagination: Handle large datasets efficiently
  • Advanced Filtering: OData-style where clauses

Use Cases:

  • Multi-organization invoicing from single CRM
  • Automated contact synchronization
  • Project-based billing with tracking
  • Invoice status monitoring and reconciliation
  • Bulk reads that fetch every page automatically

Prerequisites

1. Xero Account

An active Xero subscription, and a Xero user who may manage contacts and invoices in the organisation(s) to use. No Xero developer app is needed — BaseCloud connects with its own.

2. BaseCloud App Connection

  1. Go to Settings → App Connections and add a Xero connection
  2. Sign in to Xero and allow access
  3. On the task, pick the connection, then the Organisation (Tenant) it works in

One connection can reach every organisation the Xero user allowed; each task works in the one it names. BaseCloud renews the connection's access with Xero by itself.

3. Tracking Categories (Optional)

Xero Tracking Setup:

  1. Log into Xero Settings Tracking Categories
  2. Create categories (e.g., "Department", "Project")
  3. Add options (e.g., Department: Sales, Marketing, Support)
  4. Note exact option names for use in invoices

Settings → Tracking Categories: Department with the options Electrical, Heating & Cooling and Plumbing, and Region with South Side, Downtown and North Side, each with Add Option; a note that the maximum of 2 tracking categories is reached

Two categories maximum, because that is Xero's limit — but each can hold any number of options. Categories group invoice line items for reporting and reconciliation, so the names here are what a task writes into when it sets a tracking value.

Outputs

Reference fields as {{task_<ID>_<field>}}.

Field Type Notes
xero string Xero's response — contact or invoice data, depending on the action. Present only on some actions.

Always emitted

Field Type Notes
run boolean Whether the task succeeded.
run_text string What happened, including the reason on failure.

Fields marked as action-dependent may be absent

This task does several different things depending on its action setting, and only the fields relevant to that action are emitted. Check a real run in the OUTPUT panel before referencing one downstream.

Configuration

Builder fields

The Field column is the label as it appears in the task builder; Key is the name the value is stored under and referenced by.

Field Key Type Default Notes
Xero Account app_connection_id app-connection –
Organisation (Tenant) tenant_id select –
Action xero_action select – Options: Create Contact · Update Contact · Get Contact · Get Contacts · Create Invoice · Update Invoice · Get Invoice · Get Invoices
Contact ID Contact ID text – Only shown when xero_action is update_contact, get_contact
Contact Name Contact Name text – Only shown when xero_action is create_contact, update_contact, get_contact, create_invoice
Account Number Account Number text – Only shown when xero_action is create_contact, update_contact, get_contact
First Name First Name text – Only shown when xero_action is create_contact, update_contact
Last Name Last Name text – Only shown when xero_action is create_contact, update_contact
Email Address Email Address text – Only shown when xero_action is create_contact, update_contact
Tax Number Tax Number text – Only shown when xero_action is create_contact, update_contact
Bank Account Details Bank Account Details text – Only shown when xero_action is create_contact, update_contact
Where Filter Where Filter text – Only shown when xero_action is get_contacts
Where Filter Where Filter text – Only shown when xero_action is get_invoices
Order By Order By select – Options: Default order · Name (A to Z) · Name (Z to A) · Recently updated first · Oldest updated first · Email address · Account number. Only shown when xero_action is get_contacts
Order By Order By select – Options: Default order · Newest invoice date first · Oldest invoice date first · Due soonest first · Due latest first · Invoice number · Highest total first · Highest amount due first · Recently updated first. Only shown when xero_action is get_invoices
Include Archived Include Archived select false Options: No · Yes. Only shown when xero_action is get_contacts
Invoice ID Invoice ID text – Only shown when xero_action is update_invoice, get_invoice
Invoice Number Invoice Number text – Only shown when xero_action is create_invoice, get_invoice
Invoice Date Date text – Only shown when xero_action is create_invoice, update_invoice
Due Date Due Date text – Only shown when xero_action is create_invoice, update_invoice
Reference Reference text – Only shown when xero_action is create_invoice, update_invoice
Status Status select – Options: Draft · Submitted · Authorised · Voided. Only shown when xero_action is create_invoice, update_invoice
Statuses Filter Statuses select – Options: Draft · Submitted · Authorised · Paid · Voided · Deleted. Only shown when xero_action is get_invoices
Contact IDs Filter Contact IDs text – Only shown when xero_action is get_invoices
Tax Type line_items_tax_type select – Options: Exclusive · Inclusive · No Tax. Only shown when xero_action is create_invoice, update_invoice
Item Code(s) Item Code text – Only shown when xero_action is create_invoice, update_invoice
Description(s) Description text – Only shown when xero_action is create_invoice, update_invoice
Quantity(ies) Quantity text – Only shown when xero_action is create_invoice, update_invoice
Unit Price(s) Unit Price text – Only shown when xero_action is create_invoice, update_invoice
Discount %(s) Discount % text – Only shown when xero_action is create_invoice, update_invoice
Account Code(s) Account Code text – Only shown when xero_action is create_invoice, update_invoice
Tracking Category 1 Tracking Category 1 Value text – Only shown when xero_action is create_invoice, update_invoice
Tracking Category 2 Tracking Category 2 Value text – Only shown when xero_action is create_invoice, update_invoice

Actions

Every action uses the Xero Account and Organisation (Tenant) chosen above. The settings each action reads are the ones the builder shows for it; anything else is ignored. A task with no account, no organisation or no action fails at once, and so does an action missing a setting it requires.

What the action returns is the xero output. Its fields are referenced with an underscore, for example {{task_<ID>_xero_contact_id}} for the contact_id inside xero.

Create Contact

Creates a contact. Contact Name is required; Account Number, First Name, Last Name, Email Address, Tax Number and Bank Account Details are optional.

If Xero already has a contact with that name or account number, the task does not fail: it returns the existing contact, and its message says so. It never updates that contact — use Update Contact for that.

xero holds status, contact_id, contact_name, account_number, first_name, last_name, email_address and message.

Update Contact

Updates the contact given by Contact ID (required, Xero's contact ID). Only the fields that hold a value are sent, so an empty field is left as it is in Xero, not cleared.

Get Contact

Finds one contact by Contact ID, Account Number or Contact Name (an exact name match) — one of them is required. xero.contact is Xero's contact record. Finding none is not a failure: the task completes with "No contact found." and found false.

Get Contacts

Lists contacts, reading every page Xero returns. Where Filter takes a Xero where clause (for example Name.Contains("Acme")), Order By a sort from the list, and Include Archived whether archived contacts are included. xero.contacts is the list and xero.pagination says how many were read and whether the list was cut short because it was too large to keep in full.

Create Invoice

Creates an invoice for Contact Name. The contact is found by name, or created if Xero has none. Required: Contact Name, Invoice Date and Due Date (both DD/MM/YYYY HH:mm), Status (Draft, Submitted, Authorised or Voided) and Tax Type (Exclusive, Inclusive or No Tax). Invoice Number and Reference are optional; an Invoice Number Xero already has fails the task.

Line items are written as lists separated by |, one entry per line: Item Code(s), Description(s), Quantity(ies), Unit Price(s), and optionally Discount %(s), Account Code(s) and the two Tracking Category values. The number of descriptions decides the number of lines, so keep every list the same length. A tracking value must be an option of that Xero tracking category.

Xero has one description per line. To send the details shown under an item in BaseCloud as well, map item_description_with_details into Description(s) instead of item_description: it carries each description with its details on the lines below it.

xero holds status, message, invoice_id, invoice_number, invoice_status, invoice_total, invoice_sub_total, invoice_total_tax, invoice_total_discount and contact_id.

Get Invoice

Finds one invoice by Invoice ID or Invoice Number — one is required. xero.invoice is Xero's invoice record.

Get Invoices

Lists invoices, reading every page. Where Filter takes a Xero where clause, Order By a sort from the list, Statuses Filter limits it to some statuses, and Contact IDs Filter (Xero contact IDs, comma-separated) to some contacts. xero.invoices is the list and xero.pagination as for Get Contacts.

Update Invoice

Updates the invoice given by Invoice ID (required): any of Reference, Status, Invoice Date and Due Date that hold a value, and — when line items are given — its lines, in the same | format as Create Invoice. Given lines replace the invoice's lines; they are not added to them. Xero decides which changes an invoice's status allows (a paid invoice, for example, cannot be edited).


Real-World Examples

Create a Xero invoice from a won deal

CRM Trigger  (status changed to "Won")
  └─ Match to Client   look the client up
      └─ Xero          create the invoice

Keep a Xero contact in step with the CRM

CRM Trigger  (contact updated)
  └─ Match to Client   look the client up
      └─ Xero          update the contact

Store the Xero contact ID on the client record so the update targets the right contact rather than creating a duplicate.

Confirm to the customer once the invoice exists

Webhook In
  └─ Xero    create the invoice
      └─ Email   send confirmation, referencing {{task_31001_xero}}

Troubleshooting

Connection expired

Cause: Xero no longer accepts the connection — it was revoked, or its tokens lapsed.

Solution: BaseCloud refreshes tokens on its own; when that is no longer possible, reconnect Xero in App Connections.

Create Contact returned a contact that already existed

Cause: Xero already had a contact with that name or account number.

Solution: This is expected — the task returns the existing contact (its message says so) and does not change it. Use {{task_31001_xero_contact_id}} either way, and Update Contact to change it.

Tracking Category Not Found

Cause: A tracking value must match one of the category's options exactly (case included). A value that matches none is left off the line silently — the invoice is still created, untracked.

Solutions:

  1. Copy the option name exactly as Xero shows it
  2. Leave a line's value empty (or null) to leave that line untracked on purpose

Invoice Number Already Exists

Cause: Xero already has an invoice with that number; the task fails with "Invoice number … already exists."

Solutions:

  1. Leave Invoice Number empty to let Xero number it
  2. Or check first with Get Invoice by that number

Line Items Calculation Wrong

Cause: Tax type mismatch with line_items_tax_type

Solutions:

  • Exclusive: Unit prices don't include tax tax added on top
  • Inclusive: Unit prices include tax tax extracted from price
  • Verify which format your prices use

Not All Records Returned

Cause: Get Contacts and Get Invoices read every page, but stop at about 12 MB of results so the output can still be saved. {{task_31001_xero_pagination.truncated}} is true when that happens.

Solution: Narrow the list with a Where Filter, Statuses or Contact IDs.

Wrong organisation

Cause: The task's Organisation (Tenant) is not the Xero organisation you meant — one Xero account can hold several.

Solution: Pick the organisation in the task; the list shows every organisation the connected Xero account can reach. Use a separate task (or connection) per organisation.


Best Practices

OAuth Management

  1. Tokens: BaseCloud keeps and refreshes the connection's tokens itself
  2. Reconnection: if Xero ends the connection (revoked, or unused for too long), reconnect it in App Connections

Contact Management

  1. Auto-Create in Invoices: create_invoice auto-creates missing contacts
  2. Unique Account Numbers: Use CRM client IDs: C{{client_id}}
  3. Sync Strategy: Decide on sync direction (CRMXero, XeroCRM, bi-directional)
  4. Duplicate Prevention: Use get_contact before create_contact

Invoice Creation

  1. Status Workflow:
  2. DRAFT: For review/approval workflows
  3. AUTHORISED: For immediate dispatch
  4. Never set to PAID manually (Xero manages)

  5. Tracking Categories:

  6. Always use both levels for detailed reporting
  7. Standardize category values across CRM
  8. Validate values exist before invoice creation

  9. Line Items:

  10. Use meaningful item codes
  11. Consistent account codes (200=Sales, 400=Sales Discounts)
  12. Calculate totals in CRM for validation

Performance

  1. Pagination: Automatic for get_contacts and get_invoices — every page is read
  2. Filters: Use where clauses to reduce data transfer
  3. Caching: Cache tenant IDs and tracking categories
  4. Rate Limits: Xero has rate limits - add delays in bulk operations

Error Handling

  1. Why it failed: {{task_31001_run_text}} carries Xero's message
  2. Retries: a Xero rate limit is retried later on its own; a missing or wrong setting fails at once, as retrying cannot fix it

FAQ

Q: Can I use Xero with multiple organizations simultaneously?

A: Yes — each task picks its organisation in Organisation (Tenant).

Q: How do I get my tenant ID?

A: You don't need it: the task's Organisation (Tenant) list shows the organisations by name once the Xero account is connected.

Q: Can I update invoice line items after creation?

A: Yes, with update_invoice. Note: Replaces all existing line items (not additive).

Q: What happens if I create invoice with existing invoice number?

A: The task fails, saying the number already exists. Leave Invoice Number blank to let Xero number it.

Q: How do I handle refunds or credit notes?

A: Create separate credit note in Xero (not currently supported via task). Use Xero UI or request feature addition.

Q: Can I attach files to invoices?

A: Not via task action. Use Xero API directly or Xero UI for attachments.

Q: How long do access tokens last?

A: Access tokens: 30 minutes, Refresh tokens: 90 days. Auto-refresh handled by task.

Q: Can I get invoice PDFs?

A: Not directly. Xero generates PDFs separately. Use Xero API or UI to download.

Q: What's the rate limit?

A: Xero: 60 requests per minute per tenant. Add delays in bulk operations.

Q: How do I query tracking category reports?

A: Use get_invoices with where filter or query Xero Reports API separately.

Q: Can I create quotes instead of invoices?

A: Xero separates quotes from invoices. This task handles invoices only.

Q: How do I handle multiple currencies?

A: Xero supports 160+ currencies per contact. Specify currency when creating invoices.

Q: Can I mark invoices as paid from CRM?

A: No - Xero manages payment status based on payment entry. Use Xero UI or payment API.

Q: What if contact auto-create fails?

A: Task returns error. Create contact manually first with create_contact action.



Technical Details

  • Type ID: 31
  • Function: taskXero() in automationService.js
  • Service: xeroService.js
  • Library: xero-node (XeroClient)
  • Authentication: OAuth 2.0 with auto token refresh
  • Outputs: {{task_<ID>_xero_<field>}}, the ID being the task's own
  • Pagination: Automatic, 1,000 results per request
  • Rate limits: a rate-limited call is retried later on its own