Accounting API

Unified Accounting API

One integration layer for QuickBooks, Xero, NetSuite, and 50+ accounting systems — so your team ships product features, not bespoke connectors.

Book a 15-minute demo

1. The Problem Every Integration Builder Faces

If you’ve ever connected your business to more than one accounting tool, you know how frustrating it gets. QuickBooks calls something one thing. Xero calls it something else.

Freshbooks has its own name for it. Zoho does too. It’s the same information, just described four different ways by four different companies.

And that’s just one example. This happens across dozens of fields.

Every time you add a new accounting platform, it becomes a whole new headache.

More time, more effort, more things that can go wrong. And the more platforms you support, the more time you spend just trying to make them talk to each other, instead of actually getting things done.

The Unified Accounting API changes that. Rather than forcing you to learn the quirks of every platform you use, it speaks all of them for you quietly, in the background.

You just connect your tools and get on with your work.

Here’s a straightforward comparison of what integration life looks like with and without a unified layer:

✕ Without a Unified API

  • ✕ Separate integration code for every platform
  • ✕ Different field names, types, and formats to handle
  • ✕ Frontend must change with every new integration
  • ✕ Each platform needs its own error handling
  • ✕ Auth flows differ across every system
  • ✕ Maintenance grows with every new platform added

✓ With a Unified API

  • ✓ One integration, all platforms, zero rewrites
  • ✓ Normalized field names across every system
  • ✓ Add new platforms without touching the frontend
  • ✓ Single, centralized error handling layer
  • ✓ One consistent authentication pattern
  • ✓ Scale to new platforms in days, not months

2. Supported Platforms

We currently support six of the most widely used accounting platforms from simple tools that freelancers love, all the way up to the more powerful systems that growing businesses rely on.

Each platform connects through its own dedicated channel, which handles everything behind the scenes logging in on your behalf, making sure your data is read correctly, and presenting it back to you in a consistent, easy-to-understand format.

You don’t need to know how any of that works. You just connect your accounting tool, and everything lines up automatically.

PlatformConnector IDBest FitMarket
XeroxeroSMB / Cloud accountingAU, UK, NZ, US
QuickBooksquickbooksSMB to EnterpriseUS, Global
FreshbooksfreshbooksFreelancers and small businessUS, Global
Zoho BookszohoSMB to mid-marketGlobal
Clear BooksclearbooksUK-focused SMBUK
NetSuitenetsuiteEnterprise ERPGlobal Enterprise

Need MS Dynamics Business Central, Sage Intacct, or SAP? Those are available too, just on one of our extended plans.

3. How It Works: The Architecture

Think of it as a universal translator that sits between your business and your accounting tools.

You ask for something once, and it figures out how to get that information from whichever platform you’re connected to then brings it back to you in a format that always looks the same, no matter where it came from.

Here’s what happens when you make a request:

  1. Your Application – Frontend or backend makes a standard REST call to the Unified API

↓ Request received at Unified API layer

  1. Field Normalizer Validates and maps your request fields to platform-specific format
  2. Platform Router Identifies the connected platform and dispatches to the right connector
  3. Platform Connector Authenticates with the platform, makes the API call, handles errors

↓ Response normalized back to unified schema

  1. Your Application Receives one consistent JSON response – always the same structure

The part that makes this powerful is that each accounting platform has its own dedicated connection.

All the complicated, platform-specific stuff lives there completely out of sight. When we add support for a new platform, nothing on your end needs to change.

Two ways data gets delivered:

  • Right away for things you need instantly, like pulling up an account list or loading an invoice. This typically takes less than two seconds.
  • In the background for bigger jobs, like syncing thousands of transactions at once. We start the job immediately and let you know when it’s done, either through a notification or by letting you check in when you’re ready.

4. Common Model: Chart of Accounts

Your chart of accounts is essentially the backbone of your finances. It’s the master list of every category your business uses to record money coming in, going out, and everything in between.

Get this right, and everything else your invoices, transactions, journal entries falls into place naturally, because they all refer back to it.

When you request account information through our API, you always get it back in the same format, with the same field names regardless of which accounting platform it actually came from.

We handle the translation so you don’t have to think about it.

Field Mapping Reference

The table below shows exactly how each platform names these fields behind the scenes.

You’ll always see our unified field names in your responses this is just so you understand what’s happening under the hood.

A couple of things to keep in mind before you dive in:

  • Fields marked * are required they will always be there in every response, no exceptions.
  • Fields showing simply mean that particular platform doesn’t support that field. It’s not an error, it’s just not something they track.
Unified FieldXeroQuickBooksFreshbooksZoho BooksClear BooksNetSuite
accountId *AccountIDIduuidaccount_idid
accountCode *CodeAcctNumnumberaccount_code
accountName *NameNamenameaccount_nameaccount_name
classificationClassClassification
descriptionDescriptionDescriptiondescriptiondescription
currencyCurrencyCodeCurrencyRef.valuecurrency_code
bankAccountNumberBankAccountNumber
accountTypeTypeAccountTypetypeaccount_typegroup_name
accountSubTypeAccountSubTypesub_type
isBankAccountBankAccountType: BANK
isActiveStatus (Active only)Activestateis_activehidden
modifiedDateUpdatedDateUTCMetaData.LastUpdatedTimeupdated_atlast_modified_time
isSubAccountSubAccountsub_accountsis_child_present
currentBalancecurrentBalancecurrent_balance
parentRef → idParentRef.valueparent_account_id

Note on Xero’s isActive field: Xero’s Status field has three possible values: Active, Archive, and Deleted.

The unified isActive field maps to true only when Status equals ‘Active’. Archive and Deleted accounts are returned as isActive: false.

What Each Platform Actually Supports

Not every accounting platform tracks the same information and that’s okay.

The table below gives you a clear picture of which fields are available on each platform, so you can make smart decisions about what to show your users and what to filter on.

If a field is ticked for a platform, you can count on it being there.

If it’s not, it’s worth having a fallback in mind or simply not surfacing that field for users on that platform.

Unified FieldXeroQuickBooksFreshbooksZohoClear BooksNetSuite
accountId
accountCode
accountName
classification
description
currency
bankAccountNumber
accountType
accountSubType
isBankAccount
isActive
modifiedDate
isSubAccount
currentBalance
parentRef → id

5. API Response: The Account Object

Here’s what a real response looks like when you pull an account. Two things are worth noticing straight away.

GET /api/v1/accounts/{accountId} → 200 OK
{
 "accountId": "acc_7f3a2b14-9c8d-4e1f",
 "accountCode": "1200",
 "accountName": "Trade Debtors / Accounts Receivable",
 "accountType": "CURRENT_ASSET",
 "accountSubType": "AccountsReceivable",
 "classification": "ASSET",
 "description": "Money owed to the business by customers",
 "currency": "USD",
 "isActive": true,
 "isBankAccount": false,
 "isSubAccount": false,
 "currentBalance": 48230.00,
 "parentRef": null,
 "modifiedDate": "2025-04-12T08:33:17Z",
 "_meta": {
 "platform": "xero",
 "rawId": "bd9f2c1a-4518-4c3e-8b72-f190e4a6c3d1",
 "syncedAt": "2025-04-12T08:40:02Z"
 }
}

First, every field name is consistent – it doesn’t matter whether the data came from Xero, QuickBooks, or anywhere else. You always get the same structure back.

Second, see that _meta block at the bottom? That’s where we keep a few handy extras which platform the data came from, the platform’s own internal ID for this record, and the last time we synced it.

Useful when something looks off and you need to trace it back to the source.

One thing worth calling out specifically the _meta.rawId field. If you ever want to send a user directly to a record inside their own accounting platform, that’s the ID you use.

You can build a direct link to a Xero invoice, a QuickBooks account, or anything else without ever having to store platform-specific IDs in your own database.

6. REST Endpoint Reference

All endpoints are relative to the base URL: https://api.synctools.io/accounting/v1

MethodEndpointDescription
GET/accountsList all accounts in the chart of accounts. Supports pagination and modified_after filtering.
GET/accounts/{id}Fetch a single account record by its unified ID.
GET/balance-sheetRetrieve the balance sheet report. Accepts date, currency, and company query parameters.
GET/profit-lossRetrieve the profit & loss statement for a given date range.
GET/transactionsList all transactions. Use modified_after for incremental syncs.
POST/journal-entriesCreate a journal entry. Body accepts the unified JournalEntry model.
GET/tax-ratesList all tax rates available in the connected accounting platform.
GET/contactsList customers and suppliers using the unified Contact model.
GET/invoicesList all invoices. Supports filtering by status, date range, and contact.
GET/paymentsList payment records, including linked invoice references.

Query Parameters

These query parameters work across all list endpoints:

ParameterType / DefaultDescription
modified_afterISO 8601 timestampReturn only records modified after this time. Use for incremental syncs.
pageinteger (default: 1)Page number for paginated results.
page_sizeinteger (default: 100)Number of records per page. Maximum is 500.
expandmodel name stringReturn full nested objects instead of just IDs. E.g. expand=contacts.

7. Appendix: Error Reference

All errors follow a consistent structure regardless of which platform connector generated them.

This means you can write one error handling layer for your entire integration.

HTTP CodeStatusError CodeMeaning
400Bad RequestINVALID_FIELDA required field is missing or has an invalid value.
401UnauthorizedINVALID_TOKENThe API key or account token is missing or expired.
403ForbiddenINSUFFICIENT_SCOPEThe linked account does not have permission for this data.
404Not FoundRECORD_NOT_FOUNDThe requested record does not exist in the platform.
429Too Many RequestsRATE_LIMITEDRate limit exceeded. Check the Retry-After header.
503UnavailablePLATFORM_DOWNThe connected accounting platform is temporarily unavailable.

Ideal for

SaaS platforms adding accounting connectivity to close enterprise deals.
Fintech apps syncing invoices, payments, and customers to a client's books of record.
Product teams that lost a quarter to "Do you integrate with QuickBooks?"

Under the hood

Unified REST API with normalized objects across platforms.
OAuth 2.0 connection flows for QuickBooks Online, Xero, and NetSuite.
Webhooks and scheduled sync for invoices, bills, payments, customers, and chart-of-accounts data.
Production-tested error handling, rate-limit management, and retry logic.

Run this accelerator against your real documents, live, in 15 minutes.

Book a 15-minute demo
← View all accelerators