Xero Accounting API — SKILL.md
Raw skill file that agents receive when using this skill
---
name: "Xero Accounting API"
description: "Integrate with Xero: OAuth 2.0 + PKCE, multi-tenant, invoices, payments, bank transactions, webhooks, tax handling (GST/VAT), SDKs, and app certification. Use when building accounting integrations outside the US/Canada market."
version: "1.0.0"
author: "skynet"
category: "dev"
agents: ["claude-code", "codex", "gemini"]
tags: ["xero", "accounting", "api", "oauth", "invoicing", "saas"]
---
# Xero Accounting API
---
name: "Xero Accounting API"
description: "Integrate with Xero: OAuth 2.0 + PKCE, multi-tenant, invoices, payments, bank transactions, webhooks, tax handling (GST/VAT), SDKs, and app certification. Use when building accounting integrations out"
version: "1.0.0"
author: "skynet"
category: "dev"
tags: ["xero", "accounting", "api", "oauth", "invoicing", "saas"]
---
I will search for any existing Xero-related code or documentation in the repository to provide context-specific examples if available.
This technical reference provides a comprehensive guide for integrating with the Xero Accounting API, covering authentication, core resources, common workflows, and operational best practices.
---
### 1. Authentication: OAuth 2.0 with PKCE
Xero uses OAuth 2.0. For server-side or desktop apps, **Proof Key for Code Exchange (PKCE)** is recommended to enhance security by preventing authorization code injection.
* **Scopes:** Common scopes include `openid`, `profile`, `email`, `accounting.transactions`, `accounting.contacts`, `accounting.settings`, `offline_access` (required for refresh tokens).
* **The Tenant ID:** Unlike some APIs where the token is enough, Xero requires a `Xero-tenant-id` header in every request. An authorized user may have access to multiple organizations; you must fetch the connections to allow the user to select the active tenant.
* **Endpoint:** `GET https://api.xero.com/connections`
* **Token Refresh:** Access tokens expire in 30 minutes. Use the `refresh_token` to get a new `access_token` and a *new* `refresh_token`.
```javascript
// Example: Token Refresh (Node.js)
const response = await axios.post('https://identity.xero.com/connect/token', {
grant_type: 'refresh_token',
refresh_token: savedRefreshToken,
client_id: process.env.XERO_CLIENT_ID,
client_secret: process.env.XERO_CLIENT_SECRET
});
```
---
### 2. Key Endpoints
All Accounting API calls are base-pathed to `https://api.xero.com/api.xro/2.0/`.
| Endpoint | Purpose |
| :--- | :--- |
| `/Contacts` | Create/Update customers and suppliers. |
| `/Invoices` | Sales invoices and purchase bills. |
| `/Payments` | Apply payments to Invoices or Credit Notes. |
| `/BankTransactions` | Spend/Receive money transactions not linked to an invoice. |
| `/Accounts` | Chart of Accounts (required for coding transactions). |
| `/Items` | Inventory items or services for line items. |
| `/ManualJournals` | Low-level accounting adjustments. |
| `/Reports` | Access Profit & Loss, Balance Sheet, etc. |
---
### 3. Common Integration Patterns
#### Invoice Creation
Invoices require a `ContactID`, `Type` (`ACCREC` for sales, `ACCPAY` for bills), and at least one `LineItem`.
* **Status:** Use `DRAFT`, `SUBMITTED`, or `AUTHORISED`.
* **Deep Links:** Use the `InvoiceID` to generate a link directly to the Xero UI: `https://go.xero.com/AccountsReceivable/View.aspx?InvoiceID={ID}`.
#### Payment Reconciliation
To pay an invoice, POST to `/Payments`:
```json
{
"Invoice": { "InvoiceID": "..." },
"Account": { "AccountID": "..." },
"Date": "2023-10-27",
"Amount": 150.00
}
```
#### Tax Handling (GST/VAT/Sales Tax)
* **TaxTypes:** Xero uses specific strings like `OUTPUT`, `INPUT`, `NONE`, or region-specific codes like `GSTONIMPORTS`.
* **Line Amount Types:** Specify if line amounts are `Inclusive`, `Exclusive`, or `NoTax`. This significantly affects rounding calculations.
---
### 4. Webhooks
Xero webhooks notify you of changes in real-time.
1. **Intent to Receive:** When you first add a webhook URL, Xero sends a POST with a `x-xero-signature` header. You must respond with the same signature to verify ownership.
2. **Verification:** Every payload is signed with your Webhook Key using **HMACSHA256**.
3. **Events:** Supported for `Invoices`, `Contacts`, `Accounts`, and `BankTransactions`. Events are batched (up to 60 seconds of delay).
---
### 5. SDKs vs. Direct REST
* **Official SDKs:** `xero-node`, `xero-python`, `xero-ruby`, `xero-php`, `xero-dotnet`.
* **Direct Usage:** Highly recommended for simple integrations to avoid bloated dependencies. Use standard JSON headers, but remember Xero also supports XML (legacy).
---
### 6. Rate Limits
Xero enforces strict tiered limits:
* **Minute Limit:** 60 calls per minute per tenant.
* **Daily Limit:** 5,000 calls per 24-hour period per tenant.
* **Concurrent Limit:** 5 calls at any one time.
* **App Limit:** 10,000 calls per minute across all tenants for your app.
*Strategy: Implement a retry-after logic by inspecting the `X-Rate-Limit-Retry-After` header.*
---
### 7. Gotchas & Differences
* **Xero vs. QuickBooks:** Xero is strictly "double-entry" first. You cannot delete a payment; you must void or un-apply it. Contacts are shared between customers and suppliers.
* **Rounding:** Xero rounds at the line item level, then sums. If your external system rounds the total first, you may have a 1-2 cent discrepancy.
* **Pagination:** Use the `page` parameter (e.g., `?page=1`). Each page returns 100 records.
* **If-Modified-Since:** Use this header to sync only changed records. Xero returns a `304 Not Modified` if nothing has changed since the provided UTC timestamp.
---
### 8. Testing: The Demo Company
Every Xero user has access to a **Demo Company**.
* It contains pre-populated data (Invoices, Bank Statements, Contacts).
* It can be reset at any time to a clean state.
* **Crucial:** Use the Demo Company for testing Webhooks and Bank Feeds to avoid messing up live production accounts.
---
### 9. Xero App Store & Certification
To list your app on the Xero App Store, you must:
1. **Certification:** Pass a technical and UX review.
2. **OAuth Requirements:** Use the standard OAuth 2.0 flow.
3. **Sign-up:** Provide a "Sign up with Xero" button for new users.
4. **Support:** Maintain a support URL and documentation for Xero users.
*Note: Certified apps can request higher rate limits if they hit the 5,000 daily cap consistently.*
curl -s https://skills.skynet.ceo/api/skills/xero-api/skill.md