Integrations

Xero

Reconcile Xero AP and AR against Zivvy /v1/purchase-invoices and /v1/sales-invoices.

The snag

Bookkeepers post AP and AR in Xero while operations run in another system, so reconciliation is always a manual join.

How Zivvy helps

Zivvy syncs both directions of Xero AP (Bills) and AR (Invoices) into /v1/purchase-invoices and /v1/sales-invoices, keyed by Xero's InvoiceID.

What you get

  • Two-way AR sync via /v1/sales-invoices
  • Two-way AP sync via /v1/purchase-invoices
  • Xero bank feed reconciled against /v1/payment-entries

Workflow stream

Xero Bill → /v1/purchase-invoices

Common uses

  1. 01

    Xero Bill → /v1/purchase-invoices

  2. 02

    Xero Invoice → /v1/sales-invoices

  3. 03

    Xero payment reconciles to /v1/payment-entries

Integration code

Open API reference

Post a Xero bill

curl -X POST https://integrate.zivvy.xyz/v1/purchase-invoices \
  -H "Authorization: Bearer $ZIVVY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "supplier": "AWS",
    "external_id": "xero-bill-1234",
    "bill_no": "AWS-INV-2026-07",
    "items": [{ "item_code": "CLOUD-USAGE", "qty": 1, "rate": 4210.55 }]
  }'

Bridge Xero webhook

import { XeroClient } from "xero-node";
import { zivvy } from "./zivvy-client";

export async function onXeroInvoiceUpdated(evt) {
  const inv = await xero.accountingApi.getInvoice(
    evt.tenantId, evt.resourceId
  );
  await zivvy.salesInvoices.upsert({
    external_id: `xero-${inv.body.invoices[0].invoiceID}`,
    customer: inv.body.invoices[0].contact.name,
    posting_date: inv.body.invoices[0].date
  });
}

API endpoints

POST /v1/sales-invoicesPOST /v1/purchase-invoicesPOST /v1/payment-entries

Events emitted

HMAC-SHA256 signed webhooks, retried for 24 hours.

  • sales-invoices.submitted
  • purchase-invoices.submitted
  • payment-entries.paid

0

free seats forever

0

card required to start

1

workspace for the workflow

Questions

Ready to try it?

Free plan. Two seats. No card.