Reports
QuickBooks Desktop computes reports itself, with its own accounting rules, on the customer’s computer. The report endpoints run those reports and return them as structured JSON, so the numbers you show match what your customer sees in QuickBooks.
Report families
Section titled “Report families”| Endpoint | Includes, for example |
|---|---|
GET /v1/quickbooks-desktop/reports/general-summary |
Profit and loss (standard, by class, by job, year-to-date comparison), balance sheet, trial balance, sales by customer or item, income and expense summaries, inventory valuation, sales tax liability |
GET /v1/quickbooks-desktop/reports/general-detail |
Transaction detail reports: general ledger, journal, transaction detail by account, open invoices, sales and purchase detail |
GET /v1/quickbooks-desktop/reports/aging |
Accounts receivable and payable aging, summary and detail, and the collections report |
GET /v1/quickbooks-desktop/reports/budget-summary |
Budget overview and budget versus actual |
GET /v1/quickbooks-desktop/reports/job |
Job profitability and estimates versus actuals |
GET /v1/quickbooks-desktop/reports/time |
Time by job, by item and by name |
GET /v1/quickbooks-desktop/reports/custom-summary |
Custom summary reports you define with rows and columns |
GET /v1/quickbooks-desktop/reports/custom-detail |
Custom transaction detail reports |
GET /v1/quickbooks-desktop/reports/payroll-summary |
Payroll summaries, when the company uses QuickBooks payroll |
GET /v1/quickbooks-desktop/reports/payroll-detail |
Payroll detail, when the company uses QuickBooks payroll |
reportType picks the report within a family, for example profit_and_loss_standard or balance_sheet_standard for general summary, or ar_aging_summary for aging. The API reference lists every value.
Running a report
Section titled “Running a report”import { DesktopAccountingApi } from "@desktopaccountingapi/quickbooks-desktop";
const qb = new DesktopAccountingApi().forEndUser("eu_01j9...");
const report = await qb.qbd.reports.generalSummary({ reportType: "profit_and_loss_standard", reportDateMacro: "last_month", basis: "accrual",});
for (const row of report.rows) { if (row.kind === "data" || row.kind === "total") { console.log(row.rowDescriptor?.value, row.cells.map((c) => c.value).join(" | ")); }}from desktopaccountingapi import DesktopAccountingApi
qb = DesktopAccountingApi().for_end_user("eu_01j9...")
report = qb.qbd.reports.general_summary( report_type="profit_and_loss_standard", report_date_macro="last_month", basis="accrual",)
for row in report.rows: if row.kind in ("data", "total"): print(row.row_descriptor.value if row.row_descriptor else None, [c.value for c in row.cells])curl "https://api.desktopaccountingapi.com/v1/quickbooks-desktop/reports/general-summary?reportType=profit_and_loss_standard&reportDateFrom=2026-09-01&reportDateTo=2026-09-30" \ -H "Authorization: Bearer $DAAPI_SECRET_KEY" \ -H "Daapi-End-User-Id: eu_01j9..."Common parameters: reportDateFrom / reportDateTo or reportDateMacro for the period; basis (accrual or cash) where it applies; summarizeColumnsBy to split columns by month, quarter, class or customer; filters by account, entity, item, class and transaction type.
The report object
Section titled “The report object”{ "objectType": "qbd_report", "category": "general_summary", "reportType": "profit_and_loss_standard", "title": "Profit & Loss", "subtitle": "September 2026", "basis": "accrual", "rowCount": 24, "columnCount": 2, "columnTitleRowCount": 1, "columns": [ { "columnId": "1", "columnType": "label", "dataType": "strtype", "titles": [{ "rowNumber": 1, "value": null }] }, { "columnId": "2", "columnType": "amount", "dataType": "amttype", "titles": [{ "rowNumber": 1, "value": "Sep 26" }] } ], "rows": [ { "kind": "text", "rowNumber": 1, "text": "Income", "rowDescriptor": null, "cells": [] }, { "kind": "data", "rowNumber": 2, "text": null, "rowDescriptor": { "type": "account", "value": "Sales" }, "cells": [ { "columnId": "1", "value": "Sales", "dataType": "strtype" }, { "columnId": "2", "value": "48210.00", "dataType": "amttype" } ] }, { "kind": "total", "rowNumber": 3, "text": null, "rowDescriptor": null, "cells": [ { "columnId": "1", "value": "Total Income", "dataType": "strtype" }, { "columnId": "2", "value": "48210.00", "dataType": "amttype" } ] } ]}columnsdescribe each column in display order.titlesholds one entry per title row; multi-row headers (a month above “Actual” and “Budget”) have several.rowscome in display order.kindisdata(a line of the report),text(a heading, intext),subtotalortotal.rowDescriptorsays what a data row describes, such as an account or customer, and its name.- Every row has every field: a text row has
rowDescriptor: nulland emptycells; other rows havetext: null. The names match Conductor’s report rows. cellshold values keyed bycolumnId. Values are strings, as QuickBooks formats them;dataTypetells you how to parse each one (amttypeis an amount,datetypea date,strtypetext, and so on; these are QuickBooks’ own type names in lowercase).
Rows are flat. Use the order of text, data, subtotal and total rows to rebuild the hierarchy QuickBooks shows, or rely on rowDescriptor for the account or name of each data row.
Performance
Section titled “Performance”Reports run inside QuickBooks on the customer’s computer and can take a while on large files, especially detail reports over long periods. Keep date ranges tight, use async mode (Prefer: respond-async) for heavy reports, and raise Daapi-Timeout-Seconds if you call them synchronously. A report too large to process returns 422 QBD_RESPONSE_TOO_LARGE; narrow the period or the filters.
Payroll reports need a company that uses QuickBooks payroll. Without it, QuickBooks returns an error that we pass through with its status code.