Power BI Dataset Refresh Trigger
Triggers a Power BI dataset refresh when new data arrives in SharePoint or SQL Server. Sends a Teams notification when the refresh completes or fails, ensuring dashboards are always current.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
Kicks off a Power BI dataset refresh the moment a new row lands in a SharePoint list (the "data inbox" pattern), polls the Power BI Service for completion, then reports the outcome to Teams and (on failure) to an admin email. The flow ships as a Dataverse-aware solution and is built through an API-first pipeline — no designer authoring required.
Power BI is intentionally not wired in as a Power Platform connector here. The native Power BI connector requires an interactive user license at design time and frequently fails solution import when the target tenant lacks the right license SKU. This flow uses an HTTP action with ActiveDirectoryOAuth against the Power BI REST API instead — all it needs is an Entra app registration with Tenant.Read.All and workspace contributor rights on the target workspace.
The flow ships in the Stopped state. Consumers wire up the 12 flowlibs_-prefixed environment variables (workspace, dataset, SharePoint site/list, Teams group/channel, admin email, tenant/client/secret, polling budgets), authorize the SharePoint / Teams / Office 365 connection references, grant the Entra app Power BI workspace contributor rights, then turn the flow on.
Use Case
Use this flow whenever a Power BI dataset needs to refresh in response to upstream data landing — not on a fixed schedule. A SharePoint list acts as the "data inbox": any system that drops a new row triggers a refresh within minutes, the flow polls the Power BI Service until the refresh reports Completed or Failed, and the outcome is broadcast to a Teams channel (with an admin email escalation on failure). Because the Power BI call is HTTP + service principal, the same pattern works in tenants where the Power BI Power Automate connector is unlicensed or blocked.
The flow is ideal for teams that:
- Data engineering and BI teams who need dashboards to reflect upstream data without waiting for a scheduled refresh window
- Operations teams whose downstream reports must be current the moment new source data lands
- Tenants where the native Power BI Power Automate connector is unlicensed, blocked, or unreliable and a service-principal HTTP pattern is preferred
- Admins who want Teams + email visibility into every refresh outcome (success or failure) without opening the Power BI Service UI
Flow Architecture
When a new item arrives in SharePoint
SharePoint — GetOnNewItems (3-minute poll)Polls a tenant-scoped SharePoint list every 3 minutes for new items. The list URL is read from `flowlibs_SPSiteUrl` and the list GUID from `flowlibs_RefreshTriggerSPListId`, so the same flow can target any list without editing the definition.
Initialize state variables
Initialize variable (x9)Loads workspace ID, dataset ID, Teams group/channel, admin email, polling budgets (`varMaxPollAttempts`, `varPollDelaySeconds`), refresh status (`varRefreshStatus`), poll-attempt counter (`varPollAttempt`), and the triggering item title into runtime variables, all sourced from `flowlibs_*` environment variables.
Start Power BI dataset refresh
HTTP (POST, ActiveDirectoryOAuth)POSTs to `https://api.powerbi.com/v1.0/myorg/groups/{workspaceId}/datasets/{datasetId}/refreshes` with body `{ "notifyOption": "NoNotification" }`. Authenticates with `ActiveDirectoryOAuth` using `flowlibs_GraphTenantId`, `flowlibs_GraphClientId`, and the secure `flowlibs_GraphClientSecret`. Audience is `https://analysis.windows.net/powerbi/api`.
Poll refresh status until done
Until loopFor each iteration: Wait `varPollDelaySeconds` seconds → HTTP GET `…/refreshes?$top=1` with the same `ActiveDirectoryOAuth` → ParseJson the response → set `varRefreshStatus` from `first(value)?['status']` (coalesced to `Unknown`) → increment `varPollAttempt`. Loop exits when `varRefreshStatus` equals `Completed` or `Failed`, or when `varPollAttempt >= varMaxPollAttempts`. Loop has a safety ceiling of 60 iterations / 1 hour.
If refresh completed
If conditionBranches on whether `varRefreshStatus` equals `Completed`. Success posts a Teams card; any other status (Failed, Unknown, or timed-out polling) posts a Teams alert and a High-importance admin email.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_PowerBIWorkspaceId | String | <configure> | Target Power BI workspace (group) GUID. |
| flowlibs_PowerBIDatasetId | String | <configure> | Target Power BI dataset GUID to refresh. |
| flowlibs_SPSiteUrl | String | https://your-tenant.sharepoint.com | SharePoint site hosting the trigger list (the "data inbox"). |
| flowlibs_RefreshTriggerSPListId | String | 00000000-0000-0000-0000-000000000000 | GUID of the SharePoint list whose new items trigger a refresh. |
| flowlibs_TeamsGroupId | String | <configure> | Teams Team/Group ID where notifications are posted. |
| flowlibs_TeamsChannelId | String | <configure> | Teams Channel ID where notifications are posted. |
| flowlibs_AdminNotificationEmail | String | alerts@yourcompany.com | Email address that receives the High-importance failure escalation. |
| flowlibs_GraphTenantId | String | <your-tenant-id> | Entra tenant ID used by ActiveDirectoryOAuth for the Power BI REST calls. |
| flowlibs_GraphClientId | String | 00000000-0000-0000-0000-000000000000 |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| SharePoint | shared_sharepointonline | GetOnNewItems (trigger — 3-minute poll on the SharePoint trigger list) |
| Microsoft Teams | shared_teams | PostMessageToChannel (success card) PostMessageToChannel (failure alert card) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (High-importance admin failure email) |
| HTTP (ActiveDirectoryOAuth) | http | POST /datasets/{id}/refreshes (starts the Power BI refresh) GET /datasets/{id}/refreshes?$top=1 (polls refresh history inside the Until loop) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Switch from SharePoint trigger to a recurrence
- If you want refreshes on a fixed cadence instead of on data arrival, swap the SharePoint GetOnNewItems trigger for a Recurrence trigger and remove the varTriggeringItemTitle coalesce in the Teams/email message bodies.
- Tune the polling budget
- flowlibs_RefreshPollMaxAttempts x flowlibs_RefreshPollDelaySeconds is the worst-case wait time before the flow gives up. Defaults are 10 x 30 s = 5 minutes. Increase for large datasets; decrease to fail fast on small ones.
- Mark HTTP actions as Secure Inputs/Outputs
- ActiveDirectoryOAuth blocks are not redacted by default, so workspace and dataset GUIDs (and the bearer token in transit) appear in run history. If your tenant treats those as sensitive, enable Secure Inputs and Secure Outputs on both HTTP actions.
- Replace HTTP + service principal with the native Power BI connector
- If your tenant has the right Power BI license SKU and you prefer a user-delegated connection, replace the two HTTP actions with the Power BI connector's Refresh a dataset and Get refresh history actions. You can then drop the four flowlibs_Graph* env vars.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Power BI refresh URL
Builds the POST URI for starting a dataset refresh from the runtime variables loaded from `flowlibs_PowerBIWorkspaceId` and `flowlibs_PowerBIDatasetId`.
EXPR.02Refresh history (latest) URL
Builds the GET URI used inside the Until loop to fetch only the most recent refresh history entry.
EXPR.03Until loop exit expression
Exits the polling loop on terminal status (`Completed` or `Failed`) or when the poll-attempt counter reaches the configured maximum.
EXPR.04Coalesce status from refresh history
Reads the most recent refresh row's `status` field, defaulting to `Unknown` so the loop can exit gracefully if the response is empty.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.