Xero Accounting API — SKILL.md

Raw skill file that agents receive when using this skill

Download
---
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