Skip to main content

QuickBooks Online ExecModule

Overview

QuickBooksOnlineModule connects ValkyrAI workflows to the QuickBooks Online Accounting API through the native map I/O ExecModule ABI. Workflow Studio discovers it as QuickBooksOnlineModule; the OAuth access token and numeric QuickBooks company realm ID resolve only from an encrypted IntegrationAccount.

The first production operation set focuses on the accounting path from customer to receivable to payment:

  • get_company_info
  • list_customers, get_customer, create_customer, update_customer
  • list_invoices, get_invoice, create_invoice, update_invoice, send_invoice
  • list_payments, get_payment, create_payment

QuickBooks query pagination is numeric and bounded. Only GET requests retry automatically. Customer, invoice, payment, and delivery writes run once so an ambiguous timeout cannot duplicate or resend financial activity.

Usage

  1. Create an Intuit application and authorize the com.intuit.quickbooks.accounting scope.
  2. Store the current OAuth access token in the encrypted apiKey field of an IntegrationAccount.
  3. Store the numeric QuickBooks company realm ID in IntegrationAccount.accountId and set status to READY.
  4. Bind that account through ExecModuleConfig.authConfig.integrationAccount.
  5. Use get_company_info to verify the intended company before financial mutations.
  6. Read the latest resource and retain its SyncToken before an update.
  7. Reconcile QuickBooks state before repeating any write after an ambiguous connection failure.

Workflow input cannot provide an OAuth token, realm ID, or arbitrary endpoint. The module routes only to the fixed production or sandbox QuickBooks Online hosts.

Inputs

NameTypeRequirementDefaultDescription and constraints
operationstringRequiredNoneOne of the 13 documented operations.
resourceIdstringGet, update, and send operationsNoneNumeric QuickBooks entity ID, maximum 32 digits.
syncTokenstringCustomer/invoice updateNoneNumeric optimistic-concurrency token from the latest entity read.
customerobject or JSON stringCustomer create/updateNoneAllowlisted customer fields, 512 KiB maximum.
invoiceobject or JSON stringInvoice create/updateNoneAllowlisted invoice fields and 1–1,000 lines, 512 KiB maximum.
paymentobject or JSON stringPayment createNoneAllowlisted payment fields; positive amount and optional linked-transaction lines.
emailstringsend_invoiceNoneValid bounded recipient address, maximum 254 characters.
environmentstringOptionalproductionproduction or sandbox; maps to a fixed Intuit host.
minorVersionintegerOptional75QuickBooks Accounting API minor version from 75 through 999.
startPositionintegerOptional list continuation1One-based query start position.
limitintegerOptional100Maximum emitted resources, 1–10,000.
returnAllbooleanOptionalfalseContinue 1,000-record query pages until exhaustion or the result cap.

Customer payloads accept only DisplayName, GivenName, MiddleName, FamilyName, CompanyName, PrimaryEmailAddr, PrimaryPhone, BillAddr, ShipAddr, Notes, Taxable, PreferredDeliveryMethod, CurrencyRef, ParentRef, Job, and Active.

Invoice payloads accept only CustomerRef, Line, TxnDate, DueDate, DocNumber, PrivateNote, CustomerMemo, BillEmail, BillEmailCc, BillEmailBcc, SalesTermRef, DepositToAccountRef, CurrencyRef, ExchangeRate, DepartmentRef, ClassRef, TxnTaxDetail, ApplyTaxAfterDiscount, PrintStatus, EmailStatus, AllowOnlineACHPayment, and AllowOnlineCreditCardPayment.

Payment payloads accept only CustomerRef, TotalAmt, Line, TxnDate, PaymentMethodRef, DepositToAccountRef, PaymentRefNum, PrivateNote, CurrencyRef, ExchangeRate, ARAccountRef, and TxnSource.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation name.
attemptsintegerAlwaysProvider attempts across all pages.
httpStatusintegerProvider respondedLast QuickBooks HTTP status.
dataobjectSingle-resource/write successProvider company, customer, invoice, or payment.
Id, SyncToken, DocNumberstringProvider returns fieldSafe convenience identity fields.
items / countarray / integerList successBounded entity results and emitted count.
hasMorebooleanList successWhether another numeric query page may exist.
nextStartPositionintegerAnother page may existOne-based continuation position.
requestIdstringIntuit returns oneSafe intuit_tid or request trace reference.
errorobjectFailureSafe {code, message, httpStatus?, retryable} details.

OAuth tokens and authorization headers never enter outputs. Provider messages pass through ValkyrAI's workflow sensitive-data policy.

IntegrationAccount Requirements

SettingRequirement
ProviderIntuit QuickBooks Online OAuth 2.0 application
Scopecom.intuit.quickbooks.accounting
accountIdNumeric company realm ID returned by Intuit OAuth
apiKeyCurrent OAuth access token in an encrypted SecureField
passwordLegacy encrypted token fallback only; prefer apiKey
statusREADY or legacy unset status; CLOSED and ERROR fail closed

OAuth authorization-code exchange, refresh-token storage, token refresh, revocation, and rotation belong to the platform integration-account lifecycle. Workflow inputs never handle OAuth secrets.

Configuration

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:quickbooks-revenue-ops"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_invoices\",\"environment\":\"production\",\"limit\":100}"
}
}

The integration-account value is symbolic. Persisted workflows use the generated relationship rather than a plaintext token or realm identifier.

Operations

OperationQuickBooks behaviorSide effect
get_company_infoReads the bound company profile.Read-only; safe retries.
list_customersRuns a bounded Customer query.Read-only; safe retries.
get_customerReads one customer by numeric ID.Read-only; safe retries.
create_customerCreates one allowlisted customer; DisplayName is required.New accounting entity; single attempt.
update_customerApplies a sparse update with caller-supplied Id and SyncToken.Accounting mutation; single attempt.
list_invoicesRuns a bounded Invoice query.Read-only; safe retries.
get_invoiceReads one invoice by numeric ID.Read-only; safe retries.
create_invoiceCreates one customer invoice with bounded lines.New receivable; single attempt.
update_invoiceApplies a sparse invoice update with explicit concurrency token.Financial mutation; single attempt.
send_invoiceSends one invoice to the validated email recipient.External delivery; single attempt.
list_paymentsRuns a bounded Payment query.Read-only; safe retries.
get_paymentReads one payment by numeric ID.Read-only; safe retries.
create_paymentRecords a positive customer payment and optional invoice links.Financial mutation; single attempt.

Errors and Failure Modes

CodeTypical causeRetryableResolution
VALIDATION_ERRORMissing/invalid realm, ID, token, email, payload, reference, line, or pagination bound.NoCorrect input; no unsafe request was sent.
UNSUPPORTED_OPERATIONUnknown operation.NoSelect a documented operation.
INTEGRATION_ACCOUNT_REQUIREDNo bound account.NoBind a QuickBooks IntegrationAccount.
INTEGRATION_ACCOUNT_NOT_READYAccount is closed/error.NoRepair or reconnect the account.
QUICKBOOKS_HTTP_400Intuit rejected an entity field or Accounting API rule.NoInspect the safe fault detail and correct the request.
QUICKBOOKS_HTTP_401 / 403Access token invalid/expired or scope/company access missing.NoRefresh/re-authorize the IntegrationAccount.
QUICKBOOKS_HTTP_404Entity is absent or invisible in the bound realm.NoRe-read/list with the same account and realm.
QUICKBOOKS_HTTP_409Stale SyncToken or business-rule conflict.NoRead the current entity and rebuild the update.
QUICKBOOKS_HTTP_429 / 5xxRate limit or transient provider failure.Yes for readsHonor Retry-After; reconcile writes before repeating them.
NETWORK_ERRORTimeout, DNS, TLS, or connectivity failure.Yes for readsVerify connectivity and provider state.
RESPONSE_TOO_LARGEResponse exceeded 5 MiB.NoLower the limit or split the query.
INVALID_PROVIDER_RESPONSEExpected entity or query array was absent/invalid.NoUse requestId to verify provider/API compatibility.

Example

Create one approved invoice:

{
"operation": "create_invoice",
"invoice": {
"CustomerRef": {"value": "42"},
"TxnDate": "2026-08-08",
"DueDate": "2026-09-07",
"PrivateNote": "ValkyrAI workflow milestone valkyr-4404",
"Line": [
{
"Amount": 250,
"DetailType": "SalesItemLineDetail",
"Description": "Workflow automation milestone",
"SalesItemLineDetail": {
"ItemRef": {"value": "7"},
"Qty": 1,
"UnitPrice": 250
}
}
]
}
}

Expected result:

{
"status": "success",
"operation": "create_invoice",
"attempts": 1,
"httpStatus": 200,
"Id": "145",
"SyncToken": "0",
"DocNumber": "1001",
"data": {
"Id": "145",
"SyncToken": "0",
"DocNumber": "1001"
}
}

Notes

  • Pagination: list operations generate only SELECT * FROM <allowlisted entity> STARTPOSITION n MAXRESULTS m. Provider-returned URLs and arbitrary caller SQL are never followed or executed. Pages are capped at 1,000 items and total output at 10,000.
  • Rate limits: reads retry HTTP 408, 429, 500, 502, 503, and 504 according to RetryPolicy, honoring numeric Retry-After. Writes never retry automatically.
  • API limits: provider responses are capped at 5 MiB, structured payloads at 512 KiB, and invoice/payment line arrays at 1,000 entries.
  • Minor versions: the default is 75 because Intuit discontinued minor versions 1–74. Change it only after validating the target schema and compatibility.
  • Idempotency: creates, updates, payment recording, and invoice delivery are single-attempt. Use caller-owned DocNumber, PaymentRefNum, or workflow correlation fields where appropriate and reconcile provider state after ambiguous failures.
  • Concurrency: updates require the latest SyncToken; the module never hides a preliminary provider read inside a financial mutation.
  • Destructive behavior: this release exposes no delete, void, refund, credit memo, bill-payment, or transaction-journal operations. Customer deactivation is an explicit sparse update and remains subject to QuickBooks rules.
  • API behavior: QuickBooks can apply company preferences, taxes, multicurrency, custom transaction numbers, rounding, and linked-transaction rules beyond local structural validation.
  • Security: credentials remain in IntegrationAccount SecureFields. Fixed-host routing, numeric realm/ID validation, allowlisted entity fields, bounded responses, and redacted fault details prevent arbitrary routing or token reflection.
  • External verification: request construction, query pagination, validation, concurrency fields, retry safety, redaction, response mapping, and metadata discovery have deterministic local tests. Live Intuit OAuth scopes, company preferences, taxation, email delivery, rate limits, and accounting effects require separately authorized provider credentials and are not exercised in repository tests.
  • Deferred operations: vendors, bills, purchases, estimates, items, employees, reports, attachments, PDFs, batch requests, CDC, webhooks/triggers, refunds, credit memos, deposits, journal entries, OAuth refresh, arbitrary queries, and destructive operations.
  • Functional references: n8n QuickBooks node source, Intuit Accounting API, and Intuit minor versions.