---
name: unified-accounting-invoicing
description: >-
  Build invoicing, billing, and bookkeeping features against many accounting
  platforms (QuickBooks, Xero, NetSuite, Sage, FreshBooks, and more) through the
  single Unified.to Accounting API. Use when a coding task involves creating or
  syncing invoices, bills, contacts, accounts, payments, or financial reports
  across one or more accounting systems.
license: MIT
metadata:
  category: accounting
  api_base: https://api.unified.to
  docs: https://docs.unified.to/accounting/overview
---

# Build an invoicing system with the Unified.to Accounting API

Unified.to normalizes many accounting platforms behind one REST API. Build your
invoicing/bookkeeping integration once and it works across every supported
platform. This skill teaches an agent how to build against the Unified
Accounting API.

## When to use this skill

Use this skill when the task is to:

- Create and send invoices, and sync their status
- Manage contacts (customers/vendors) and chart-of-accounts data
- Record bills, expenses, credit memos, and payments
- Pull financial reports (balance sheet, P&L, aged receivables)
- Support more than one accounting platform without platform-specific code

## Prerequisites

1. A Unified.to workspace with an **API key** and **Workspace ID**.
2. An activated accounting integration (e.g. QuickBooks) — start in the Sandbox.
3. A **connection ID** from the embedded Authorization component
   (https://docs.unified.to/concepts/embedded-components).

Keep the API key server-side only.

## Core request pattern

```
https://api.unified.to/accounting/{connection_id}/{object}
```

Authenticate every request:

```
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

Regional base URLs: `api.unified.to` (NA), `api-eu.unified.to` (EU),
`api-au.unified.to` (AU).

## Data objects (subset)

| Object          | Purpose                                         |
| --------------- | ----------------------------------------------- |
| `invoice`       | A customer invoice                              |
| `bill`          | A vendor bill                                   |
| `contact`       | A customer or vendor                            |
| `account`       | A chart-of-accounts account                     |
| `transaction`   | A financial transaction                         |
| `creditmemo`    | A credit memo                                   |
| `expense`       | An expense                                      |
| `taxrate`       | A tax rate                                      |
| `journal`       | A journal entry                                 |

Read-only report objects include `balancesheet`, `profitloss`, `cashflow`,
`agedreceivable`, `agedpayable`, and `trialbalance`.

### Supported operations (invoice shown; most objects follow the same shape)

| Method   | Path                                 | Description        |
| -------- | ------------------------------------ | ------------------ |
| `GET`    | `/accounting/{cid}/invoice`          | List invoices      |
| `GET`    | `/accounting/{cid}/invoice/{id}`     | Get one invoice    |
| `POST`   | `/accounting/{cid}/invoice`          | Create an invoice  |
| `PATCH`  | `/accounting/{cid}/invoice/{id}`     | Update an invoice  |
| `DELETE` | `/accounting/{cid}/invoice/{id}`     | Delete an invoice  |

The same verbs apply to `bill`, `contact`, `account`, `transaction`,
`creditmemo`, `expense`, `taxrate`, and `journal`. Report objects are `GET`-only.

Not every platform supports every object or field — check the **Feature
Support** tab in `app.unified.to`. A `501` response means unsupported.

## Pagination, filtering & sorting

- `limit` (max 100) and `offset` (zero-based).
- `updated_gte=YYYY-MM-DDTHH:MM:SSZ` for incremental sync.
- `sort` (`created_at`, `updated_at`, `name`) + `order` (`asc` / `desc`).

## Example: create and list invoices (fetch)

```javascript
const BASE = 'https://api.unified.to';
const headers = {
    Authorization: `Bearer ${process.env.UNIFIED_API_KEY}`,
    'Content-Type': 'application/json',
};

// Ensure a customer contact exists
const contactRes = await fetch(`${BASE}/accounting/${connectionId}/contact`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
        name: 'Globex Corp',
        emails: [{ email: 'ap@globex.com' }],
        is_customer: true,
    }),
});
const contact = await contactRes.json();

// Create an invoice for that contact
await fetch(`${BASE}/accounting/${connectionId}/invoice`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
        contact_id: contact.id,
        currency: 'USD',
        invoice_number: 'INV-1001',
        lineitems: [
            { description: 'Consulting', quantity: 10, unit_amount: 150 },
        ],
    }),
});

// List recently updated invoices for reconciliation
const invoices = await (
    await fetch(
        `${BASE}/accounting/${connectionId}/invoice?updated_gte=2025-01-01T00:00:00Z&limit=100`,
        { headers }
    )
).json();
```

Field names differ slightly by platform; consult the invoice data model at
https://docs.unified.to/accounting/invoice/model for the canonical fields.

## Example: with the official SDK

```bash
npm install @unified-api/typescript-sdk
```

```typescript
import { UnifiedTo } from '@unified-api/typescript-sdk';

const unified = new UnifiedTo({ security: { jwt: process.env.UNIFIED_API_KEY! } });

const { accountingInvoices } = await unified.accounting.listAccountingInvoices({
    connectionId,
    limit: 100,
});
```

SDKs for Python, PHP, Java, Go, C#, and Ruby: https://docs.unified.to/reference/sdks.

## Keeping data in sync (recommended)

- Register **webhooks** for `invoice`, `bill`, `contact`, and `transaction`
  events, and upsert by `id`. See https://docs.unified.to/reference/webhooks.
- Sync into your own database for reporting and fast, consistent queries.

## Error handling

| Code | Meaning & action                                            |
| ---- | ----------------------------------------------------------- |
| 401  | Connection broken — re-authorize the end-user.              |
| 403  | Missing scopes — fix provider app + Unified.to scopes.      |
| 429  | Provider rate limit — back off; prefer webhook sync.        |
| 501  | Operation unsupported by platform — check Feature Support.  |

## References

- Accounting API overview & data model: https://docs.unified.to/accounting/overview
- Invoice data model: https://docs.unified.to/accounting/invoice/model
- REST basics: https://docs.unified.to/reference/rest
- Pagination & filtering: https://docs.unified.to/reference/pagination
- Source guide: https://docs.unified.to/guides/how_to_build_an_invoicing_system_with_unified
