Integrations / Xero
Xero
Xero accounting: list connected organisations, invoices, contacts, accounts, bank transactions and payments; create invoices and contacts.
10 actions
OAuth 2
8 read2 write
Calls api.xero.com
Connect
const conn = await setu.connections.initiate({ userId: "user_1", toolkit: "xero" });
console.log(conn.connectUrl); // show this to your user
await conn.waitUntilActive();Permissions requested
| Scope | Why it is requested |
|---|---|
offline_access | Stay connected without asking you to sign in again (refresh tokens) |
openid | Identify which Xero user connected |
profile | Read the connected user's name |
email | Read the connected user's email address to label the connection |
accounting.invoices | Read and create invoices, credit notes and quotes |
accounting.contacts | Read and create contacts (customers and suppliers) |
accounting.settings.read | Read the organisation details and chart of accounts |
accounting.banktransactions.read | Read bank transactions |
accounting.payments.read | Read payments |
Actions
Create contactwritexero.create_contactCreate a contact (customer or supplier) in Xero with a name and optional email and phone. The name must be unique in the organisation.
Needs scope: accounting.contacts
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
name | string | Required | Full name or organisation name, unique |
first_name | string | Optional | First name |
last_name | string | Optional | Last name |
email | string | Optional | Email address |
await setu.execute({
userId: "user_1",
action: "xero.create_contact",
input: {
"tenant_id": "<tenant_id>",
"name": "<name>"
},
});Create invoicewritexero.create_invoiceCreate an invoice (ACCREC sales invoice or ACCPAY bill) in Xero for a contact, with line items. It is created as DRAFT unless status says otherwise.
Needs scope: accounting.invoices
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
type | string | Required | ACCREC is a sales invoice, ACCPAY a bill |
contact_id | string | Required | Contact id (GUID) |
line_items | array of object | Required | Lines with Description, Quantity, UnitAmount and AccountCode |
date | string | Optional | Invoice date, YYYY-MM-DD |
due_date | string | Optional | Due date, YYYY-MM-DD |
reference | string | Optional | Reference text |
status | string | Optional | Defaults to DRAFT |
await setu.execute({
userId: "user_1",
action: "xero.create_invoice",
input: {
"tenant_id": "<tenant_id>",
"type": "<type>",
"contact_id": "<contact_id>",
"line_items": []
},
});Get invoicereadxero.get_invoiceGet one Xero invoice by its invoice id or invoice number, with status, contact, totals and amount due.
Needs scope: accounting.invoices
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
invoice_id | string | Required | Invoice id (GUID) or invoice number |
await setu.execute({
userId: "user_1",
action: "xero.get_invoice",
input: {
"tenant_id": "<tenant_id>",
"invoice_id": "<invoice_id>"
},
});Get organisationreadxero.get_organisationGet the details of a Xero organisation: name, legal name, base currency, country, financial year end and organisation type.
Needs scope: accounting.settings.read
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
await setu.execute({
userId: "user_1",
action: "xero.get_organisation",
input: {
"tenant_id": "<tenant_id>"
},
});List accountsreadxero.list_accountsList the chart of accounts of a Xero organisation: account codes, names, types and status. Needed to pick an AccountCode for invoice lines.
Needs scope: accounting.settings.read
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
where | string | Optional | Xero filter, e.g. Type=="REVENUE" |
order | string | Optional | Sort, e.g. Name |
await setu.execute({
userId: "user_1",
action: "xero.list_accounts",
input: {
"tenant_id": "<tenant_id>"
},
});List bank transactionsreadxero.list_bank_transactionsList spend and receive money bank transactions in a Xero organisation, optionally filtered with a where expression. Returns 100 per page.
Needs scope: accounting.banktransactions.read
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
where | string | Optional | Xero filter, e.g. Status=="AUTHORISED" |
order | string | Optional | Sort, e.g. Date DESC |
page | integer | Optional | Page number, starting at 1 |
await setu.execute({
userId: "user_1",
action: "xero.list_bank_transactions",
input: {
"tenant_id": "<tenant_id>"
},
});List connected organisationsreadxero.list_connectionsList the Xero organisations this connection can access, with their tenant ids. Call this first: every other Xero action needs a tenant_id from here.
No input.
await setu.execute({
userId: "user_1",
action: "xero.list_connections",
input: {},
});List contactsreadxero.list_contactsList or search contacts (customers and suppliers) in a Xero organisation by name, email or account number with search_term, or with a where expression.
Needs scope: accounting.contacts
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
search_term | string | Optional | Matches name, first or last name, email, account number |
where | string | Optional | Xero filter, e.g. ContactStatus=="ACTIVE" |
page | integer | Optional | Page number, starting at 1 |
await setu.execute({
userId: "user_1",
action: "xero.list_contacts",
input: {
"tenant_id": "<tenant_id>"
},
});List invoicesreadxero.list_invoicesList invoices (sales and bills) in a Xero organisation. Filter by status or contact, or with a where expression like Type=="ACCREC"; returns 100 per page.
Needs scope: accounting.invoices
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
where | string | Optional | Xero filter, e.g. Type=="ACCREC" AND AmountDue>0 |
order | string | Optional | Sort, e.g. Date DESC |
statuses | array of string | Optional | DRAFT, SUBMITTED, AUTHORISED, PAID, VOIDED |
contact_ids | array of string | Optional | Only invoices for these contact ids |
page | integer | Optional | Page number, starting at 1 |
await setu.execute({
userId: "user_1",
action: "xero.list_invoices",
input: {
"tenant_id": "<tenant_id>"
},
});List paymentsreadxero.list_paymentsList payments applied to invoices in a Xero organisation, optionally filtered with a where expression such as Status=="AUTHORISED".
Needs scope: accounting.payments.read
| Input | Type | Description | |
|---|---|---|---|
tenant_id | string | Required | Xero organisation (tenant) id from list_connections |
where | string | Optional | Xero filter, e.g. Date>=DateTime(2026,10,1) |
order | string | Optional | Sort, e.g. Date DESC |
page | integer | Optional | Page number, starting at 1 |
await setu.execute({
userId: "user_1",
action: "xero.list_payments",
input: {
"tenant_id": "<tenant_id>"
},
});