Skip to main content

QuickBooks Online

Read and write one QuickBooks Online company - invoices, customers, bills, payments, items and accounts - with QuickBooks' own query language and reports.

Connect a QuickBooks Online company to work its ledger end to end: query any entity with QuickBooks' SELECT syntax, count matches with COUNT(*), read a record with the SyncToken a write needs, create and update entities (sparse by default), delete or void transactions, email invoices and estimates to customers, and run QuickBooks' own reports - P&L, balance sheet, cash flow, trial balance, aged receivables and payables. Counts come from the database rather than from measuring a page, and the difference between deleting, voiding and deactivating is treated as the accounting decision it is.

Connect

Sign in with Intuit. Sign in with Intuit to read and write one QuickBooks Online company file. An organization admin configures the OAuth app once under Integrations → OAuth apps; after that, connecting is a consent screen.

  • Connecting signs in as YOU and grants access to the ONE company you pick on Intuit's consent screen - every ledger entry this integration writes is stamped with that account.

  • After connecting, set Company ID on the connection. Intuit hands the company (realm) id back on the sign-in redirect, which this platform's generic OAuth broker does not keep, and no API lists the companies a token can reach. Find it in QuickBooks under Settings → Account and settings → Billing & subscription → Company ID, and remove the spaces.

  • Set Environment to sandbox only when the connection points at an Intuit developer sandbox company. Sandbox and production are different hosts, and using the wrong one fails as a plain 401 that says nothing about environments.

  • Intuit refresh tokens rotate on every use and expire after 100 days of inactivity. A connection nothing has run for over three months has to be reconnected - that is Intuit's rule, not a setting.

  • For scheduled or triggered automations, connect a dedicated QuickBooks user and bind the automation as a service connection: an automation cannot run as whoever happened to start it.

SettingRequiredWhat it is
Company ID (COMPANY_ID)NoThe QuickBooks company (realm) id every API path is built around - Settings → Account and settings → Billing & subscription → Company ID, without the spaces. Set it after connecting: Intuit sends it on the sign-in redirect, which the OAuth broker does not store, and no API can be asked for it.
Environment (ENVIRONMENT)NoWhich Intuit deployment this company lives in - production or sandbox. Empty means production. Sandbox companies are served from a different host, and mixing them up fails as an ordinary 401.

Tools

ToolAccessWhat it does
Get company info (yekar.quickbooks-online.get-company-info)ReadThe company file this connection actually reaches - its name, country, fiscal year start and the API host in use. Also the cheapest way to prove the sign-in, the Company ID and the Environment agree: it is the one call that fails specifically when they do not, before a write is at stake.
List entities (yekar.quickbooks-online.list-entities)ReadA page of records of any QuickBooks entity - invoices, customers, items, payments, bills, accounts - filtered with a WHERE clause and sorted with ORDERBY. Paging is 1-based STARTPOSITION plus MAXRESULTS; there is no cursor and no total, so a full page means there may be more. Use Count entities to count and Run report for figures QuickBooks computes itself.
Count entities (yekar.quickbooks-online.count-entities)ReadHow many records match a condition, counted by QuickBooks itself with SELECT COUNT(*). This is the only QuickBooks read that returns a true total - a List entities page reports how many rows it returned and nothing about how many exist. Pass the same WHERE clause as the list it summarizes.
Query (yekar.quickbooks-online.query)ReadRun a QuickBooks SELECT statement directly - the escape hatch for reads List entities cannot express. Reads only: QuickBooks' query language has no writes at all. Watch the differences from SQL: no JOIN, no OR, no aggregates other than COUNT(*), ORDERBY as one word, and STARTPOSITION/MAXRESULTS instead of LIMIT/OFFSET.
Get entity (yekar.quickbooks-online.get-entity)ReadRead one record by id, with its CURRENT SyncToken. Always the first half of an update: QuickBooks refuses a write carrying a stale SyncToken, so the value returned here is what the matching Update entity, Delete entity or Void transaction call must send back.
Create entity (yekar.quickbooks-online.create-entity)WriteCreate one QuickBooks record - an invoice, customer, item, payment, bill, vendor, journal entry. QuickBooks validates the whole object, so a rejected create changes nothing at all. NOT idempotent: calling twice creates two records, and QuickBooks offers no idempotency key, so a retry after an unclear failure should re-read before resending.
Update entity (yekar.quickbooks-online.update-entity)WriteUpdate one QuickBooks record. Sparse by default, so only the fields sent change; a full (non-sparse) update CLEARS everything omitted, which is how invoice lines get silently wiped. Requires the current SyncToken from a fresh read - a stale one is refused as a conflict rather than applied. Deactivating a customer, vendor, item or account is this tool with Active: false; QuickBooks has no delete for those.
Delete entity (yekar.quickbooks-online.delete-entity)WritePermanently delete one QuickBooks TRANSACTION - an invoice, bill, payment, journal entry. It is removed from the ledger and cannot be undone through the API; voiding instead keeps the document and its number at zero value, which is usually what an accountant wants. Name-list records (customers, vendors, items, accounts) cannot be deleted at all - deactivate them with Update entity and Active: false.
Void transaction (yekar.quickbooks-online.void-transaction)WriteVoid a transaction: QuickBooks zeroes its amounts, stamps the memo 'Voided.' and keeps the document and its number in the ledger. This is the reversal an audit trail expects - deleting removes the record and its number entirely. Voiding cannot be undone through the API; the transaction has to be recreated.
Send transaction (yekar.quickbooks-online.send-transaction)WriteEmail an invoice, estimate, sales receipt, credit memo, refund receipt or purchase order to its customer or vendor, as a PDF from QuickBooks' own mail service. This SENDS: the mail leaves immediately and cannot be recalled, and QuickBooks marks the document EmailSent. Put an approval gate in front of it in any automation whose recipient comes from a model.
Run report (yekar.quickbooks-online.run-report)ReadRun one of QuickBooks' own reports - P&L, balance sheet, cash flow, trial balance, aged receivables/payables, sales by customer or product - for a period, and get it back as flat rows with their nesting depth. These are the numbers QuickBooks itself computes, which is why they are worth more than summing query rows: the ledger's own rules about accounting method, sub-accounts and periods are already applied.

Notes

  • Sign in with Intuit and pick the company on the consent screen - every entry this integration writes is stamped with the QuickBooks user who signed in, and their role is the ceiling on what it can do.
  • Then set Company ID on this connection: Intuit returns the company (realm) id on the sign-in redirect, which this platform's generic OAuth broker does not keep, and no API lists the companies a token can reach. Find it in QuickBooks under Settings → Account and settings → Billing & subscription → Company ID and remove the spaces.
  • Leave Environment empty for a real company. Set it to sandbox only for an Intuit developer sandbox - the two are different API hosts (production, sandbox), and the wrong one fails as a plain 401 that mentions neither.
  • Updating a record needs the SyncToken from a CURRENT read: read with Get entity, change what you need, send it back with that token. If something else changed the record in between, QuickBooks refuses the write rather than overwriting - re-read and reapply.
  • Update entity is sparse by default, changing only the fields you send. A full (sparse: false) update clears everything you omit, including invoice lines.
  • Customers, vendors, items and accounts cannot be deleted - only deactivated (Update entity with Active: false). Their names stay unique against deactivated records too, so re-creating one fails as a duplicate; reactivate instead.
  • Deleting a transaction removes it from the ledger; voiding keeps the document and its number at zero. Voiding is usually what an accountant expects, and neither can be undone through the API.
  • Send transaction emails a real document to a real customer through QuickBooks' mail service, immediately and irreversibly. Put an approval gate in front of it whenever the recipient comes from a model.
  • Intuit refresh tokens rotate on every use and die after 100 days of inactivity, so a connection nothing has run for three months needs reconnecting.