@xeroapi/xero-command-line
v0.0.2
Published
CLI tool for Xero API access via PKCE OAuth
Readme
xero-command-line
A command-line tool for the Xero API using PKCE OAuth. Authenticates via browser-based login — no client secret required. Supports multiple Xero organisations via named profiles.
Alpha (v0.0.1) — APIs may change.
Install
npm install -g @xeroapi/xero-command-lineOr try it without installing:
npx @xeroapi/xero-command-line <command>From source
git clone https://github.com/XeroAPI/xero-command-line.git
cd xero-command-line
npm install
npm run build
npm linkPrerequisites
- Node.js >= 18
- A Xero OAuth 2.0 app at developer.xero.com (no client secret needed — PKCE handles authentication)
- Set the redirect URI on your OAuth 2.0 PKCE app to
http://localhost:8742/callback
Setup
- Create a profile with your Xero app's Client ID:
xero profile add my-company
# Prompts for Client IDOr pass it inline:
xero profile add my-company --client-id YOUR_CLIENT_ID- Log in via the browser:
xero loginThis opens your browser for Xero's OAuth consent flow. After you authorize, the CLI receives tokens via a local callback server. If your app is connected to multiple organisations, you'll be prompted to select one.
Tokens are encrypted (AES-256-GCM) and cached at ~/.config/xero-command-line/tokens.json. The encryption key is stored in the OS keychain. Tokens refresh automatically when expired.
Global Flags
Every command that calls the Xero API supports:
| Flag | Description |
|---|---|
| -p, --profile <name> | Use a specific profile (defaults to the default profile) |
| --client-id <id> | Override profile with an inline client ID |
| --json | Output raw JSON (for piping/scripting) |
| --csv | Output as CSV |
Environment variables XERO_PROFILE and XERO_CLIENT_ID are also supported.
Finding IDs
Most commands that reference contacts, invoices, or accounts require a Xero GUID (e.g., edc74793-8d7e-4bf2-9e63-146dc4c675a2). Use the list commands to find IDs:
xero contacts list --search "Acme" # find a contact ID
xero accounts list # find account codes
xero invoices list # find invoice IDsCommands
Profile Management
# Add a profile (first profile becomes the default)
xero profile add acme-corp
# List all profiles
xero profile list
# Set the default profile
xero profile set-default acme-corp
# Remove a profile
xero profile remove acme-corpOrganisation
xero org details
xero org details --jsonContacts
# List contacts
xero contacts list
xero contacts list --search "Acme"
xero contacts list --page 2 --json
# Create a contact
xero contacts create --name "Acme Corp" --email [email protected] --phone "+1234567890"
xero contacts create --file contact.json
# Update a contact
xero contacts update --contact-id 00000000-0000-0000-0000-000000000001 --name "Acme Corporation" --email [email protected]
xero contacts update --file contact-update.jsonContact Groups
xero contact-groups list
xero contact-groups list --group-id 00000000-0000-0000-0000-000000000001Accounts
xero accounts list
xero accounts list --jsonInvoices
# List invoices
xero invoices list
xero invoices list --contact-id 00000000-0000-0000-0000-000000000001
xero invoices list --invoice-number INV-0001
xero invoices list --page 2 --csv
# Create an invoice (inline flags for a single line item)
xero invoices create --contact-id 00000000-0000-0000-0000-000000000001 --type ACCREC \
--description "Consulting" --quantity 10 --unit-amount 150 \
--account-code 200 --tax-type OUTPUT2
# Create an invoice (JSON file for multiple line items)
xero invoices create --file invoice.json
# Update a draft invoice
xero invoices update --invoice-id 00000000-0000-0000-0000-000000000001 --reference "Updated ref"
xero invoices update --file invoice-update.json{
"contactId": "00000000-0000-0000-0000-000000000001",
"type": "ACCREC",
"date": "2025-06-15",
"reference": "REF-001",
"lineItems": [
{
"description": "Consulting",
"quantity": 10,
"unitAmount": 150,
"accountCode": "200",
"taxType": "OUTPUT2"
},
{
"description": "Travel",
"quantity": 1,
"unitAmount": 500,
"accountCode": "200",
"taxType": "OUTPUT2"
}
]
}Quotes
# List quotes
xero quotes list
xero quotes list --contact-id 00000000-0000-0000-0000-000000000001
xero quotes list --quote-number QU-0001
# Create a quote
xero quotes create --file quote.json
xero quotes create --contact-id 00000000-0000-0000-0000-000000000001 --title "Project Quote" \
--date 2025-12-30 --description "Web design" --quantity 1 --unit-amount 5000 \
--account-code 200 --tax-type OUTPUT2
# Update a draft quote
xero quotes update --file quote-update.jsonCredit Notes
# List credit notes
xero credit-notes list
xero credit-notes list --contact-id 00000000-0000-0000-0000-000000000001 --page 2
# Create a credit note
xero credit-notes create --file credit-note.json
xero credit-notes create --contact-id 00000000-0000-0000-0000-000000000001 \
--description "Refund" --quantity 1 --unit-amount 100 \
--account-code 200 --tax-type OUTPUT2
# Update a draft credit note
xero credit-notes update --file credit-note-update.jsonManual Journals
# List manual journals
xero manual-journals list
xero manual-journals list --manual-journal-id 00000000-0000-0000-0000-000000000001
xero manual-journals list --modified-after 2025-01-01
# Create a manual journal (requires JSON file — minimum 2 lines)
xero manual-journals create --file journal.json
# Update a draft manual journal
xero manual-journals update --file journal-update.json{
"narration": "Reclassify office supplies",
"manualJournalLines": [
{ "accountCode": "200", "lineAmount": 100, "description": "Debit" },
{ "accountCode": "400", "lineAmount": -100, "description": "Credit" }
]
}Bank Transactions
# List bank transactions
xero bank-transactions list
xero bank-transactions list --bank-account-id 00000000-0000-0000-0000-000000000001
# Create a bank transaction
xero bank-transactions create --file bank-transaction.json
xero bank-transactions create --type SPEND --bank-account-id 00000000-0000-0000-0000-000000000001 \
--contact-id 00000000-0000-0000-0000-000000000002 --description "Office supplies" \
--quantity 1 --unit-amount 50 --account-code 429 --tax-type INPUT2
# Update a bank transaction
xero bank-transactions update --file bank-transaction-update.jsonPayments
# List payments
xero payments list
xero payments list --invoice-id 00000000-0000-0000-0000-000000000001
xero payments list --invoice-number INV-0001
xero payments list --reference "Payment ref"
# Create a payment
xero payments create --invoice-id 00000000-0000-0000-0000-000000000001 --account-id 00000000-0000-0000-0000-000000000002 --amount 500
xero payments create --file payment.jsonItems
# List items
xero items list
xero items list --page 2
# Create an item
xero items create --code WIDGET --name "Widget" --sale-price 29.99
xero items create --file item.json
# Update an item
xero items update --item-id 00000000-0000-0000-0000-000000000001 --code WIDGET --name "Updated Widget"
xero items update --file item-update.jsonCurrencies
xero currencies list
xero currencies list --jsonTax Rates
xero tax-rates list
xero tax-rates list --jsonTracking Categories & Options
# List tracking categories
xero tracking categories list
xero tracking categories list --include-archived
# Create a tracking category
xero tracking categories create --name "Department"
# Update a tracking category
xero tracking categories update --category-id 00000000-0000-0000-0000-000000000001 --name "Region"
xero tracking categories update --category-id 00000000-0000-0000-0000-000000000001 --status ARCHIVED
# Create tracking options
xero tracking options create --category-id 00000000-0000-0000-0000-000000000001 --names "Sales,Marketing,Engineering"
# Update tracking options
xero tracking options update --category-id 00000000-0000-0000-0000-000000000001 --file tracking-options.jsonReports
# Trial balance
xero reports trial-balance
xero reports trial-balance --date 2025-12-31 --json
# Profit and loss
xero reports profit-and-loss
xero reports profit-and-loss --from 2025-01-01 --to 2025-12-31
xero reports profit-and-loss --timeframe QUARTER --periods 4
# Balance sheet
xero reports balance-sheet
xero reports balance-sheet --date 2025-12-31
xero reports balance-sheet --timeframe MONTH --periods 12
# Aged receivables (requires contact ID)
xero reports aged-receivables --contact-id 00000000-0000-0000-0000-000000000001
xero reports aged-receivables --contact-id 00000000-0000-0000-0000-000000000001 --report-date 2025-12-31
# Aged payables (requires contact ID)
xero reports aged-payables --contact-id 00000000-0000-0000-0000-000000000001
xero reports aged-payables --contact-id 00000000-0000-0000-0000-000000000001 --from-date 2025-01-01 --to-date 2025-12-31JSON File Input
Commands that create or update resources accept a --file flag with a JSON payload. All inputs are validated before being sent to the API. Validation errors are displayed with specific field-level messages.
xero invoices create --file invoice.jsonOutput Formats
# Formatted table (default)
xero contacts list
# JSON (for piping to jq, scripts, etc.)
xero contacts list --json
# CSV (for spreadsheets)
xero contacts list --csvMultiple Organisations
Use profiles to manage multiple Xero orgs:
xero profile add client-a --client-id ID_A
xero profile add client-b --client-id ID_B
xero login -p client-a
xero login -p client-b
xero contacts list --profile client-a
xero invoices list --profile client-bDevelopment
# Run in dev mode (no build step)
npm run dev -- contacts list
# Build
npm run build
# Run tests
npm test
npm run test:watch