AccountingKitDocs

Quickstart

Register a Xero app, connect an organization, and run your first accounting workflow.

1. Register your Xero app

Paid production contracts use a Xero OAuth app owned by your organization. In the console, choose the intended Test or Live environment, open Provider apps, and add Xero. Name the configuration first; AccountingKit immediately creates a resumable draft and shows its callback URLs.

Copy the two generated values into the Xero developer portal:

  • Add the AccountingKit OAuth redirect URI to the app's redirect URIs.
  • Set the app's webhook delivery URL to the app-specific AccountingKit URL.

Then paste the Xero client ID, client secret, and webhook signing key into AccountingKit. The credentials are encrypted and are never returned. The webhook URL contains an opaque AccountingKit app ID, allowing AccountingKit to select the correct signing key before trusting the webhook body. Trials may omit this step and use the hosted AccountingKit Xero app within the trial allowance.

2. Create a test API key

Sign in to the developer console, select test, name the key, and create it. Copy the secret when it is shown; only an HMAC digest is stored and the secret cannot be recovered later.

API keys use the acct_test_ or acct_live_ prefix. Send the key as a bearer token:

Authorization: Bearer acct_test_...

For TypeScript services, use the typed client:

import {AccountingKitClient} from '@accountingkit/sdk'

const accounting = new AccountingKitClient({
  apiKey: process.env.ACCOUNTINGKIT_API_KEY!,
  baseUrl: 'https://api.example.com',
})

3. Create a connect session

curl --request POST "$API_URL/v1/connect-sessions" \
  --header "Authorization: Bearer $ACCOUNTING_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "provider": "xero",
    "external_account_id": "customer_123",
    "redirect_uri": "https://app.example.com/integrations/xero/complete",
    "provider_app_id": "the-app-id-from-the-console",
    "retention_mode": "cached",
    "metadata": {"workspace_id": "workspace_456"}
  }'

Open the returned connect_url in the customer's browser. AccountingKit performs Xero OAuth using the selected customer-owned app, discovers authorized organizations, and stores encrypted rotating tokens. If Xero returns more than one organization, the customer must choose one before the connection becomes active.

retention_mode defaults to cached. Use zero only for live-read integrations that do not need sync, automations, webhook hydration, or cached lists.

4. Verify app setup and list connections

Return to Provider apps, open the app, and select Check setup. OAuth, Xero intent-to-receive, and every required scope must be complete before production cutover.

curl "$API_URL/v1/connections" \
  --header "Authorization: Bearer $ACCOUNTING_API_KEY"

Store connection_id against the same customer record as external_account_id.

5. Create a draft invoice

All writes require an idempotency key. Repeating the same key and request returns the original result. Reusing a key with a different request is rejected.

curl --request POST "$API_URL/v1/connections/$CONNECTION_ID/invoices" \
  --header "Authorization: Bearer $ACCOUNTING_API_KEY" \
  --header "Idempotency-Key: invoice-order-10042" \
  --header "Content-Type: application/json" \
  --data '{
    "external_reference": "order_10042",
    "contact_id": "provider-or-normalized-contact-id",
    "status": "DRAFT",
    "due_date": "2026-09-30",
    "line_items": [
      {"description": "Implementation", "quantity": 1, "unit_amount": 1200}
    ]
  }'

6. Register a webhook endpoint

Create an HTTPS endpoint through POST /v1/webhook-endpoints. The signing secret is returned once. Verify every delivery before processing it. See webhooks.

On this page