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.