Power BI Integration: Automatically Refresh Data with n8n and Make.com
How to integrate Power BI into your automation workflows.
Power BI is Microsoft's Business Intelligence solution - powerful, but often isolated from other systems. In this guide, we show you how to connect Power BI with automation: automatically refresh data, distribute reports, and send alerts when KPIs change.
Why Automate Power BI?
Typical Problems:| Problem | Manual Effort | Automated Solution |
|---|---|---|
| Data Refresh | Daily manual | Automatic on change |
| Report Distribution | Email export | Automatic delivery |
| KPI Monitoring | Check dashboard | Proactive alerts |
| Data Source Sync | Maintain ETL jobs | Event-based updates |
Power BI REST API Basics
Setting Up API Access
- Azure Portal -> App registrations -> New registration
- Name: "Power BI Automation"
- Redirect URI: https://n8n.your-domain.com/oauth2/callback
- API permissions -> Add permission -> Power BI Service
- Delegated: Dataset.ReadWrite.All, Report.Read.All
- Certificates & secrets -> New client secret
- Copy and store secret securely
Authentication
// Get OAuth2 token
const tokenResponse = await fetch('https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
scope: 'https://analysis.windows.net/powerbi/api/.default',
grant_type: 'client_credentials'
})
});
const { access_token } = await tokenResponse.json();
Workflow 1: Automatic Dataset Refresh
The Goal
Automatically refresh datasets when source data changes.
Trigger Options
Option A: Scheduled
Schedule (daily 6:00 AM)
|
Power BI: Dataset Refresh
Option B: Event-based
Database (new data)
|
Power BI: Dataset Refresh
Option C: Webhook
External System (Webhook)
|
Power BI: Dataset Refresh
n8n Implementation
Node 1: Trigger (Schedule or Webhook) Node 2: Start Power BI Refresh// Node: HTTP Request
{
"method": "POST",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/datasets/{{ $env.DATASET_ID }}/refreshes",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}",
"Content-Type": "application/json"
},
"body": {
"notifyOption": "MailOnFailure"
}
}
Node 3: Check Refresh Status
// Power BI Refresh is async - query status
// Node: HTTP Request
{
"method": "GET",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/datasets/{{ $env.DATASET_ID }}/refreshes?$top=1",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}"
}
}
Node 4: Wait for Completion
// Node: Wait + Loop
const refreshStatus = $json.value[0].status;
if (refreshStatus === 'Completed') {
return { success: true };
} else if (refreshStatus === 'Failed') {
throw new Error('Refresh failed: ' + $json.value[0].serviceExceptionJson);
} else {
// Still in progress - check again
await wait(30000); // 30 seconds
// ... Loop
}
Workflow 2: Send Report via Email
The Goal
Automatically export reports as PDF and send via email.
The Workflow
Schedule (Monday 8:00 AM)
|
Power BI: Export report (PDF)
|
Wait for export
|
Download PDF
|
Send email with attachment
n8n Implementation
Step 1: Start Export// Node: HTTP Request
{
"method": "POST",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/reports/{{ $env.REPORT_ID }}/ExportTo",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}",
"Content-Type": "application/json"
},
"body": {
"format": "PDF",
"powerBIReportConfiguration": {
"pages": [
{ "pageName": "ReportSection1" }
]
}
}
}
Step 2: Check Export Status
// Node: HTTP Request (Loop until done)
{
"method": "GET",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/reports/{{ $env.REPORT_ID }}/exports/{{ $json.id }}",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}"
}
}
Step 3: Download PDF
// Node: HTTP Request (Binary)
{
"method": "GET",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/reports/{{ $env.REPORT_ID }}/exports/{{ $json.id }}/file",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}"
},
"responseFormat": "file"
}
Step 4: Send Email
// Node: Send Email
{
"to": "management@company.com",
"subject": "Weekly Sales Report - Week {{ $now.weekNumber }}",
"body": "Please find the current sales report attached.",
"attachments": [
{
"filename": "Sales-Report-Week{{ $now.weekNumber }}.pdf",
"data": "{{ $binary.data }}"
}
]
}
Workflow 3: KPI Alerts
The Goal
Get notified when KPIs exceed or fall below certain thresholds.
The Workflow
Schedule (hourly)
|
Power BI: Execute DAX query
|
Check KPI values
|
Threshold exceeded?
|
Yes: Send alert (Slack/Email)
Execute DAX Query
// Node: HTTP Request
{
"method": "POST",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/datasets/{{ $env.DATASET_ID }}/executeQueries",
"headers": {
"Authorization": "Bearer {{ $json.access_token }}",
"Content-Type": "application/json"
},
"body": {
"queries": [
{
"query": "EVALUATE SUMMARIZECOLUMNS('Date'[Month], 'Sales'[Total Revenue], 'Sales'[Order Count])"
}
],
"serializerSettings": {
"includeNulls": true
}
}
}
Alert Logic
// Node: Code
const results = $json.results[0].tables[0].rows;
const currentMonth = results[results.length - 1];
const alerts = [];
// Revenue Check
if (currentMonth['Sales[Total Revenue]'] < 100000) {
alerts.push({
type: 'warning',
kpi: 'Revenue',
value: currentMonth['Sales[Total Revenue]'],
threshold: 100000,
message: 'Revenue below target!'
});
}
// Order Count Check
if (currentMonth['Sales[Order Count]'] < 500) {
alerts.push({
type: 'critical',
kpi: 'Orders',
value: currentMonth['Sales[Order Count]'],
threshold: 500,
message: 'Orders critically low!'
});
}
return { alerts, hasAlerts: alerts.length > 0 };
Slack Alert
// Node: Slack (when hasAlerts = true)
{
"channel": "#kpi-alerts",
"attachments": [
{
"color": "{{ $json.alerts[0].type === 'critical' ? 'danger' : 'warning' }}",
"title": "KPI Alert",
"fields": $json.alerts.map(a => ({
"title": a.kpi,
"value": ${a.value} (Target: ${a.threshold}),
"short": true
}))
}
]
}
Workflow 4: Push Data to Power BI
Create Push Datasets
Power BI supports push datasets for real-time data:
// Create dataset
{
"method": "POST",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/datasets",
"body": {
"name": "Real-Time Sales",
"defaultMode": "Push",
"tables": [
{
"name": "Sales",
"columns": [
{ "name": "Timestamp", "dataType": "DateTime" },
{ "name": "Product", "dataType": "String" },
{ "name": "Amount", "dataType": "Double" },
{ "name": "Quantity", "dataType": "Int64" }
]
}
]
}
}
Push Data
// On new order: Send data to Power BI
{
"method": "POST",
"url": "https://api.powerbi.com/v1.0/myorg/groups/{{ $env.WORKSPACE_ID }}/datasets/{{ $env.PUSH_DATASET_ID }}/tables/Sales/rows",
"body": {
"rows": [
{
"Timestamp": "{{ $now.toISO() }}",
"Product": "{{ $json.product_name }}",
"Amount": {{ $json.total }},
"Quantity": {{ $json.quantity }}
}
]
}
}
Make.com Scenario
Modules for Power BI
Make.com has native Power BI modules:
Example Scenario
Schedule (daily 6:00 AM)
|
Power BI: Refresh Dataset
|
Wait: 10 minutes
|
Power BI: Export Report to PDF
|
Wait: 5 minutes
|
Power BI: Get Export Status
|
Gmail: Send with Attachment
Integration with Other Data Sources
SQL Server -> Power BI
SQL Server (new data)
|
Trigger: New rows
|
Power BI: Dataset Refresh
Google Analytics -> Power BI
Schedule (daily)
|
Google Analytics: Get report
|
Transform data
|
Power BI: Push Dataset
Shopify -> Power BI (Real-time)
Shopify Webhook (new order)
|
Format data
|
Power BI: Push to Real-Time Dataset
Best Practices
1. Mind the Refresh Limits
| Power BI Plan | Refreshes/Day |
|---|---|
| Pro | 8 |
| Premium | 48 |
| Premium per User | 48 |
2. Error Handling
// Catch refresh errors
try {
await refreshDataset();
} catch (error) {
if (error.status === 429) {
// Rate limit - try again later
await wait(3600000); // 1 hour
} else if (error.status === 401) {
// Token expired - re-authenticate
await refreshToken();
} else {
await sendAlert(error);
}
}
3. Use Incremental Refresh
Instead of full refresh, only load new data:
Power BI Desktop:
- Enable Incremental Refresh
- Define RangeStart/RangeEnd parameters
- Only delta data is loaded
4. Monitor Gateway Status
// Check gateway status
const gateways = await fetch(
'https://api.powerbi.com/v1.0/myorg/gateways',
{ headers: { 'Authorization': Bearer ${token} } }
);
for (const gateway of gateways.value) {
if (gateway.publicKey === null) {
await sendAlert(Gateway ${gateway.name} is offline!);
}
}
Costs
| Component | Cost |
|---|---|
| Power BI Pro | $10/User/Month |
| Power BI Premium | From $4,995/Month |
| n8n Cloud | From $20/Month |
| Make.com | From $9/Month |
Conclusion
Power BI automation enables:
- Real-time data updates
- Automatic report distribution
- Proactive KPI monitoring
- Integration with other systems
Next Steps
We can help you with Power BI automation, from setup to production use.