---
title: "Reports in Workflows & Dashboards"
url: https://flexie.io/resources/reports/reports-in-workflows-and-widgets
description: "A saved report is more than a page. It is a reusable data source for dashboards, for HTML reports, for workflow steps, and via the API for outside systems."
---

# Reports in Workflows & Dashboards

Last updated 25 May 2026

![A saved Flexie report feeding a dashboard widget, an HTML report, a workflow step, and an external API caller](https://flexie.io/image/resources/reports-reports-in-workflows-and-widgets.png)

A saved report is not only viewed on its own page. It is also a **data source** for dashboards, for HTML reports, for workflow steps, and (via the API) for outside systems.

## A report as a dashboard widget

The most common second life for a saved report is becoming a widget on a [dashboard](https://flexie.io/resources/dashboards/overview). Every **published** report automatically becomes available as a widget type. You don't have to do anything special. Add a widget to a dashboard, pick the report, and choose how it should render.

A report widget can be displayed in any of six ways:

* **Single value**: pull one cell from one column for a big-number tile.
* **Single number**: alias for Single value.
* **Line chart**: plot two columns as X and Y.
* **Bar chart**: plot two columns as category and value.
* **Pie chart**: plot two columns as label and slice value.
* **Grid**: the report's full result as a small table inside the widget.

The full configuration (axes, label or value columns, single-value column, optional limit) is covered in [Report widgets](https://flexie.io/resources/dashboards/report-widgets).

### What kinds of reports work as widgets

* **Data Grid reports** work as Grid, Line, Bar, Pie, or Single value widgets. The report's query is the data source; the widget configures how it is rendered.
* **HTML reports** work as **custom HTML widgets**. The whole rendered template appears as the widget contents. See [Custom HTML widgets](https://flexie.io/resources/dashboards/custom-html-widgets). This is the "any imaginable widget" route.

## Pulling a report's data from a Flexie Scripting context

If you want to use a report's data _inside_ something else (an HTML report that combines multiple reports, an email template, an automation step) you can call the saved report's data with the `getReportData(...)` function.

> The exact availability of `getReportData(...)` depends on which Flexie Scripting context you are in. It is available **inside HTML reports** and the report-render path. If you call it from a general workflow action and find it isn't recognised, fall back to writing the equivalent `query("SELECT ...")` in your script; `query(...)` works everywhere [Flexie Scripting](https://flexie.io/resources/flexie-scripting/overview) runs.

### Signature

```
getReportData(reportId, userId?, filters?, templateData?)

```

| Argument     | Meaning                                                                                                                                                                      |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reportId     | The numeric id of a saved report.                                                                                                                                            |
| userId       | Optional. If provided, the report's placeholder variables ({user\_id}, {group\_id}, {role\_id}, {timezone}) are resolved against _that_ user rather than the signed-in user. |
| filters      | Optional. An array of { alias, operator, value } objects, programmatic equivalents of what a user would fill into the report's filter row.                                   |
| templateData | Optional. Extra Flexie Scripting tokens you want resolved inside the report's query before it runs.                                                                          |

The function returns an array of rows, the same shape as the data grid would show; each row is a key-value map of column names to values. **Capped at 1,000 rows**, same as everything else.

### Using it inside an HTML report

The simplest pattern, re-use an existing aggregated report as a data feed:

```
{% set rows = getReportData(42) %}

<table>
  <tr><th>Owner</th><th>Total won</th></tr>
  {% for r in rows %}
    <tr><td>{{ r.owner_name }}</td><td>{{ r.total | number_format(0) }}</td></tr>
  {% endfor %}
</table>

```

…assuming report `42` is a saved data grid report whose query produces `owner_name` and `total` columns.

### Applying filters programmatically

```
{% set rows = getReportData(
    42,
    user_id,
    [
      { "alias": "status",  "operator": "eq", "value": "finalized" },
      { "alias": "country", "operator": "eq", "value": "DE" }
    ]
) %}

```

The filter aliases are the same as those defined in the saved report's [filters JSON](https://flexie.io/resources/reports/filters).

## Workflows reading a saved report

Workflows reach reports two ways.

### Inside a workflow action's Flexie Scripting fields

Any step's value, template, or condition fields are Flexie Scripting. You can pull report data there with `query(...)` and act on it.

```
{# Compute today's pipeline value for the contact's owner #}
{% set rows = query("
  SELECT SUM(amount) AS total
  FROM deals
  WHERE owner_id = " ~ owner_id ~ "
    AND is_won = 0 AND is_lost = 0
") %}

{% set pipelineValue = rows[0].total | default(0) %}

```

This isn't strictly using a _saved_ report; it is running an ad-hoc query. But the same access functions are available.

### Calling the API from a webhook

A workflow's **Webhook** action can call your own back-end, which in turn hits `/api/reports/{id}/data`. Useful if the report does something complex you don't want to recompute inline.

## Reports as a feed for other systems

Outside systems can read a report through the API:

* `GET /api/reports/{id}/data` returns the report's rows.
* Pass filter values as query parameters to apply them.
* The 1,000-row cap and the read-only restrictions still apply.

Use this when another team or a partner needs a snapshot of your data: they authenticate with a Flexie API token, pull the report's rows, and load them into their own system.

## Patterns that come up a lot

### A KPI feed for an external dashboard

1. Build a small **data grid** report: one row, a handful of columns. `SELECT (count_query) AS deals, (sum_query) AS pipeline, ...`.
2. Mark the report as **published** and give it a stable id.
3. Have the external dashboard call `/api/reports/{id}/data` on its refresh cycle.

### A bigger report feeding multiple smaller widgets

1. Build one **data grid** report that produces all the columns you would ever need (for example `owner_id, owner_name, won_count, won_total, open_count`).
2. Add it to a dashboard as five different widgets: Single value for each metric, Bar chart for the ranking.
3. Every widget shares one query, one data source, one update. Fast and consistent.

### An HTML report that combines multiple sources

1. Build an **HTML report** that calls `query(...)` (or `getReportData(...)`) multiple times for the different sections of a single page.
2. Render the results as your own custom layout: KPI cards across the top, tables in the middle, a chart at the bottom.
3. Drop that HTML report on a dashboard as a custom HTML widget. See [Custom HTML widgets](https://flexie.io/resources/dashboards/custom-html-widgets).

## Next steps

* [Dashboards](https://flexie.io/resources/dashboards/overview): where reports usually end up.
* [Dashboards: report widgets](https://flexie.io/resources/dashboards/report-widgets): the six visualisation subtypes in detail.
* [Dashboards: custom HTML widgets](https://flexie.io/resources/dashboards/custom-html-widgets): using an HTML report as a fully custom widget.
