Reporting — Products (GraphQL)
Returns the aggregate statistics that power the Bagisto admin Reporting → Products screen — sold quantities, wishlist additions, top sellers, review counts, visit counts and search-term analytics.
| Query | statsAdminReportingProducts |
| View Details query | viewStatsAdminReportingProducts |
| Endpoint | POST /api/admin/graphql |
| Returns | A single object: { entity, type, dateRange, statistics } (entity is always "products") |
All admin endpoints require an admin Bearer token — see Authentication.
Understanding type — the Products report is eight separate calls
This is the most important thing to understand about this API.
The Products reporting screen is not one response. Each panel is a separate query selected with the type argument. A single call returns one report, and the statistics payload changes shape per type — sometimes an object (the chart reports), sometimes a flat array (the ranked-list reports) — so always branch on type when consuming it.
total-sold-quantities is the default — if you omit type, you get the sold-quantities chart.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
type | String | No | One of the eight values listed below. Defaults to total-sold-quantities. An unknown value returns a GraphQL errors[] entry (400, invalid-type). |
start | String (YYYY-MM-DD) | No | Lower bound of the reporting window. Defaults to 30 days ago. |
end | String (YYYY-MM-DD) | No | Upper bound. Defaults to today. |
channel | String | No | Channel code to scope the figures to a single channel. Defaults to all channels. |
start / end drive both the figures and the previous baseline used for each progress percentage — the previous period is the same-length window immediately before start.
Selection set
query AdminReportingProducts($type: String, $start: String, $end: String, $channel: String) {
statsAdminReportingProducts(type: $type, start: $start, end: $end, channel: $channel) {
entity
type
dateRange
statistics
}
}entity— always"products".type— echoes back the requested report.dateRange— an object{ previous, current }with a human-readable label for each window. Unlike some other admin GraphQL endpoints, the reportingdateRangeresolves correctly here.statistics— a JSON scalar whose shape depends ontype(documented below). Query it bare — its sub-shape is not field-selectable.
Response shapes by type
Figures with a previous / current / progress shape are period comparisons: current is the chosen window, previous is the preceding window of equal length, and progress is the percentage change (can be negative).
type | statistics is | Shape |
|---|---|---|
total-sold-quantities | object | { quantities: { previous, current, progress }, over_time: { previous: [{label,total}], current: [{label,total}] } } |
total-products-added-to-wishlist | object | { wishlist: { previous, current, progress }, over_time: { previous: [{label,total}], current: [{label,total}] } } |
top-selling-products-by-revenue | array | rows of { id, name, price, formatted_price, revenue, formatted_revenue, progress, images: [{id,type,path,product_id,position,url}] } |
top-selling-products-by-quantity | array | rows of { id, name, price, formatted_price, total_qty_ordered, progress, images: [{id,type,path,product_id,position,url}] } |
products-with-most-reviews | array | rows of { product_id, product_name, reviews, progress } |
products-with-most-visits | array | rows of { visitable_id, name, visits, progress } |
last-search-terms | array | rows of { id, term, results, uses, channel_id, locale } |
top-search-terms | array | rows of { id, term, results, uses, channel_id, locale } |
total-sold-quantities
| Key | Shape | Meaning |
|---|---|---|
quantities | { previous, current, progress } | Total units sold in the window vs. the previous window. |
over_time | { previous: [{label,total}], current: [{label,total}] } | Two per-day series (previous and current windows) for the chart line; total is units sold per bucket. |
total-products-added-to-wishlist
| Key | Shape | Meaning |
|---|---|---|
wishlist | { previous, current, progress } | Wishlist additions in the window vs. the previous window. |
over_time | { previous: [{label,total}], current: [{label,total}] } | Two per-day series for the chart line; total is additions per bucket. |
top-selling-products-by-revenue
statistics is an array of product rows. Each row: id, name, price (may be null), formatted_price, revenue, formatted_revenue, progress, and images (array of { id, type, path, product_id, position, url } — empty when the product has no image).
top-selling-products-by-quantity
statistics is an array of product rows. Each row: id, name, price, formatted_price, total_qty_ordered, progress, and images (array of { id, type, path, product_id, position, url }).
products-with-most-reviews
statistics is an array. Each row: product_id, product_name, reviews (count in the window), progress.
products-with-most-visits
statistics is an array. Each row: visitable_id, name, visits, progress. Visit figures depend on the Bagisto visitor/analytics tables being populated; on a fresh store this report is empty.
last-search-terms
statistics is an array of the most recent storefront searches. Each row: id, term, results (matches returned), uses (times searched), channel_id, locale.
top-search-terms
statistics is an array of the most-used storefront searches — same row shape as last-search-terms (id, term, results, uses, channel_id, locale), ranked by uses. This report has no View Details (table) form — it is stats-only.
View Details
viewStatsAdminReportingProducts is the detailed table form of the matching statsAdminReportingProducts query — its statistics carries columns ({ key, label }) and records (the row data behind a panel's View Details link), rather than the rolled-up headline figures. It honors the same type values as the stats query, except top-search-terms, which has no table form. Records may carry extra fields beyond the displayed columns (e.g. the raw revenue / images alongside the formatted display values).
The CSV Export is REST only (a binary text/csv download); there is no GraphQL equivalent.
Errors
| Condition | Result |
|---|---|
| Missing / invalid Bearer token | 401 Unauthenticated |
Unknown type value | GraphQL errors[] — "Invalid reporting stat type." (400) |
See also
- Reporting — Products (REST) — same data plus the CSV Export.
- Dashboard Statistics (GraphQL) — the at-a-glance dashboard figures.

