FlowKit

Connecting n8n to Sage Business Cloud Accounting: syncing invoices and contacts without webhooks

Published 14 August 2026 · 6 min read

A small business that invoices through Sage Business Cloud Accounting usually keeps the rest of its stack separate: quotes come out of another tool, orders arrive by email, and someone re-keys each approved invoice into Sage at the end of the week. Unlike Pennylane or other, newer cloud accounting platforms, Sage didn't build its API around webhooks — so the integration needs a different design from the start. This guide covers OAuth2 authentication, the two most valuable use cases (invoices and contacts), and the polling architecture that stands in for the lack of event notifications.

Identifying the right Sage product first

Sage sells several accounting products under one brand, with very different architectures. This guide is specifically about Sage Business Cloud Accounting (formerly Sage One), which exposes a public REST API at https://api.accounting.sage.com/v3.1, documented on developer.sage.com. Sage 100, an installed product more common among French industrial SMEs, doesn't share this API: its integration goes through other mechanisms (file exports, an ODBC connector) not covered here. Before building anything in n8n, confirm with your accounting team which Sage version is actually in use.

Authentication: OAuth2 with short-lived tokens

The Sage Business Cloud API requires OAuth2, with a detail that often surprises people: the access token expires after just five minutes, versus several hours or days for most accounting APIs. The refresh token stays valid for several weeks but rotates on every use — Sage returns a brand-new refresh token on each refresh, and the old one becomes unusable.

In n8n, this flow is configured with the generic OAuth2 API credential:

  • Authorization URL: https://www.sageone.com/oauth2/auth/central
  • Access Token URL: https://oauth.accounting.sage.com/token
  • Scope: depends on the targeted resources (read and/or write access to invoices, contacts, etc., detailed in Sage's documentation)

n8n natively handles refreshing the access token from the refresh token stored in the credential — the same mechanism covered in our guide to configuring OAuth2 for Google in n8n. The Sage-specific gotcha is refresh token rotation: n8n needs to persist the new refresh token issued on each cycle rather than reusing the old one, or the credential eventually locks itself out after a few refresh cycles. n8n's built-in OAuth2 credential handles this correctly; it only becomes a real trap if you rebuild the token exchange by hand in an HTTP Request node instead of going through the dedicated credential.

One more detail not to miss: every API call must include an X-Business header specifying which Sage company is targeted. A single Sage account can hold several companies, and the API guesses nothing by default — a call without this header (or with the wrong identifier) either fails or, worse, acts on the wrong entity. If you host n8n for multiple clients, see our guide to hosting n8n for a multi-client agency, store this company identifier per client rather than hardcoding it into a single shared workflow.

No webhooks at Sage: building clean polling

Unlike Pennylane (see our guide to connecting the Pennylane API), the Sage Business Cloud Accounting API offers no event notification mechanism at all: there's no way for n8n to learn about a new invoice or an updated contact in real time. The only option is to query the API on a regular schedule — exactly the pattern covered in our guide to intelligent polling without a webhook, directly applicable here:

  1. Schedule Trigger on an interval calibrated to the API's rate limit (2,500 requests per day per company, 100 per minute — plenty for a small business, but worth watching if several workflows poll the same company in parallel).
  2. HTTP Request to the relevant endpoint, filtered server-side rather than fetched in full — our guide to pagination with the HTTP Request node covers the multi-page retrieval mechanics that Sage's API also uses for its list endpoints.
  3. A cursor stored via $getWorkflowStaticData() (see our dedicated guide) that remembers the last sync timestamp, reused on the next run to fetch only records modified since.
  4. A defensive filter before any processing, following the same principle laid out in our guide to idempotency, so the same invoice is never processed twice if two runs happen to overlap.

Use case 1 — Pushing a customer invoice generated by n8n

If your quotes and invoices are already generated by n8n — see our guide to generating invoice PDFs — the natural next step is recording that same invoice on the accounting side without re-typing it. The API exposes dedicated resources for contacts and sales invoices: a POST call with the contact, line items, applicable VAT, and payment terms creates the invoice directly in Sage, right after the workflow that produced the PDF sent to the customer. The Edit Fields (Set) node that already builds the PDF payload becomes the base for this second JSON payload, with no additional manual entry.

Use case 2 — Syncing contacts without duplicates

Creating a contact in Sage on every new invoice, with no prior check, quickly produces dozens of duplicate contacts for the same company (spelling variants, casing, stray spaces). Before any POST on contacts, a GET call filtered by name or VAT/registration number lets you check whether the contact already exists and retrieve its ID instead of recreating one — the same lookup-before-write discipline recommended in our guide to n8n webhooks and avoiding duplicates, applied here to a simple read before a write.

What the research says about accounting automation in SMEs

Wiring an ERP or CRM into a small business's cloud accounting isn't just an automation engineer's hunch. A 2023 study by Abedrabbo Rawashdeh published in Human Behavior and Emerging Technologies (see on Google Scholar), examining the determinants of cloud accounting adoption in SMEs, finds that technological readiness and management support matter more than company size in whether such a project succeeds — a useful reminder that the hard part isn't picking the right accounting software, it's actually connecting it to the rest of the information system instead of leaving it running in a silo.

Common pitfalls

  • Forgetting the X-Business header on a multi-company account: the call can fail silently or hit the wrong entity.
  • Reimplementing the OAuth2 flow by hand in an HTTP Request node instead of using n8n's native OAuth2 API credential, which handles refreshing and refresh-token rotation on its own.
  • Querying the API with no server-side filter, in a "fetch everything then filter in n8n" style: with a 2,500-request-per-day cap, that habit burns through the useful quota within a few pages.
  • Not throttling bulk imports (catching up on a month of archives): our guide to API rate limits covers spacing out calls with a Loop Over Items node instead of firing the whole queue at once.

Going further

This connection closes the loop between document workflows already in place — quote generation, AI-based invoice PDF extraction — and the accounting tool that receives them. If you also need an audit trail for every entry pushed to Sage (who sent what, when, with what result), the Compliance & Audit Pack (€149) provides the logging building block, ready to wire in alongside these API calls. If supplier invoices first arrive by email before any processing, the Inbox AI Pack (€79) handles the initial mailbox sorting. All three packs, bundled in the Complete FlowKit Bundle (€269 instead of €347 bought separately), cover the whole document journey, from receipt to the accounting entry.

FAQ

Frequently asked questions

Do Sage Business Cloud Accounting and Sage 100 use the same API?

No. This guide covers the REST API v3.1 of Sage Business Cloud Accounting (the cloud product, formerly Sage One). Sage 100 is an installed piece of software with a different architecture and different integration paths (file exports, a dedicated connector) that fall outside the scope of this article. Check on developer.sage.com which Sage product your company actually runs before starting.

Why does n8n show an authorization error after just a few minutes of use?

Sage API access tokens have a very short lifetime, around five minutes. That's expected: n8n's OAuth2 credential should refresh the access token automatically on every expired call, using the refresh token. If the error persists beyond a simple refresh, check that the refresh token itself hasn't expired (its lifetime is measured in weeks, not minutes) or been invalidated by a concurrent refresh from another tool.

Do I need to re-authenticate for every company managed inside Sage?

The access token obtained via OAuth2 is tied to the user who signed in, but every API call must still specify the target company through a dedicated header. If you manage several client ledgers from the same n8n instance, store that company identifier per client rather than hardcoding it in the workflow, so the same credential can be reused across accounts.

Does the Sage API offer a test environment before touching real data?

Sage provides developer access with dedicated application credentials, requested on developer.sage.com, but it doesn't work like a fully isolated sandbox the way some other accounting vendors offer. Test your first calls read-only (GET) against a real account before enabling any write, and limit your first write tests to a contact or invoice that's clearly identifiable as a test.

Bundle FlowKit Complet

€269