Translytical task flows let end users automate actions — updating records, adding annotations, or triggering workflows in other systems — directly from a Power BI report, without leaving the report experience.
| Action Type | Example |
|---|---|
| Add data | Add a new customer record to a table and see it reflected in the report immediately |
| Edit data | Update a status field or annotation on an existing record |
| Delete data | Remove a customer record that is no longer needed |
| Call an external API | Post a Teams Adaptive Card, trigger a REST endpoint, or create a work item in an approvals pipeline |
Translytical task flows use Fabric User Data Functions to invoke Python functions from a Power BI report button. The function can read from and write to Fabric data sources, then return a string message displayed back to the user.
Power BI Report → Data Function Button → User Data Function (Python)
↓
Fabric SQL Database / Warehouse / Lakehouse
↓
(Optional) External API — Teams, REST
↓
Return string → Report auto-refreshes
| Data Source | Support |
|---|---|
| Fabric SQL Database | ✅ Recommended for write-back |
| Fabric Warehouse | ✅ |
| Fabric Lakehouse (files) | ✅ |
For most write-back scenarios, Microsoft recommends Fabric SQL Database — it performs well under the heavy read/write operations typical in reporting scenarios.
| Component | Purpose |
|---|---|
| Fabric SQL Database | Stores data with full history. All writes go here. |
| Lakehouse (optional) | Provides shortcuts to SQL tables for Direct Lake semantic models |
| Variable Library (optional) | Stores config values (webhook URLs, report URLs) separately from function code — update without republishing |
| User Data Functions | Python functions that handle write-back to SQL and post notifications |
| Power BI Semantic Model | Defines the data model, relationships, and measures |
| Power BI Report | The user interface — data function buttons trigger the workflow |
| Microsoft Teams | Receives Adaptive Card notifications with status changes and deep links back to the report |
Full tutorial: MS Learn — Tutorial: Create a translytical task flow
This tutorial creates a translytical task flow where a user adds a product description directly from a Power BI report. The description is written back to a SQL Database in Fabric.
- Go to your Fabric workspace → New item → SQL database
- Choose the Sample data option to load the AdventureWorksLT dataset
- Note the database name — you will use it when connecting the UDF
- In your workspace → New item → User Data Functions (under Develop data)
- Name it, for example:
sqlwriteback - Select New function
- Select Manage connections → Add data connection
- Select your
AdventureWorksLTdatabase → Connect - Note the auto-generated Alias — you will reference it in your function code
The function takes a product description and product model ID, validates input length, then inserts into the [SalesLT].[ProductDescription] table. It must return a str — Power BI displays this message to the user after execution.
import fabric.functions as fn
import uuid
udf = fn.UserDataFunctions()
@udf.connection(argName="sqlDB", alias="<YOUR_CONNECTION_ALIAS>")
@udf.function()
def write_one_to_sql_db(sqlDB: fn.FabricSqlConnection, productDescription: str, productModelId: int) -> str:
if len(productDescription) > 200:
raise fn.UserThrownError("Descriptions have a 200 character limit.", {"Description:": productDescription})
connection = sqlDB.connect()
cursor = connection.cursor()
insert_description_query = "INSERT INTO [SalesLT].[ProductDescription] (Description) OUTPUT INSERTED.ProductDescriptionID VALUES (?)"
cursor.execute(insert_description_query, productDescription)
results = cursor.fetchall()
cultureId = str(uuid.uuid4())
insert_model_description_query = "INSERT INTO [SalesLT].[ProductModelProductDescription] (ProductModelID, ProductDescriptionID, Culture) VALUES (?, ?, ?);"
cursor.execute(insert_model_description_query, (productModelId, results[0][0], cultureId[:6]))
connection.commit()
cursor.close()
connection.close()
return "Product description was added"- Select Publish
- Hover over the function in Functions explorer → select Run
- Provide sample values: a string for
productDescription, an integer (1–127) forproductModelId - Select Run and review output
- In Power BI Desktop → Get data → OneLake Catalog → SQL database → select your database
- Load these tables:
SalesLT.ProductDescription,SalesLT.ProductModel,SalesLT.ProductModelProductDescription - Choose DirectQuery mode (required for live data refresh after write-back)
- Add a Table visual with
ProductModel.NameandProductModelProductDescription.ProductModelID - Add an Input slicer visual — title it
Write a new product description - Insert a Blank button below the slicer
-
Select the button → Format button → expand Action → turn On
-
Set Type =
Data function -
Select your Workspace and Function Set (
sqlwriteback) -
Select your Data function (
write_one_to_sql_db) -
Map the parameters:
Parameter Value productDescriptionSelect the Write a new product descriptioninput slicerproductModelIdUse Conditional formatting (fx) → Field value → SalesLT.ProductModel > ProductModelID→ Summarization: Maximum -
Label the button
Enterin Format button → Style → Text -
Set Loading state text to
Submittingwith a Spinner icon
- Publish the report to your Fabric workspace
- If prompted with "data source missing credentials": open the semantic model → Settings → Data source credentials → Edit credentials → choose OAuth2 → Sign in
- Open the report in the Power BI web portal, select a product, write a description, and select Enter
Full tutorial: MS Learn — Tutorial: Create a status update workflow
This tutorial extends the pattern with a project tracking solution. Users update project status from a Power BI report. Each update writes to SQL history and sends a Teams Adaptive Card notification.
User selects project in report
→ Selects new status + adds notes
→ Selects "Update Status" button
→ UDF writes new row to [Status updates] table
→ UDF posts Adaptive Card to Teams
→ Report auto-refreshes to show updated status
The Request Update button sends a Teams notification to the project owner without writing to the database — useful for nudging someone to provide an update.
Run the following SQL in your Fabric SQL Database to create the project tracking schema:
-- Project table
CREATE TABLE [Project] (
[Project id] INT NOT NULL,
[Project name] NVARCHAR(200) NOT NULL,
[Priority] NVARCHAR(20),
[Project manager] NVARCHAR(100),
[Department] NVARCHAR(100),
[Is active] BIT,
CONSTRAINT PK_Project PRIMARY KEY NONCLUSTERED ([Project id])
);
-- Status history table (append-only — never update rows)
CREATE TABLE [Status updates] (
[Update id] INT NOT NULL,
[Project id] INT NOT NULL,
[Status] NVARCHAR(50) NOT NULL,
[Updated date] DATETIME2 NOT NULL,
[Updated by] NVARCHAR(100) NOT NULL,
[Notes] NVARCHAR(4000),
CONSTRAINT PK_StatusUpdates PRIMARY KEY NONCLUSTERED ([Update id])
);
-- View: latest status per project
CREATE VIEW [Project status] AS
SELECT
p.[Project id],
p.[Project name],
COALESCE(ls.[Latest status], 'Not Started') AS [Latest status],
ls.[Latest notes]
FROM [Project] p
LEFT JOIN (
SELECT
[Project id],
[Status] AS [Latest status],
[Notes] AS [Latest notes],
ROW_NUMBER() OVER (PARTITION BY [Project id] ORDER BY [Update id] DESC) AS RowNum
FROM [Status updates]
) ls ON p.[Project id] = ls.[Project id] AND ls.RowNum = 1;A Variable Library stores config values (like webhook URLs) outside your function code. When the URL changes, you update the library — no code republish needed.
-
Workspace → New item → Variable library
-
Name it
ProjectVariables -
Add the following variables:
Variable Name Type Purpose TEAMS_WEBHOOK_URLString Your Teams incoming webhook URL POWERBI_REPORT_URLString URL to your published Power BI report -
To get a Teams webhook URL, follow: Create an Incoming Webhook
⚠️ Anyone with the webhook URL can post to your Teams channel. Store it only in Variable Library — never hard-code it.
Create a User Data Functions item with two connections:
@udf.connection(argName="sqlDb", alias="ProjectTrackingDb") # → Fabric SQL Database
@udf.connection(argName="varLib", alias="ProjectVariables") # → Variable LibraryThe two key functions are:
Validates the new status value against the allowed list, inserts a new row into [Status updates], reads the previous status for comparison, and posts an Adaptive Card showing the transition (Previous → New).
Parameters: projectId, newStatus, updatedBy, notes, updatedDate
Allowed status values: Not Started · In Progress · On Hold · Completed · Cancelled
Queries project details (name, manager, current status), then posts a Teams card with an Update Status deep-link button pointing back to the report.
Parameters: projectId, requestedBy, message
Connect to the SQL database in Power BI Desktop using DirectQuery. Add visuals for project list, status slicer, notes input, and date picker. Then configure two data function buttons:
| Button | Function | Key Parameters |
|---|---|---|
| Update Status | update_project_status |
projectId → selected project ID · newStatus → status slicer · notes → notes input · updatedBy → fixed text (user name) |
| Request Update via Teams | request_status_update |
projectId → selected project ID · requestedBy → fixed text · message → message input |
For both buttons: enable "Refresh the report after a successful outcome" in Format button → Action.
Direct Lake mode cannot read SQL views — only tables. To use the [Project status] view with Direct Lake:
- Create a Lakehouse with schemas enabled
- Add shortcuts pointing to
[Project]and[Status updates]SQL tables - Create a Materialized Lake View in the Lakehouse that computes the latest status per project using Spark SQL
- Any write-back pattern: insert, update, upsert, soft-delete
- External API calls from within the UDF (Teams, REST APIs, Azure OpenAI, etc.)
- Full input validation with
fn.UserThrownError— error details shown to the user in the report - Auto-refresh of the report after a successful function call
- Loading button state with spinner icon during function execution
- User data functions must return a
strtype to be used in a report button - Power BI Embedded is supported only for secure embed scenarios
- Direct Lake cannot read SQL views directly — use Lakehouse shortcuts + materialized lake views
- Service limits apply: User data functions service limits
For users other than the report author to trigger data function buttons:
- On the User Data Functions page → Share
- Add users or groups
- Select Execute Functions and View Functions Logs from Additional permissions
- Select Send
| Symptom | Cause | Fix |
|---|---|---|
| "The data source is missing credentials" | Semantic model needs OAuth2 sign-in | SM → Settings → Data source credentials → Edit → OAuth2 → Sign in |
| "Something went wrong" on button click | Function error, timeout, or unauthorized user | Select View details in the error popup for the specific reason |
| Button stays disabled | No row selected in the table | Select a row in the report table to pass context to the button |
| Function not visible in button config | Function does not return str |
Ensure -> str is declared on the function signature |
| Teams notification not sent | Webhook URL is empty or invalid | Set TEAMS_WEBHOOK_URL in Variable Library (or _TEAMS_WEBHOOK_URL in function code) |
| Direct Lake fails on SQL views | Direct Lake cannot read views | Create Lakehouse shortcuts + materialized lake views |
| Resource | Link |
|---|---|
| Translytical Task Flow Overview | learn.microsoft.com |
| Tutorial 1 — Data Write-Back | learn.microsoft.com |
| Tutorial 2 — Status Update + Teams | learn.microsoft.com |
| Create a data function button in Power BI | learn.microsoft.com |
| User Data Functions Overview | learn.microsoft.com |
| User Data Functions Service Limits | learn.microsoft.com |
| Create a Fabric SQL Database | learn.microsoft.com |
| Fabric Variable Library | learn.microsoft.com |
| Create an Incoming Webhook (Teams) | learn.microsoft.com |
| Official UDF Code Samples (Gist) | github.com/Sujata994 |