Aggregate Reports (/report)

Some resources expose a report endpoint for server-side aggregates (sums, averages, counts, and similar totals) over filtered rows. Prefer /report when you need totals or averages instead of downloading every row with /get and aggregating in the client.

GET https://services.trade-traks.ca/api/{Resource}/report

Example:

GET https://services.trade-traks.ca/api/Expense/report?filters=[["job_id",12]]

Not every resource supports /report. If it is not available for that resource, the API returns an error such as Report not configured for this resource. Check the resource's method list in the API docs for a report method, or inspect the keys returned in a successful data object for that resource.


Request Parameters

Parameters can be sent as either FormData fields, or as fields in a JSON request body when the Content-Type header is application/json.

Parameter Type Value
filters JSON Same filter format as Getting/Filtering Data, but only fields on the resource itself. Filters that target related resources (for example User.first_name) are not supported. Do not use include with /report.
include_deleted boolean For resources that soft-delete records, pass true to include deleted rows in the aggregate (by default they are excluded).

/report does not support include, orders, page, or limit. It always returns a single aggregate object for the matching rows (tenant-scoped like other endpoints).


Permissions

The caller must have full module read access for the resource. Callers without full permissions receive an empty data object rather than aggregates. This is stricter than some /get paths that return a filtered subset of rows.


Example response

A successful call returns a single data object (not an array). The keys are the aggregate metrics defined for that resource. For example, Expense/report may return:

{
	"success": true,
	"data": {
		"subtotal_sum": 1250.5,
		"grand_total_sum": 1400.25,
		"average_tip": 3.5,
		"average_tip_pct": 2.1,
		"average_expense_total": 70.01,
		"record_count": 20
	}
}

When to use /report vs /get
  • Use /report for totals, averages, and counts over a filtered set (revenue, hours cost, expense totals, purchase order totals, etc.).
  • Use /get when you need individual rows, related records via include, sorting, or pagination.
  • Do not confuse a resource's /report endpoint with JobReport/get-range, which is a separate billing/report API.

Resources that support reports

Resources that currently expose /report (and typical response keys):

  • JobInvoice - e.g. total_revenue, total_holdback
  • ServiceInvoice - e.g. total_revenue (filter is_quote for invoices vs quotes)
  • Expense - e.g. subtotal_sum, grand_total_sum, record_count
  • TimeLog - e.g. total_hours, total_regular_hours, overtime hour sums, total_calculated_cost
  • PurchaseOrder - e.g. grand_total_sum, record_count
  • JobChangeOrder - e.g. grand_total_sum, pretax_total_sum, record_count
  • JobBid - e.g. grand_total_sum, record_count (filter status for pipeline slices)
  • JobBidComponent - e.g. direct_value_sum, direct_labour_hrs_sum, record_count
  • JobActualCostDatapoint - e.g. actual_project_cost_sum, record_count (dated snapshots; filter by job_id and/or date so you do not sum multiple snapshots for the same project)
  • Job - e.g. record_count, actual_project_cost_sum, total_holdback_to_date_sum, total_holdback_release_to_date_sum
  • ServiceContract - e.g. price_sum (annual contract price book), record_count
  • Rfi - e.g. record_count (filter status for open vs closed volumes)
  • Locate - e.g. record_count

Call /report on the resource (or check its method list in the docs) to see the metrics available for that resource.