Skip to main content
Technical Preview

Overview

A client-mode connector for the QuickBooks Online Accounting API (v3). Use it to close the loop between the shop floor and accounting: bill a customer when a batch ships, write scrap or consumption back as an inventory quantity adjustment, and read item stock levels or recent changes into MQTT. The file holds two connectors. QuickBooksOnlineRestApi talks to the accounting API, and QuickBooksOnlineOAuth refreshes the OAuth access token on Intuit’s token host. Every accounting call adds minorversion=75. Since August 2025 QuickBooks ignores minor versions 1 to 74 and answers as 75, so the template pins the current base. Set BASE_ADDRESS to https://quickbooks.api.intuit.com for real companies or https://sandbox-quickbooks.api.intuit.com for sandbox companies. Topics use finance/quickbooks/<object>/<verb>; replies land on <topic>/response. See the base guide: REST API Connectors.
Auth: QuickBooks Online uses OAuth 2.0 authorization code with the com.intuit.quickbooks.accounting scope. Do the one-time consent outside the broker (the Intuit OAuth 2.0 Playground or your own app) to get a refresh token and the company’s realmId. After that the broker can stay connected on its own: publish to the RefreshToken event to get a fresh access token (valid 60 minutes) and send it as access_token with realm_id on every accounting call. Keep the client id, client secret and refresh token in Hub secrets (suggested names QBO_CLIENT_ID, QBO_CLIENT_SECRET, QBO_REFRESH_TOKEN, QBO_REALM_ID). Never commit them into the .lot.
The refresh token rotates. The token response can return a new refresh_token, and the old one stops working soon after. Always store the latest value. A refresh token that is not used for about 100 days expires, and the user has to reconnect.

Basic Syntax

MQTT examples

Control fields (access_token, realm_id, ids, query, dates) only fill the URL and headers. Only body is sent as the request body. RefreshToken (finance/quickbooks/oauth/refresh). basic_auth is the Base64 of client_id:client_secret. Expect 200:
Response:
Query (finance/quickbooks/query). The query is placed in the URL, so URL-encode it. This asks for inventory items:
Response (trimmed):
CreateInventoryAdjustment (finance/quickbooks/inventoryadjustment/create). Writes scrap back to stock: two units off item 11, posted to the adjustment account 91. Expect 200 with the new InventoryAdjustment:
Use a positive QtyDiff to add stock. Inventory adjustments need QuickBooks Online Plus or Advanced with quantity tracking turned on, and the item must be an Inventory item. CreateInvoice (finance/quickbooks/invoice/create), expect 200 with the new Invoice (Id, DocNumber, TotalAmt):
SendInvoice (finance/quickbooks/invoice/send) takes invoice_id and a URL-encoded send_to address, for example "send_to": "ap%40customer.example". The body is empty. Updates. QuickBooks updates are sparse POSTs to the create endpoint. Send the entity’s Id, its current SyncToken and "sparse": true together with the fields to change. An old SyncToken returns 400 with code 5010; read the entity again and retry.

Keeping the token

A small action can keep the latest tokens when the refresh reply arrives:
Refresh before the access token expires (for example every 50 minutes), or when a call returns 401 with code 3200. Restrict who can read the finance/quickbooks/# topics with a rule, because these payloads carry tokens and client credentials.

Webhooks (companion, not packaged)

QuickBooks webhooks can POST entity-change notifications (for example Invoice, Item or Payment created or updated) to an HTTPS URL. Each request carries an intuit-signature header, an HMAC-SHA256 of the body with your app’s verifier token, which the receiver should check. Receiving them needs a separate ENABLE_SERVER REST API connector on a publicly reachable HTTPS address. That companion connector is not part of this template. Change data capture (ChangeDataCapture) is the polling alternative.

Notes

  • Limits: 500 requests per minute and 10 concurrent requests per company and app; a batch holds at most 30 operations, with 40 batch calls per minute. Above that QuickBooks answers 429.
  • A query returns at most 1000 rows. Page with STARTPOSITION and MAXRESULTS, for example select * from Item STARTPOSITION 1001 MAXRESULTS 1000.
  • Common errors: 401 code 3200 (expired or invalid token), 403 code 3100 (the app is not connected to that realm_id), 400 ValidationFault with codes such as 2500 (invalid reference), 6000 (business rule), 6240 (duplicate name), 5010 (stale SyncToken).
  • Sandbox and production use different hosts and different companies. A sandbox token does not work on quickbooks.api.intuit.com.
  • Not covered: invoice PDF download (binary), attachments (multipart upload), the Payments and Payroll APIs, and token revoke (POST https://developer.api.intuit.com/v2/oauth2/tokens/revoke).
  • Suggested branches: feat/rest-api-route-quickbooks-online, feat/docs-rest-api-quickbooks-online (Hugo pushes).
Last modified on October 21, 2026