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

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. 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:

The full configuration (axes, label or value columns, single-value column, optional limit) is covered in Report widgets.

What kinds of reports work as widgets

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 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.

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:

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.

Next steps