Special Reports

Some reports in Shopfront can't be written with the Reporting Query Language, these are available as their own endpoints instead. Each one runs for a single Outlet and responds in the same shape as a successful query, always as a single page.

Unlike the reports in Shopfront, values aren't formatted for display: numbers are sent as numbers, dates are sent as YYYY-MM-DD in the Vendor's timezone (or null when there isn't one), and each product row has an ID column with the product's ID alongside its Name.

Scopes

The special reports require the same scopes as the rest of the Reporting API:

  • run_advanced_reports

For further information on scopes, please see Scopes.

Rate Limit

The special reports share the Reporting API's rate limit, each request uses one request from the same limit as querying /api/v2/reports. The X-Reporting-RateLimit-Remaining header contains the number of requests you have remaining, once it reaches zero you'll receive a status of 429 until the limit has reset.

Errors

If the Outlet can't be found, the application doesn't have access to report on it, or a parameter is missing or invalid, you'll receive a status of 400 with an error message. If the application is missing the required scopes, you'll receive a status of 403 in the same format as a failed query.

Error Response (JSON)
{
    "error": "The user does not have access to this Outlet for reporting"
}

Slow Moving Stock

Lists the Outlet's in stock products that are selling slowly, ordered by their score (slowest first). Products that have never sold are scored by the number of days since they were created multiplied by their inventory, otherwise they're scored by how many days of their average daily sales the current inventory would cover.

Send a POST request to https://[vendor].onshopfront.com/api/v2/reports/slow-moving-stock with the following parameters:

Parameter Required Description
outlet Required The ID of the Outlet to report on
brands Optional Only include products in these Brand IDs
categories Optional Only include products in these Category IDs
families Optional Only include products in these Family IDs
tags Optional Only include products with these Tag IDs

Each row contains the columns ID, Name, Average Sold Per Day, Inventory, Creation Date, Last Sold, Last Ordered, Last Received, and Score.

Example
Slow Moving Stock (HTTP)
POST /api/v2/reports/slow-moving-stock HTTP/1.1
Host: example.onshopfront.com
Accept: application/json
Authorization: Bearer ...
Content-Type: application/json
{
    "outlet": "11e6d61b3dec425286c45cf9dd713698",
    "categories": [
        "11e7a2c4f0d84c6ab2d1e2c5a1f3b4d5"
    ]
}
Success Response (JSON)
{
    "completed": true,
    "data": {
        "columns": [
            "ID",
            "Name",
            "Average Sold Per Day",
            "Inventory",
            "Creation Date",
            "Last Sold",
            "Last Ordered",
            "Last Received",
            "Score"
        ],
        "data": [
            {
                "ID": "11e8b1c2d3e44f5a9b6c7d8e9f0a1b2c",
                "Name": "Pale Ale 6 Pack",
                "Average Sold Per Day": 0,
                "Inventory": 24,
                "Creation Date": "2026-03-02",
                "Last Sold": null,
                "Last Ordered": "2026-03-02",
                "Last Received": "2026-03-04",
                "Score": 5376
            },
            {
                "ID": "11e8b1c2d3e44f5a9b6c7d8e9f0a1b2d",
                "Name": "Shiraz 750ml",
                "Average Sold Per Day": 0.042,
                "Inventory": 18,
                "Creation Date": "2025-11-20",
                "Last Sold": "2026-08-14",
                "Last Ordered": "2025-11-20",
                "Last Received": "2025-11-22",
                "Score": 429
            }
        ],
        "groups": [],
        "totals": []
    }
}

Last Stocktaked

Lists when each of the Outlet's products was last stocktaked, on or before the end of a date, and who stocktaked it.

Send a POST request to https://[vendor].onshopfront.com/api/v2/reports/last-stocktaked with the following parameters:

Parameter Required Description
outlet Required The ID of the Outlet to report on
date Required The date (YYYY-MM-DD) to report up to the end of
showZeroInventory Optional Whether products with no inventory are included (defaults to false)
includeInactive Optional Whether inactive products are included, adding a Status column (defaults to false)
brands Optional Only include products in these Brand IDs
categories Optional Only include products in these Category IDs
families Optional Only include products in these Family IDs
tags Optional Only include products with these Tag IDs

Each row contains the columns ID, Name, Category, Date, Inventory, and User (the name of who performed the stocktake).

Example
Last Stocktaked (HTTP)
POST /api/v2/reports/last-stocktaked HTTP/1.1
Host: example.onshopfront.com
Accept: application/json
Authorization: Bearer ...
Content-Type: application/json
{
    "outlet": "11e6d61b3dec425286c45cf9dd713698",
    "date": "2026-10-16",
    "showZeroInventory": false,
    "includeInactive": false
}
Success Response (JSON)
{
    "completed": true,
    "data": {
        "columns": [
            "ID",
            "Name",
            "Category",
            "Date",
            "Inventory",
            "User"
        ],
        "data": [
            {
                "ID": "11e8b1c2d3e44f5a9b6c7d8e9f0a1b2c",
                "Name": "Pale Ale 6 Pack",
                "Category": "Beer",
                "Date": "2026-09-30",
                "Inventory": 24,
                "User": "Sam Smith"
            }
        ],
        "groups": [],
        "totals": []
    }
}

Inventory At Date

Calculates the inventory levels and stock value of the Outlet's products at a previous date.

Send a POST request to https://[vendor].onshopfront.com/api/v2/reports/inventory-at-date with the following parameters:

Parameter Required Description
outlet Required The ID of the Outlet to report on
date Required The date and time to report the inventory at, in the Vendor's timezone
showZero Optional Whether products with no inventory are included (defaults to true)
groupBy Optional Group the products by category, brand, family, tag, core_supplier, or last_supplier
showProducts Optional When grouping, whether each product is included or only the group totals (defaults to true)
columns Optional The column keys to include, see data.columns in the response for the available keys
sort Optional The column key to sort the products by (defaults to Name)
direction Optional Either asc or desc (defaults to asc)

The column names for quantities and costs use the Vendor's quantity terminology (e.g. "Case Quantity"), so data.columns is an object of each column's key to its name. When products are grouped, each group also contains the id of the classification it's grouped by, and when showProducts is false each row's ID is the classification's ID instead of a product's (null for the group of products without one).

Example
Inventory At Date (HTTP)
POST /api/v2/reports/inventory-at-date HTTP/1.1
Host: example.onshopfront.com
Accept: application/json
Authorization: Bearer ...
Content-Type: application/json
{
    "outlet": "11e6d61b3dec425286c45cf9dd713698",
    "date": "2026-06-30 23:59:59",
    "showZero": false
}
Success Response (JSON)
{
    "completed": true,
    "data": {
        "columns": {
            "ID": "ID",
            "Name": "Name",
            "Outlet": "Outlet",
            "case_quantity_label": "Case Quantity",
            "case_level_label": "Case Level",
            "single_level_label": "Single Level",
            "total_single_label": "Total Singles",
            "last_case_cost_ex_label": "Last Case Cost (Ex)",
            "last_case_cost_label": "Last Case Cost",
            "Stock Value (Ex) (Last)": "Stock Value (Ex) (Last)",
            "Stock Value (Inc) (Last)": "Stock Value (Inc) (Last)"
        },
        "data": [
            {
                "ID": "11e8b1c2d3e44f5a9b6c7d8e9f0a1b2c",
                "Name": "Pale Ale 6 Pack",
                "Outlet": "Main Store",
                "Case Quantity": 4,
                "Case Level": 6,
                "Single Level": 0,
                "Total Singles": 24,
                "Last Case Cost (Ex)": 12.5,
                "Last Case Cost": 13.75,
                "Stock Value (Ex) (Last)": 75,
                "Stock Value (Inc) (Last)": 82.5
            }
        ],
        "groups": [],
        "totals": {
            "Stock Value (Ex) (Last)": 75,
            "Stock Value (Inc) (Last)": 82.5
        }
    }
}