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.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:
finance/quickbooks/query). The query is placed in the URL, so URL-encode it. This asks for inventory items:
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:
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):
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: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 canPOST 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
STARTPOSITIONandMAXRESULTS, for exampleselect * from Item STARTPOSITION 1001 MAXRESULTS 1000. - Common errors: 401 code
3200(expired or invalid token), 403 code3100(the app is not connected to thatrealm_id), 400ValidationFaultwith codes such as2500(invalid reference),6000(business rule),6240(duplicate name),5010(staleSyncToken). - 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).

