Skip to main content

A lightweight Python client for core Xero Accounting API workflows

Project description

XeroConnect

A lightweight Python client for core Xero Accounting API workflows.

XeroConnect is not a full Xero SDK, ERP, or sync engine. It wraps a focused set of endpoints — OAuth, invoices, contacts, payments, and Profit & Loss reports — with a small API surface and a single runtime dependency (httpx).

Who This Package Is For

XeroConnect is a good fit if you:

  • Need a small, readable client for common accounting workflows in production systems
  • Want plain JSON dict responses without generated model classes
  • Already know which Xero endpoints you need and do not require full API coverage
  • Prefer a minimal dependency footprint (httpx only)
  • Are building scripts, internal tools, or backend services that list invoices, fetch contacts, read payments, or pull P&L reports

Who This Package Is Not For

XeroConnect is not the right choice if you:

  • Need broad Xero API coverage (payroll, projects, assets, files, bank feeds, and more)
  • Want official Xero-maintained SDKs with OpenAPI-generated models and published API reference docs
  • Are building a full Xero App Store application and need sample apps, helper methods, and platform-specific integration patterns
  • Require PKCE OAuth flows for desktop or mobile apps (not supported in v0.1.0)
  • Need create/update endpoints across all resources (v0.1.0 covers a read-heavy subset with limited writes)

XeroConnect vs Other Python Libraries

Several Python libraries exist for Xero. Here is how they differ in scope and design.

xero-python pyxero xerosdk XeroConnect
Maintainer Xero Developer API (official) Community Third-party (Fyle) Independent open source
API coverage Full — Accounting, Payroll (AU/UK/NZ), Projects, Assets, Files Accounting endpoints via dict API Subset — Invoices, Contacts, Accounts, Items, Tracking Focused subset — OAuth, Invoices, Contacts, Payments, P&L
Response format Generated model classes Dicts Class-based wrappers Dicts
HTTP library urllib3 (via generated client) requests requests httpx
OAuth Built-in token management helpers OAuth2 with PKCE support Refresh token on connection Separate OAuthClient
Package size Large (OpenAPI-generated) Moderate Small Small

When to Use XeroConnect

Use XeroConnect when your integration only needs the endpoints it supports, you value a small install and a simple resource-based API (client.invoices.list()), and plain dict responses are sufficient for your application.

When to Use the Official SDK (xero-python)

Use the official Xero Python SDK when you need full API coverage across Accounting and other Xero API sets (Payroll, Projects, Assets, Files), typed model classes generated from Xero's OpenAPI specification, official documentation and sample applications, or long-term alignment with Xero's published SDK conventions.

When to Use Other Libraries

  • pyxero — established community library with dict-based access to accounting endpoints and PKCE OAuth support. A reasonable choice if you need broader accounting CRUD with a dict-oriented API.
  • xerosdk — small third-party SDK covering a limited set of resource classes with built-in token refresh on the connection object.

Positioning

XeroConnect is a focused Python client for production accounting workflows — OAuth, invoices, contacts, payments, and Profit & Loss reports — without the scope of a full API SDK.

What It Supports

Core Endpoints

Area Methods
OAuth Authorization URL, token exchange, refresh token, connections
Invoices List, get, update
Contacts Get
Payments List

Reports

Report Method
Profit & Loss client.reports.profit_and_loss()

Installation

pip install xeroconnect

For development:

git clone https://github.com/alixaprodev/xeroconnect.git
cd xeroconnect
pip install -e ".[dev]"

OAuth Flow

Use OAuthClient to handle the authorization flow separately from API calls:

from xeroconnect import OAuthClient

oauth = OAuthClient(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
    redirect_uri="https://yourapp.com/callback",
)

# Step 1: Redirect the user to this URL
auth_url = oauth.get_authorization_url(
    scopes=[
        "openid",
        "profile",
        "email",
        "accounting.transactions",
        "accounting.contacts",
        "offline_access",
    ],
    state="random-state-string",
)

# Step 2: Exchange the authorization code for tokens
tokens = oauth.exchange_code("authorization-code-from-callback")
access_token = tokens["access_token"]
refresh_token = tokens["refresh_token"]

# Step 3: Resolve tenant ID from connections
connections = oauth.get_connections(access_token)
tenant_id = connections[0]["tenantId"]

# Step 4: Refresh when the access token expires
tokens = oauth.refresh_token(refresh_token)

Basic Client Usage

from xeroconnect import XeroClient

client = XeroClient(
    access_token="your-access-token",
    tenant_id="your-tenant-id",
)

# Use as a context manager to ensure connections are closed
with XeroClient(access_token="...", tenant_id="...") as client:
    invoices = client.invoices.list()

Invoices

# List invoices with filtering and pagination
invoices = client.invoices.list(
    where='Date >= DateTime(2026, 1, 1)',
    order="Date DESC",
    page=1,
    page_size=100,
)

# Get a single invoice
invoice = client.invoices.get("invoice-id")
print(invoice["Invoices"][0]["InvoiceNumber"])

# Update an invoice (Xero uses POST for updates)
result = client.invoices.update("invoice-id", {
    "Invoices": [{
        "InvoiceID": "invoice-id",
        "Status": "AUTHORISED",
    }],
})

Contacts

contact = client.contacts.get("contact-id")
print(contact["Contacts"][0]["Name"])

Payments

payments = client.payments.list(page=1)

payments = client.payments.list(
    where='Status=="AUTHORISED"',
    order="Date DESC",
    page_size=50,
)

Profit and Loss Report

report = client.reports.profit_and_loss(
    from_date="2026-01-01",
    to_date="2026-01-31",
)

# With optional parameters
report = client.reports.profit_and_loss(
    from_date="2026-01-01",
    to_date="2026-01-31",
    periods=3,
    timeframe="MONTH",
    tracking_category_id="category-id",
    tracking_option_id="option-id",
)

Error Handling

XeroConnect raises typed exceptions with useful context:

from xeroconnect import (
    XeroClient,
    XeroAPIError,
    XeroAuthError,
    XeroRateLimitError,
    XeroValidationError,
)

client = XeroClient(access_token="...", tenant_id="...")

try:
    invoices = client.invoices.list()
except XeroRateLimitError as e:
    print(f"Rate limited: {e.xero_message}")
    print(f"Status: {e.status_code}")
except XeroValidationError as e:
    print(f"Bad request: {e.xero_message}")
except XeroAPIError as e:
    print(f"API error {e.status_code} on {e.endpoint}")
    print(f"Response: {e.response_body}")
Exception When
XeroConnectError Base exception
XeroAuthError OAuth / authentication failures
XeroAPIError General API errors
XeroRateLimitError HTTP 429 rate limit
XeroValidationError HTTP 400 validation errors

Limitations

  • Focused scope — Only the endpoints listed above are supported. See xero-python for full API coverage.
  • No models — Responses are plain JSON dictionaries.
  • No token storage — You manage access and refresh tokens yourself.
  • No webhooks — Not included in v0.1.0.
  • No sync engine — No background workers or database integration.
  • No framework bindings — No Django or FastAPI integration.
  • Limited write operations — Invoice update is supported; invoice create, contact create, and payment create are not.

Roadmap

  • Items API
  • Generic GET helper for explorer-style access
  • Webhooks support
  • Batch sync helpers
  • Additional reports (Balance Sheet, Trial Balance)
  • Contact list and create endpoints
  • Payment create endpoint

Requirements

  • Python >= 3.9
  • httpx >= 0.27

License

MIT License — see LICENSE for details.

Contributing

See CONTRIBUTING.md for setup, testing, and pull request guidelines.

Release history is in CHANGELOG.md.

Author

H. Ali — haxratali0@gmail.com

GitHub: https://github.com/alixaprodev/xeroconnect

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xeroconnect-0.1.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xeroconnect-0.1.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file xeroconnect-0.1.0.tar.gz.

File metadata

  • Download URL: xeroconnect-0.1.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for xeroconnect-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8359c658dc0d85beec56563a109ce73e9dafddaf47e3c290b83238f5f1d252e6
MD5 e34a2be8f30bf92c7730bb5b393fd8da
BLAKE2b-256 f3bf1e065f0385360cebdbbd555b379e28554cef0c95fe28d08cbf2ada939c56

See more details on using hashes here.

File details

Details for the file xeroconnect-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: xeroconnect-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for xeroconnect-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4556d54b19e4115b477e0ff2c5b9841f9272a375f0c2c14f4c2e6c6489885354
MD5 40a0096925d24616434064144f2816fc
BLAKE2b-256 8630343a53b0e4812edb237f0be73c3f3a0a17e4bd28f5ff9319dad4ea4217d5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page