Xero Chart of Accounts
Overview
The chart of accounts (COA) in Xero defines the general ledger structure for your organization. Every invoice line item, payment, and bank transaction references an account code. For MSPs, a well-structured COA enables tracking revenue by service line (managed services, projects, hardware sales), expenses by vendor category, and provides the foundation for meaningful financial reporting.
Core Concepts
Account Classes
Xero organizes accounts into five standard accounting classes:
| Class | Description | MSP Examples |
|---|---|---|
ASSET | Things you own | Bank accounts, accounts receivable, equipment |
EQUITY | Owner's stake | Retained earnings, owner's equity |
EXPENSE | Costs of business | Software licenses, salaries, ISP costs |
LIABILITY | Things you owe | Accounts payable, loans, tax liabilities |
REVENUE | Income earned | Managed services, project revenue, hardware sales |
Account Types
Each class contains specific account types:
| Class | Type | Code | Description |
|---|---|---|---|
| ASSET | BANK | BANK | Bank accounts (used for payments) |
| ASSET | CURRENT | CURRENT | Current assets (AR, inventory) |
| ASSET | FIXED | FIXED | Fixed assets (equipment) |
| ASSET | PREPAYMENT | PREPAYMENT | Prepaid expenses |
| EQUITY | EQUITY | EQUITY | Equity accounts |
| EXPENSE | EXPENSE | EXPENSE | Operating expenses |
| EXPENSE | DIRECTCOSTS | DIRECTCOSTS | Cost of goods sold |
| EXPENSE | OVERHEADS | OVERHEADS | Overhead expenses |
| LIABILITY | CURRLIAB | CURRLIAB | Current liabilities |
| LIABILITY | LIABILITY | LIABILITY | Long-term liabilities |
| LIABILITY | TERMLIAB | TERMLIAB | Term liabilities |
| REVENUE | REVENUE | REVENUE | Revenue accounts |
| REVENUE | OTHERINCOME | OTHERINCOME | Other income |
| REVENUE | SALES | SALES | Sales revenue |
MSP Chart of Accounts Structure
A typical MSP chart of accounts includes:
Revenue (200-299)
200 - Managed Services Revenue
210 - Project Revenue
220 - Hardware Sales
230 - Software License Revenue
240 - Cloud Services Revenue
250 - Consulting Revenue
Cost of Sales (400-499)
400 - Software License Costs
410 - Hardware Costs
420 - Cloud Platform Costs (Azure, AWS)
430 - ISP/Connectivity Costs
440 - Subcontractor Costs
Expenses (500-699)
500 - Salaries & Wages
510 - Employee Benefits
520 - Office Rent
530 - Insurance
540 - Marketing
550 - Professional Development
560 - Tools & Subscriptions
Field Reference
Core Fields
| Field | Type | Required | Description |
|---|---|---|---|
AccountID | string (UUID) | System | Auto-generated unique identifier |
Code | string | Yes | Account code (e.g., "200", "400") |
Name | string | Yes | Account name |
Type | string | Yes | Account type (REVENUE, EXPENSE, BANK, etc.) |
Status | string | No | ACTIVE or ARCHIVED |
Description | string | No | Account description |
TaxType | string | No | Default tax type for this account |
EnablePaymentsToAccount | boolean | No | Whether payments can be made to this account |
ShowInExpenseClaims | boolean | No | Show in expense claims |
Class | string | Read-only | Account class (ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE) |
BankAccountNumber | string | No | Bank account number (BANK type only) |
BankAccountType | string | No | BANK or CREDITCARD (BANK type only) |
CurrencyCode | string | No | Currency for bank accounts |
ReportingCode | string | No | Reporting code for financial statements |
ReportingCodeName | string | Read-only | Reporting code name |
System Accounts (Read-Only)
| Field | Type | Description |
|---|---|---|
SystemAccount | string | System account type (e.g., DEBTORS, CREDITORS) |
Xero creates these system accounts automatically:
| System Account | Description |
|---|---|
DEBTORS | Accounts Receivable |
CREDITORS | Accounts Payable |
GST | Tax collected/paid |
GSTONIMPORTS | Tax on imports |
HISTORICAL | Historical adjustment |
REALISEDCURRENCYGAIN | Realized currency gains |
UNREALISEDCURRENCYGAIN | Unrealized currency gains |
ROUNDING | Rounding adjustments |
API Patterns
List All Accounts
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
With Filters:
# Revenue accounts only
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts?where=Class==%22REVENUE%22" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
# Bank accounts only
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts?where=Type==%22BANK%22" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
# Active accounts only
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts?where=Status==%22ACTIVE%22" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
# Expense accounts
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts?where=Class==%22EXPENSE%22" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
Get Single Account
curl -s -X GET "https://api.xero.com/api.xro/2.0/Accounts/${ACCOUNT_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Accept: application/json"
Create Account
curl -s -X POST "https://api.xero.com/api.xro/2.0/Accounts" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Content-Type: application/json" \
-d '{
"Code": "245",
"Name": "Cloud Services Revenue",
"Type": "REVENUE",
"Description": "Revenue from cloud hosting and Azure/AWS resale",
"TaxType": "OUTPUT"
}'
Update Account
curl -s -X POST "https://api.xero.com/api.xro/2.0/Accounts/${ACCOUNT_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Content-Type: application/json" \
-d '{
"AccountID": "'${ACCOUNT_ID}'",
"Name": "Cloud & Hosting Revenue",
"Description": "Revenue from cloud hosting, Azure, AWS, and SaaS resale"
}'
Archive Account
curl -s -X POST "https://api.xero.com/api.xro/2.0/Accounts/${ACCOUNT_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}" \
-H "Content-Type: application/json" \
-d '{
"AccountID": "'${ACCOUNT_ID}'",
"Status": "ARCHIVED"
}'
Delete Account
curl -s -X DELETE "https://api.xero.com/api.xro/2.0/Accounts/${ACCOUNT_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "xero-tenant-id: ${XERO_TENANT_ID}"
Note: Accounts with transactions cannot be deleted. Archive them instead.
Common Workflows
Set Up MSP Revenue Accounts
async function setupMspRevenueAccounts() {
const accounts = [
{ Code: '200', Name: 'Managed Services Revenue', Type: 'REVENUE', Description: 'Monthly recurring managed services contracts' },
{ Code: '210', Name: 'Project Revenue', Type: 'REVENUE', Description: 'One-time project and implementation work' },
{ Code: '220', Name: 'Hardware Sales', Type: 'REVENUE', Description: 'Hardware sales and procurement markup' },
{ Code: '230', Name: 'Software License Revenue', Type: 'REVENUE', Description: 'Software license resale (M365, security, etc.)' },
{ Code: '240', Name: 'Cloud Services Revenue', Type: 'REVENUE', Description: 'Cloud hosting and IaaS/PaaS resale' },
{ Code: '250', Name: 'Consulting Revenue', Type: 'REVENUE',