Reports
Generate financial reports as files (Excel by default; CSV, PDF or HTML on request). Generation runs in the background; finished reports are stored and downloadable through the API.
Available Reports
GET /api/v1/reports/types returns the full, current list. Each item has report_name, title, description, input_type (which tells you which request fields it needs) and requires_cfo_suite. Commonly used report_name values:
report_name |
Description | Inputs |
|---|---|---|
master_transactions |
All transactions across accounts | start_date, end_date |
journal_entry_report / audit_trail |
Journal entries and change history | start_date, end_date |
categorization_review |
Flagged transactions for the period: uncategorized, likely miscategorized, unpaired transfers | start_date, end_date (optional additional_params.period) |
close_verification |
Month-end exceptions: uncategorized, miscategorized, unpaired transfers, unmatched deposits, manual JEs | start_date, end_date |
trial_balance |
Debits/credits verification | start_date, end_date (optional additional_params.include_zero_balances) |
aged_trial_balance |
Trial balance with aging buckets | end_date |
general_ledger |
Transactions per account (optionally one ledger_id) |
start_date, end_date |
chart_of_accounts |
Complete account listing | none |
profit_and_loss |
Income statement | start_date, end_date |
profit_and_loss_comparative |
P&L vs. a comparison period | dates + comparison_* fields |
income_statement_periodic / income_statement_details |
Month/quarter/year income statement; transaction-level P&L detail | dates (periodic also takes additional_params.grouping: monthly, quarterly or yearly) |
pnl_by_customer / pnl_by_department |
P&L segmented by customer or tag | dates + additional_params.customer_id / tag_group_id, tag_ids |
balance_sheet |
Assets, liabilities, equity as of a date | end_date |
balance_sheet_comparative |
Balance sheet vs. a comparison date | end_date + comparison_end_date |
balance_sheet_monthly |
Month-by-month balance sheet | start_date, end_date |
retained_earnings / statement_of_owners_equity / shareholder_loans |
Equity roll-forwards and shareholder loan tracking | start_date, end_date |
cash_flow_statement / cash_flow_periodic / cash_flow_forecast |
Cash flow, historical, by period, or projected | start_date, end_date; forecast takes additional_params.forecast_days (default 90) |
ar_report / ap_report |
Invoice and bill summaries with aging | none |
bills_pending_approval |
Bills waiting in the approval queue | none |
unpaid_ar_as_of / unpaid_ap_as_of |
Open receivables / payables at a date | end_date |
customer_statements / vendor_statements |
Statements per customer or vendor | dates + additional_params.customer_id / vendor_id |
customer_cash_receipts |
Bank deposits applied to receivables, by customer and quarter | start_date, end_date |
tax_summary, report_1099, check_register, bank_reconciliation |
Compliance and banking | start_date, end_date |
budget_vs_actual |
Budget vs. actual (optional additional_params.budget_id) |
start_date, end_date |
expense_by_category, sales_report, cogs_report, payroll_summary, subscription_costs, fixed_assets_depreciation |
Operational reports | start_date, end_date |
inventory_by_location, products_report |
Inventory and product exports | none |
unrealized_fx_gain_loss, intercompany_reconciliation |
Multi-currency and intercompany | end_date |
financial_ratios, financial_summary_dashboard, saas_metrics, quality_of_earnings |
CFO analytics | start_date, end_date |
working_capital |
Current assets vs. liabilities | end_date |
deferred_revenue_waterfall |
Deferred revenue roll-forward | dates + additional_params.grouping |
dashboard_export, transactions_export, bespoke_document |
Saved-dashboard export, Transactions table workbook (xlsx only, 10,000 rows max), AI-built custom document | see /reports/types |
These report_name values require the CFO Suite add-on and return 403 without it: profit_and_loss_comparative, income_statement_periodic, income_statement_details, pnl_by_customer, pnl_by_department, balance_sheet_comparative, balance_sheet_monthly, cash_flow_periodic, cash_flow_forecast, financial_ratios, financial_summary_dashboard, budget_vs_actual, working_capital, retained_earnings, shareholder_loans, report_1099 and subscription_costs. An unknown report_name is a 400.
Generate a Report
curl -X POST "https://api.ondayzero.com/api/v1/reports" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"report_name": "profit_and_loss",
"start_date": "2026-01-01",
"end_date": "2026-03-31",
"output_format": "pdf"
}'| Field | Description |
|---|---|
report_name |
Required. One of the names from /reports/types |
period_type |
custom (default — use start_date/end_date), tax_year or tax_quarter (use tax_year and tax_quarter; dates are derived from the business's fiscal year end) |
start_date / end_date |
YYYY-MM-DD. Point-in-time reports need only end_date |
output_format |
xlsx (default), csv, html, pdf |
comparison_period_type, comparison_start_date / comparison_end_date, comparison_tax_year / comparison_tax_quarter |
Prior period for *_comparative reports |
ledger_id, tag_group_id, tag_ids |
Narrow general_ledger to one account, or segment pnl_by_department; tag_ids also filters profit_and_loss, the periodic and comparative income statements and the financial summary |
additional_params |
Report-specific options, e.g. {"customer_id": "…"} for customer_statements or pnl_by_customer, {"vendor_id": "…"} for vendor_statements |
additional_params.basis |
accrual or cash for the income statement, balance sheet, cash flow, trial balance, general ledger and most analysis reports. Omitted means the business's configured default, which may be cash. Any other value is a 400. The file states the basis it was built on |
additional_params.include_period_columns |
true adds "Quarter Ending" and "Calendar Year Ending" columns after every date column |
instance_id |
Legacy ledger-engine instance override; normally omit |
file_s3_key / s3_keys |
Input files for upload-driven reports (see File Uploads) |
The response is 202 Accepted:
{
"success": true,
"data": {
"task_id": "report-generation-…-profit_and_loss-start-2026-01-01-end-2026-03-31",
"status": "queued",
"report_name": "profit_and_loss",
"business_id": "…",
"message": "Report generation queued successfully with Temporal",
"executor": "temporal"
}
}status is queued, or in_progress if an identical report is already being generated (the request is de-duplicated rather than run twice). The task_id is deterministic for the same report name, period and parameters.
Retrieve the Finished Report
Either poll the task with GET /api/v1/tasks/task/{task_id} (the response status becomes SUCCESS and result carries the s3_key and a download_link; an unknown task returns HTTP 200 with status: NOT_FOUND), or poll the report list — the newest reports come first — until one with your report_name and period appears:
curl "https://api.ondayzero.com/api/v1/reports?limit=5" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Each report has id, report_name, generation_params (the request you sent, with dates resolved, so you can match it), s3_key, created_at, downloaded_at, generated_by_name and a download_url. GET /api/v1/reports/{report_id} fetches one by ID. Add client_visible_only=true to the list to see only reports shared with clients.
Download
download_url points at GET /api/v1/reports/download?s3_key=… — a same-origin endpoint that validates ownership, records the download, and then 307-redirects to a short-lived presigned S3 URL (falling back to streaming the file itself). Send the usual Authorization and x-business-id headers and follow redirects:
curl -L -o pnl-q1.pdf "https://api.ondayzero.com/api/v1/reports/download?s3_key=reports/YOUR_BUSINESS_ID/profit_and_loss_2026-01-01_2026-03-31.pdf" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Add inline=true to get a Content-Disposition: inline response for viewing in a browser, or filename=… to rename the download. DELETE /api/v1/reports/{report_id} removes a stored report and its file.
To preview a stored PDF, Excel or PowerPoint file as images, GET /api/v1/reports/preview-info?s3_key=… returns available and page_count (up to 20 pages), and GET /api/v1/reports/preview-page?s3_key=…&page=1 returns that page as a PNG.
Related
GET /api/v1/reports/subledger-gl-reconciliation— checks that the AR/AP sub-ledgers agree with the general ledger control accounts. Takesas_of_date(YYYY-MM-DD, default today) andparent_ledger_id(reconcile only that control account and its sub-ledgers; a liability account is read as the payables side). Thearandapsections hold the totals in cents (open documents minus GL balance) androws, largest difference first, hold one entry per customer (AR) or vendor (AP), plus one for lines that cannot be attributed to anyone. Each row haskind,customer_or_vendor,party_id(null when unattributed),subledger_balance_cents(the party's GL balance),open_documents_cents,difference_cents(GL balance minus open documents, the opposite sign to the section totals) andexplanations: tagged causes (fee_shortfall,unapplied_credit,unposted_payment,rounding), each with an amount and whether it accounts for the difference. A manual journal entry posted straight to AR or AP carries no tag and shows as an unexplained difference. As-of figures are approximate for documents voided or written off after the date, because statuses are not historized. The MCP tool isget_subledger_gl_reconciliation.POST /api/v1/reports/suggest— AI suggestions for which reports are worth running given recent activity.GET /api/v1/reports/import-templates— CSV templates (and READMEs) for bulk imports of transactions, journal entries and more.import-templates.zipbundles them all;import-templates/{template_key}.csvand.mdfetch one template or its README.