Collect QuickBooks Online data into your data warehouse
The QuickBooks connector loads accounts, customers, vendors, every sales and purchase transaction and dated financial report snapshots into your own data warehouse, so the books sit next to orders and ad spend.
- 0.41.0Dates from Google Sheets arrive as dates, not text
- 0.41.0Rotating a connector key is one change: Sources share reusable Credentials
- 0.40.0Connecting a plan from Google Sheets takes fewer guesses
- 0.39.0Reload a year of history in one backfill, not twelve
- 0.39.0Long Facebook Ads imports no longer fail on a corrupted response
QuickBooks Endpoints
26 QuickBooks endpoints you can import. Each lands in its own table in your data warehouse.
A/P Aging Summary report
A/P Aging Summary as of report_date (window end): one row per vendor with aging buckets.
11 fieldsTime seriesA/R Aging Summary report
A/R Aging Summary as of report_date (window end): one row per customer with Current, 1-30, 31-60, 61-90, 91+ and Total columns.
11 fieldsTime seriesAccounts
Chart of accounts, active and inactive.
20 fieldsBalance Sheet report
Balance Sheet as of the run window end (Assets, Liabilities, Equity by account).
12 fieldsTime seriesBill payments
Payments against vendor bills; joins to Bill through Line[].LinkedTxn.
23 fieldsBills
Vendor bills (payables).
25 fieldsCash Flow report
Statement of Cash Flows for the run window.
12 fieldsTime seriesCompany info
One row per company: names, country, fiscal-year start.
15 fieldsCredit memos
Credits issued to customers (reduce receivables; negative revenue in reconciliations).
23 fieldsCustomers
Customers, including inactive ones and sub-customers, with open balance and a flattened billing address.
28 fieldsDeposits
Bank deposits, including the ones that group undeposited customer payments.
21 fieldsGeneral Ledger Detail report
General Ledger: every posting line per account for the run window, with opening balance and totals.
12 fieldsTime seriesInvoice changes (CDC, incl. deletes)
Change data capture for Invoice: every invoice created, updated or deleted since the run window start, full payload, deleted ones with status = Deleted.
9 fieldsTime seriesInvoices
Invoices with header amounts, customer and Line[] as JSON (SalesItemLineDetail.ItemRef, Qty, UnitPrice, Amount).
36 fieldsItems
Products and services with price, purchase cost and the three account links.
25 fieldsJournal entries
Manual and adjusting journal entries; the postings the transaction tables miss.
15 fieldsPayments
Customer payments.
21 fieldsPreferences
One row per company: home currency, multi-currency flag, fiscal-year and tracking settings.
17 fieldsProfit and Loss report
Profit and Loss per run window, one column per month (summarize_column_by=Month), rows nested by account group.
12 fieldsTime seriesPurchases
Expenses paid directly (cash, check, card) without a bill.
26 fieldsRefund receipts
Money refunded to customers.
26 fieldsSales by Customer report
Sales by Customer Summary for the run window.
12 fieldsTime seriesSales receipts
Sales paid at the time of sale (no receivable).
27 fieldsTransfers
Money moved between balance-sheet accounts.
16 fieldsVendor Expenses report
Expenses by Vendor for the run window.
12 fieldsTime seriesVendors
Vendors, including inactive ones, with open payable balance.
19 fields
A/P Aging Summary report schema
QuickBooks A/P Aging Summary report schema
11 fieldsTime seriesquickbooks_report_aged_payables
A/P Aging Summary as of report_date (window end): one row per vendor with aging buckets.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
A/R Aging Summary report schema
QuickBooks A/R Aging Summary report schema
11 fieldsTime seriesquickbooks_report_aged_receivables
A/R Aging Summary as of report_date (window end): one row per customer with Current, 1-30, 31-60, 61-90, 91+ and Total columns.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Accounts schema
20 fieldsquickbooks_account
Chart of accounts, active and inactive.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
name | STRING | |
fully_qualified_name | STRING | Parent:Child path for sub-accounts. |
account_type | STRING | Bank, Accounts Receivable, Expense, Income, Credit Card… |
account_sub_type | STRING | |
classification | STRING | Asset, Liability, Equity, Revenue, Expense. |
acct_num | STRING | |
current_balance | FLOAT | |
current_balance_with_sub_accounts | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
sub_account | BOOLEAN | |
parent_id | STRING | |
parent_name | STRING | |
description | STRING | |
active | BOOLEAN |
QuickBooks Balance Sheet report schema
12 fieldsTime seriesquickbooks_report_balance_sheet
Balance Sheet as of the run window end (Assets, Liabilities, Equity by account).
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Bill payments schema
23 fieldsquickbooks_bill_payment
Payments against vendor bills; joins to Bill through Line[].LinkedTxn.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
pay_type | STRING | Check or CreditCard. |
vendor_id | STRING | |
vendor_name | STRING | |
ap_account_id | STRING | |
ap_account_name | STRING | |
check_bank_account_id | STRING | |
check_bank_account_name | STRING | |
check_print_status | STRING | |
credit_card_account_id | STRING | |
credit_card_account_name | STRING | |
line | JSON | Line\[\] as JSON; LinkedTxn\[\] {TxnId, TxnType=Bill} names the bills settled. |
QuickBooks Bills schema
25 fieldsquickbooks_bill
Vendor bills (payables).
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line\[\] as JSON; DetailType is AccountBasedExpenseLineDetail (AccountRef) or ItemBasedExpenseLineDetail (ItemRef). |
due_date | DATE | |
balance | FLOAT | |
vendor_id | STRING | |
vendor_name | STRING | |
ap_account_id | STRING | |
ap_account_name | STRING | |
sales_term_id | STRING | |
sales_term_name | STRING | |
department_id | STRING | |
department_name | STRING | |
linked_txn | JSON | |
home_balance | FLOAT |
QuickBooks Cash Flow report schema
12 fieldsTime seriesquickbooks_report_cash_flow
Statement of Cash Flows for the run window.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Company info schema
15 fieldsquickbooks_company_info
One row per company: names, country, fiscal-year start.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
company_name | STRING | |
legal_name | STRING | |
country | STRING | |
company_start_date | DATE | |
fiscal_year_start_month | STRING | |
email | STRING | |
company_addr_country | STRING | |
company_addr | JSON | |
supported_languages | STRING | |
name_value | JSON | Extra settings as Name/Value pairs (industry type, subscription status…). |
QuickBooks Credit memos schema
23 fieldsquickbooks_credit_memo
Credits issued to customers (reduce receivables; negative revenue in reconciliations).
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line array kept as JSON. Unnest in SQL: DetailType decides which \*LineDetail object is present. |
remaining_credit | FLOAT | |
balance | FLOAT | |
customer_id | STRING | |
customer_name | STRING | |
class_id | STRING | |
class_name | STRING | |
department_id | STRING | |
department_name | STRING | |
total_tax | FLOAT | |
home_total_amt | FLOAT |
QuickBooks Customers schema
28 fieldsquickbooks_customer
Customers, including inactive ones and sub-customers, with open balance and a flattened billing address.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
display_name | STRING | |
company_name | STRING | |
given_name | STRING | |
family_name | STRING | |
primary_email | STRING | |
primary_phone | STRING | |
balance | FLOAT | Open A/R balance for the customer. |
balance_with_jobs | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
taxable | BOOLEAN | |
job | BOOLEAN | True for sub-customers (projects). |
parent_id | STRING | |
parent_name | STRING | |
payment_method_id | STRING | |
payment_method_name | STRING | |
sales_term_id | STRING | |
sales_term_name | STRING | |
bill_addr_city | STRING | |
bill_addr_country | STRING | |
bill_addr_postal_code | STRING | |
bill_addr | JSON | Full billing address as JSON. |
active | BOOLEAN |
QuickBooks Deposits schema
21 fieldsquickbooks_deposit
Bank deposits, including the ones that group undeposited customer payments.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line\[\] as JSON; lines either link received Payments (LinkedTxn) or post directly (DepositLineDetail.AccountRef, Entity). |
deposit_to_account_id | STRING | |
deposit_to_account_name | STRING | |
cash_back_amount | FLOAT | |
cash_back_account_id | STRING | |
cash_back_account_name | STRING | |
department_id | STRING | |
department_name | STRING | |
home_total_amt | FLOAT |
General Ledger Detail report schema
QuickBooks General Ledger Detail report schema
12 fieldsTime seriesquickbooks_report_general_ledger_detail
General Ledger: every posting line per account for the run window, with opening balance and totals.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
Invoice changes (CDC, incl. deletes) schema
QuickBooks Invoice changes (CDC, incl. deletes) schema
9 fieldsTime seriesquickbooks_cdc_invoice
Change data capture for Invoice: every invoice created, updated or deleted since the run window start, full payload, deleted ones with status = Deleted.
| Field | Type | Description |
|---|---|---|
id | STRING | |
realm_id | STRING | |
entity | STRING | Entity name, constant per node. |
status | STRING | "Deleted" for hard-deleted objects; absent for live ones. Live rows carry the full payload. |
last_updated_time | TIMESTAMP | |
sync_token | STRING | |
txn_date | DATE | |
total_amt | FLOAT | |
payload | JSON | Whole object as JSON (CDC returns the full payload, so the main node's columns can be re-derived). |
QuickBooks Invoices schema
36 fieldsquickbooks_invoice
Invoices with header amounts, customer and Line[] as JSON (SalesItemLineDetail.ItemRef, Qty, UnitPrice, Amount).
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line array kept as JSON. Unnest in SQL: DetailType decides which \*LineDetail object is present. |
due_date | DATE | |
balance | FLOAT | Unpaid remainder; 0 when fully paid. |
customer_id | STRING | |
customer_name | STRING | |
customer_memo | STRING | |
bill_email | STRING | |
email_status | STRING | |
print_status | STRING | |
sales_term_id | STRING | |
sales_term_name | STRING | |
deposit_to_account_id | STRING | |
deposit_to_account_name | STRING | |
class_id | STRING | |
class_name | STRING | |
department_id | STRING | |
department_name | STRING | |
ship_date | DATE | |
tracking_num | STRING | |
total_tax | FLOAT | |
txn_tax_detail | JSON | |
linked_txn | JSON | Header-level links (payments, estimates) as JSON: TxnId, TxnType. |
home_total_amt | FLOAT | |
home_balance | FLOAT |
QuickBooks Items schema
25 fieldsquickbooks_item
Products and services with price, purchase cost and the three account links.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
name | STRING | |
fully_qualified_name | STRING | |
sku | STRING | |
type | STRING | Inventory, NonInventory, Service, Category, Group… |
description | STRING | |
unit_price | FLOAT | |
purchase_cost | FLOAT | |
qty_on_hand | FLOAT | |
taxable | BOOLEAN | |
track_qty_on_hand | BOOLEAN | |
income_account_id | STRING | |
income_account_name | STRING | |
expense_account_id | STRING | |
expense_account_name | STRING | |
asset_account_id | STRING | |
asset_account_name | STRING | |
sub_item | BOOLEAN | |
parent_id | STRING | |
parent_name | STRING | |
active | BOOLEAN |
QuickBooks Journal entries schema
15 fieldsquickbooks_journal_entry
Manual and adjusting journal entries; the postings the transaction tables miss.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line\[\] as JSON; JournalEntryLineDetail has PostingType (Debit/Credit), AccountRef and optional Entity {Type, EntityRef}. |
adjustment | BOOLEAN | |
total_amt | FLOAT | Sum of one side of the entry. |
home_total_amt | FLOAT |
QuickBooks Payments schema
21 fieldsquickbooks_payment
Customer payments.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
unapplied_amt | FLOAT | |
customer_id | STRING | |
customer_name | STRING | |
deposit_to_account_id | STRING | |
deposit_to_account_name | STRING | |
payment_method_id | STRING | |
payment_method_name | STRING | |
payment_ref_num | STRING | Check or reference number. |
process_payment | BOOLEAN | |
line | JSON | Line\[\] as JSON; each line has Amount and LinkedTxn\[\] {TxnId, TxnType} pointing at the Invoice it settles. |
QuickBooks Preferences schema
17 fieldsquickbooks_preferences
One row per company: home currency, multi-currency flag, fiscal-year and tracking settings.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
home_currency | STRING | |
multi_currency_enabled | BOOLEAN | |
class_tracking_per_txn | BOOLEAN | |
class_tracking_per_txn_line | BOOLEAN | |
track_departments | BOOLEAN | |
first_month_of_fiscal_year | STRING | |
book_close_date | DATE | |
tax_year_month | STRING | |
using_sales_tax | BOOLEAN | |
sales_forms_prefs | JSON | |
vendor_and_purchases_prefs | JSON | |
product_and_services_prefs | JSON |
QuickBooks Profit and Loss report schema
12 fieldsTime seriesquickbooks_report_profit_and_loss
Profit and Loss per run window, one column per month (summarize_column_by=Month), rows nested by account group.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Purchases schema
26 fieldsquickbooks_purchase
Expenses paid directly (cash, check, card) without a bill.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line array kept as JSON. Unnest in SQL: DetailType decides which \*LineDetail object is present. |
payment_type | STRING | Cash, Check or CreditCard. |
account_id | STRING | Bank or credit-card account the money left. |
account_name | STRING | |
entity_id | STRING | Vendor, Customer or Employee paid. |
entity_name | STRING | |
entity_type | STRING | |
payment_method_id | STRING | |
payment_method_name | STRING | |
credit | BOOLEAN | True for a credit-card refund. |
print_status | STRING | |
department_id | STRING | |
department_name | STRING | |
total_tax | FLOAT |
QuickBooks Refund receipts schema
26 fieldsquickbooks_refund_receipt
Money refunded to customers.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line array kept as JSON. Unnest in SQL: DetailType decides which \*LineDetail object is present. |
customer_id | STRING | |
customer_name | STRING | |
deposit_to_account_id | STRING | Account the refund was paid from. |
deposit_to_account_name | STRING | |
payment_method_id | STRING | |
payment_method_name | STRING | |
payment_ref_num | STRING | |
class_id | STRING | |
class_name | STRING | |
department_id | STRING | |
department_name | STRING | |
total_tax | FLOAT | |
home_total_amt | FLOAT |
Sales by Customer report schema
QuickBooks Sales by Customer report schema
12 fieldsTime seriesquickbooks_report_customer_sales
Sales by Customer Summary for the run window.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Sales receipts schema
27 fieldsquickbooks_sales_receipt
Sales paid at the time of sale (no receivable).
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
doc_number | STRING | |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
line | JSON | Line array kept as JSON. Unnest in SQL: DetailType decides which \*LineDetail object is present. |
customer_id | STRING | |
customer_name | STRING | |
deposit_to_account_id | STRING | |
deposit_to_account_name | STRING | |
payment_method_id | STRING | |
payment_method_name | STRING | |
payment_ref_num | STRING | |
bill_email | STRING | |
class_id | STRING | |
class_name | STRING | |
department_id | STRING | |
department_name | STRING | |
total_tax | FLOAT | |
home_total_amt | FLOAT |
QuickBooks Transfers schema
16 fieldsquickbooks_transfer
Money moved between balance-sheet accounts.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
txn_date | DATE | Business date of the transaction (not the edit date). |
total_amt | FLOAT | |
currency_id | STRING | |
currency_name | STRING | |
exchange_rate | FLOAT | |
private_note | STRING | |
amount | FLOAT | |
from_account_id | STRING | |
from_account_name | STRING | |
to_account_id | STRING | |
to_account_name | STRING |
QuickBooks Vendor Expenses report schema
12 fieldsTime seriesquickbooks_report_vendor_expenses
Expenses by Vendor for the run window.
| Field | Type | Description |
|---|---|---|
realm_id | STRING | |
report_name | STRING | |
report_time | TIMESTAMP | When QuickBooks produced the snapshot. |
report_basis | STRING | Cash or Accrual (absent on aging reports). |
start_period | DATE | |
end_period | DATE | |
summarize_columns_by | STRING | |
currency | STRING | |
header_options | JSON | Name/Value pairs; NoReportData=true means an empty report. |
accounting_method_param | STRING | AccountingMethod parameter used for the request (ReportBasis echoes it). |
report_rows | JSON | Nested Section/Data rows as JSON. Flatten in SQL; ColData.id is the Account/Customer/Vendor Id. |
report_columns | JSON | Column metadata (ColTitle, ColType) as JSON; index-aligned with every ColData array. |
QuickBooks Vendors schema
19 fieldsquickbooks_vendor
Vendors, including inactive ones, with open payable balance.
| Field | Type | Description |
|---|---|---|
id | STRING | QuickBooks entity Id (string). Primary key together with realm_id. |
realm_id | STRING | Company (realm) id, stamped from the RealmId parameter. |
sync_token | STRING | Version counter; changes on every edit. |
create_time | TIMESTAMP | |
last_updated_time | TIMESTAMP | Incremental cursor. |
display_name | STRING | |
company_name | STRING | |
primary_email | STRING | |
primary_phone | STRING | |
balance | FLOAT | Open A/P balance owed to the vendor. |
currency_id | STRING | |
currency_name | STRING | |
vendor_1099 | BOOLEAN | |
acct_num | STRING | |
term_id | STRING | |
term_name | STRING | |
bill_addr_country | STRING | |
bill_addr | JSON | |
active | BOOLEAN |
Why collect QuickBooks data into your data warehouse with OWOX?
A wrong revenue number looks exactly like a right one. When your dashboard says one figure and finance says another, finance can point to the books and the accounting rules behind them. You have a query. The QuickBooks connector puts the books in your data warehouse next to Shopify orders and ad spend, so the two numbers are compared line by line in SQL, not argued about across two tools.
Collect to your data warehouse
QuickBooks Online data lands in tables you own in your data warehouse: Google BigQuery, Snowflake, AWS Redshift, AWS Athena or Databricks.
Changes and deletes, not just totals
Every transaction carries its business date and its last edit time, and a change-data-capture table records deleted invoices.
Books next to the store and the ads
Join invoices, bills and the P&L to commerce and marketing data in a Data Mart, with the SQL visible.

R01 · Collect
Collect all your QuickBooks data with zero engineering
The connector has 26 endpoints, each landing in its own table.
17 entity tables. Accounts (quickbooks_account), customers, vendors and items are the lists everything else points to. Sales: invoices (quickbooks_invoice), payments, sales receipts, credit memos and refund receipts. Purchases: bills (quickbooks_bill), bill payments and purchases, the card, cash and check spend that never had a bill. Journal entries hold the adjusting postings the other tables miss; deposits and transfers move money between accounts; company info and preferences hold one row per company, home currency and fiscal-year start included.
One change-data-capture table. quickbooks_cdc_invoice reads Intuit’s change data capture endpoint with a changedSince time and returns every invoice created, updated or deleted since then, with the full invoice as JSON. Deleted invoices carry status = Deleted. This is the only place a delete shows up: a query on last-updated time never returns a deleted row, so quickbooks_invoice keeps the last live version of an invoice that no longer exists. Intuit’s endpoint looks back at most 30 days and returns at most 1,000 changes per request, so the table runs daily and a delete older than its first run is not recovered.
Eight dated report snapshots. Profit and Loss with one column per month, Balance Sheet, Cash Flow, A/R Aging Summary, A/P Aging Summary, Vendor Expenses, General Ledger Detail and Sales by Customer. Each run requests the report for its run window and stores it with start_period and end_period, rows kept as JSON.
The chart of accounts, items, company info and preferences reload in full on every run. The transaction and name-list tables read the records whose MetaData.LastUpdatedTime is after the “Load changes since” date you set, oldest edit first and at most 1,000 per run, so an edited invoice returns with a new last_updated_time and sync_token. A company with more than 1,000 changes since that date needs the date moved forward, or a second Data Mart on a later window, before the table is complete. Line items stay as one line JSON column, every row carries the company id as realm_id, and an HTTP 429 from Intuit is retried with a back-off, using the Retry-After header when Intuit sends one. Range reports run on Accrual or Cash, whichever you choose, and record it in accounting_method_param, so a cash-basis and an accrual-basis P&L never mix in one query.
Authentication is OAuth 2.0 with a refresh token. The platform exchanges the refresh token for an access token on each run. Intuit rotates refresh tokens and expires one left unused for 100 days, so the token is saved in an OWOX credential, where the platform persists the rotated token for the next run.
A custom connector, built in OWOX Data Marts
QuickBooks is not one of the open-source native connectors. It is a custom connector, built in the connector builder of OWOX Data Marts from Intuit’s Accounting API documentation: 26 nodes, each a request plus the fields it lands. Its whole manifest opens in the builder’s Code tab, so you can see exactly what it fetches.
To set it up:
- In OWOX Data Marts, open Connectors and choose the custom connector QuickBooks Online.
- Create a credential with your Intuit app’s Client ID and Client Secret, a Refresh Token and the Realm ID, the QuickBooks company id.
- Create one Data Mart per table you need and point it at a dataset in your data storage.
- Add a Connector Trigger that runs the Data Marts daily.

R02 · Report
Build reports with QuickBooks data that everyone trusts
On one company’s books, eight Data Marts load daily into a BigQuery dataset named quickbooks: accounts, customers, invoices, payments, bills, items, A/R aging and P&L. The P&L history from 2026-01-01 to 2026-11-05 was backfilled in 10 segments, every one Success.
Two checks from that setup:
- A/R aging rebuilt in SQL from open balances in
quickbooks_invoicematches the A/R Aging Summary report to the cent. - Over July to October, invoices explain 94% of P&L income and bills 71% of P&L expenses. The rest sits in tables the eight Data Marts do not load yet: sales receipts and refunds on the income side, direct purchases (card and cash spend without a bill) on the expense side. Invoices alone are never the revenue number.
Join these tables with orders and ad spend in a model, and margin by channel comes from one readable query.
R03 · Why OWOX
Runbook for AI agents querying QuickBooks tables
| Question | Table | Date field |
|---|---|---|
| Income, expenses and net income by month, as QuickBooks reports them | quickbooks_report_profit_and_loss |
start_period, end_period |
| Invoiced sales by customer or item | quickbooks_invoice, unnest line |
txn_date |
| Cash received | quickbooks_payment |
txn_date |
| Open receivables and aging | quickbooks_invoice (balance), checked against quickbooks_report_aged_receivables |
due_date; end_period |
| Payables | quickbooks_bill, quickbooks_bill_payment |
txn_date, due_date |
| Spend without a bill | quickbooks_purchase |
txn_date |
| What changed or was deleted | quickbooks_cdc_invoice |
last_updated_time |
- Bucket money by
txn_date, the business date.last_updated_timeis the last edit: use it for freshness, never for revenue by month. - Every transaction and list table’s key is
realm_id+id. Join on both. Company info and preferences hold one row perrealm_id. - How the 26 tables fit together is drawn in the QuickBooks data model:
quickbooks_company_infois the anchor table onrealm_id, and customers, vendors and accounts are the hubs every transaction table joins to. Open it on the model canvas or read the bundle on GitHub. customer_idjoins toquickbooks_customer.id,vendor_idtoquickbooks_vendor.id, and any*_account_idtoquickbooks_account.id.- Payment to invoice: unnest
quickbooks_payment.line, keep eachLinkedTxnentry withTxnType=Invoice, and join itsTxnIdtoquickbooks_invoice.id. Bill payments link to bills the same way. - Drop deleted invoices with an anti-join to
quickbooks_cdc_invoicewherestatus=Deleted. - In report tables, flatten
report_rows;ColData.idis the account, customer or vendor id, andreport_columnsis index-aligned with eachColDataarray. Whereaccounting_method_paramexists, filter it to one method.
R04 · Why OWOX
Deliver QuickBooks data to the tools your team uses
A Report delivers one Data Mart to one destination, and each Data Mart can feed many destinations.
- Push mode: OWOX writes the data on a manual or scheduled run. Google Sheets, email, Slack, Microsoft Teams and Google Chat work this way.
- Pull mode: the tool asks OWOX for the data when a user refreshes it. Data Studio and Microsoft Excel work this way.
- assistants such as Claude and ChatGPT read the Data Mart through OWOX MCP, not the raw tables, so answers use your definitions.
Why use OWOX connectors to collect your QuickBooks data?
Books next to commerce
Accounting, orders and ad spend sit in one data warehouse, ready to join.
Your data stays yours
The tables sit in a data warehouse you own.
Deletes you can see
A deleted invoice is a row in the CDC table, not a mystery.
Report history you keep
Each report snapshot is stored with its period, so past periods stay queryable.
Scheduled, not exported
A daily Connector Trigger means nobody exports the books by hand.
Readable to the last field
The manifest and every field description are open in the connector builder.
Extend it yourself
To track deletes on bills or payments too, clone the CDC node for that entity.
Define once, reuse everywhere
One Data Mart feeds Sheets, Excel, Data Studio and AI assistants.
Not testimonials. Comment threads.
Real things real customers said — each quote pinned to a specific claim, straight from the quotes database.
“AI, by the nature of the models, will hallucinate. And because of that, you need something which will create guardrails to ensure that there are no hallucinations, that you can trust your data.”
“We had six or seven different channels and no single source of truth — it was almost impossible, a lot of guesswork.”
“We regained time. And time is the one resource that never comes back.”
Start collecting QuickBooks data
Add the custom connector with your Intuit app keys, create one Data Mart per table and schedule a daily run.
You are booked. The invitation is on its way to , with the calendar invite and the meeting link.

