Update Check — ONCE PER SESSION (mandatory)
The first time this skill is used in a session, run the check-updates skill before proceeding.
- GitHub Copilot CLI / VS Code: invoke the
check-updates skill.
- Claude Code / Cowork / Cursor / Windsurf / Codex: compare local vs remote package.json version.
- Skip if the check was already performed earlier in this session.
CRITICAL NOTES
- To find the workspace details (including its ID) from workspace name: list all workspaces and, then, use JMESPath filtering
- To find a dataflow by name: list all dataflows in the workspace and filter by
displayName client-side — there is no server-side name filter
getDefinition is a POST, not GET — even though it reads data
Dataflows Gen2 — Consumption via CLI
Table of Contents
| Task |
Reference |
Notes |
| Finding Workspaces and Items in Fabric |
COMMON-CLI.md § Finding Workspaces and Items in Fabric |
Mandatory — READ link first |
| Fabric Topology & Key Concepts |
COMMON-CORE.md § Fabric Topology & Key Concepts |
|
| Environment URLs |
COMMON-CORE.md § Environment URLs |
|
| Authentication & Token Acquisition |
COMMON-CORE.md § Authentication & Token Acquisition |
Wrong audience = 401; read before any auth issue |
| Core Control-Plane REST APIs |
COMMON-CORE.md § Core Control-Plane REST APIs |
Includes pagination, LRO polling, and rate-limiting patterns |
| Job Execution |
COMMON-CORE.md § Job Execution |
|
| Gotchas, Best Practices & Troubleshooting |
COMMON-CORE.md § Gotchas, Best Practices & Troubleshooting |
|
| Tool Selection Rationale |
COMMON-CLI.md § Tool Selection Rationale |
|
| Authentication Recipes |
COMMON-CLI.md § Authentication Recipes |
az login flows and token acquisition |
Fabric Control-Plane API via az rest |
COMMON-CLI.md § Fabric Control-Plane API via az rest |
Always pass --resource; includes pagination and LRO helpers |
| Job Execution (CLI) |
COMMON-CLI.md § Job Execution |
|
| Gotchas & Troubleshooting (CLI-Specific) |
COMMON-CLI.md § Gotchas & Troubleshooting (CLI-Specific) |
az rest audience, shell escaping, token expiry |
| Quick Reference |
COMMON-CLI.md § Quick Reference |
az rest template + token audience/tool matrix |
| Consumption Capability Matrix |
DATAFLOWS-CONSUMPTION-CORE.md § Consumption Capability Matrix |
Read first — shows what ops are available |
| REST API Surface (Consumption) |
DATAFLOWS-CONSUMPTION-CORE.md § REST API Surface |
List, Get, Parameters, getDefinition, Jobs |
| Dataflow Definition Exploration |
DATAFLOWS-CONSUMPTION-CORE.md § Dataflow Definition Exploration |
Decode mashup.pq, queryMetadata.json, .platform |
| Parameter Discovery and Analysis |
DATAFLOWS-CONSUMPTION-CORE.md § Parameter Discovery and Analysis |
Types, formats, M code patterns |
| Refresh and Job Monitoring |
DATAFLOWS-CONSUMPTION-CORE.md § Refresh and Job Monitoring |
LRO pattern, job instances, polling best practices |
| Agentic Exploration Pattern |
DATAFLOWS-CONSUMPTION-CORE.md § Agentic Exploration Pattern |
6-step discovery sequence |
| Security and Permissions Model |
DATAFLOWS-CONSUMPTION-CORE.md § Security and Permissions Model |
Permission matrix by operation |
| Common Errors |
DATAFLOWS-CONSUMPTION-CORE.md § Common Errors |
Error codes and resolutions |
| Gotchas and Troubleshooting Reference |
DATAFLOWS-CONSUMPTION-CORE.md § Gotchas and Troubleshooting |
12 numbered issues with cause + resolution |
| Quick Reference One-Liners |
consumption-cli-quickref.md |
az rest one-liners for all consumption ops |
| Discovery Patterns |
discovery-queries.md |
Definition decoding, parameter extraction, connection analysis |
| Script Templates |
script-templates.md |
Copy-paste bash and PowerShell templates |
| Tool Stack |
SKILL.md § Tool Stack |
|
| Connection |
SKILL.md § Connection |
|
| Agentic Exploration ("Chat With My Dataflows") |
SKILL.md § Agentic Exploration |
Start here for dataflow exploration |
Tool Stack
| Tool |
Role |
Install |
az CLI |
Primary: Auth (az login), Fabric REST API via az rest |
Pre-installed in most dev environments |
curl |
Alternative HTTP client for REST calls |
Pre-installed |
jq |
Parse JSON responses, extract fields, format output |
Pre-installed or trivial |
base64 |
Decode definition parts from base64 |
Built into bash; PowerShell uses [Convert]::FromBase64String |
bash/pwsh |
Script execution |
Pre-installed |
Agent check — verify before first operation:
az account show >/dev/null 2>&1 || echo "RUN: az login"
command -v jq >/dev/null 2>&1 || echo "INSTALL: apt-get install jq OR brew install jq"
Connection
Resolve Workspace ID and Dataflow ID
Per COMMON-CLI.md Finding Workspaces and Items in Fabric:
# Find workspace ID by name
WS_ID=$(az rest --method get \
--resource "https://api.fabric.microsoft.com" \
--url "https://api.fabric.microsoft.com/v1/workspaces" \
--query "value[?displayName=='My Workspace'].id" --output tsv)
# Find dataflow ID by name within workspace
DF_ID=$(az rest --method get \
--resource "https://api.fabric.microsoft.com" \
--url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/dataflows" \
--query "value[?displayName=='Sales Data Pipeline'].id" --output tsv)
Reusable Connection Variables
# Set once at script top
WS_ID="<workspaceId>"
DF_ID="<dataflowId>"
API="https://api.fabric.microsoft.com/v1"
AZ="az rest --resource https://api.fabric.microsoft.com"
Agentic Exploration ("Chat With My Dataflows")
Discovery Sequence
Run these in order to fully explore a workspace's dataflows. See references/discovery-queries.md for extended patterns.
# 1. List workspaces → find target
az rest --method get --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces" --query "value[].{name:displayName, id:id}" -o table
# 2. List dataflows → enumerate all
az rest --method get --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces/$WS_ID/dataflows" \
--query "value[].{name:displayName, id:id, desc:description}" -o table
# 3. Get dataflow properties
az rest --method get --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces/$WS_ID/dataflows/$DF_ID"
# 4. Discover parameters
az rest --method get --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces/$WS_ID/dataflows/$DF_ID/parameters" \
--query "value[].{name:name, type:type, required:isRequired, default:defaultValue}" -o table
# 5. Get definition → decode mashup.pq
RESPONSE=$(az rest --method post --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces/$WS_ID/dataflows/$DF_ID/getDefinition")
echo "$RESPONSE" | jq -r '.definition.parts[] | select(.path=="mashup.pq") | .payload' | base64 --decode
# 6. Check job history
az rest --method get --resource "https://api.fabric.microsoft.com" \
--url "$API/workspaces/$WS_ID/items/$DF_ID/jobs/instances" \
--query "value[].{status:status, type:invokeType, start:startTimeUtc, end:endTimeUtc, error:failureReason}" -o table
Agentic Workflow
- Discover → Run Steps 1–3 to list and identify dataflows.
- Parameters → Step 4 to understand inputs and defaults.
- Definition → Step 5 to inspect M queries, connections, staging config.
- Monitor → Step 6 for refresh history and error patterns.
- Iterate → Drill into specific queries or connection details.
- Present → Summarize findings or generate a reusable script (see script-templates.md).
Gotchas, Rules, Troubleshooting
For full platform gotchas: DATAFLOWS-CONSUMPTION-CORE.md Gotchas and Troubleshooting Reference and COMMON-CLI.md Gotchas & Troubleshooting (CLI-Specific).
MUST DO
- Always
az login first — az rest uses the active session. No session → cryptic failure.
- Always
--resource "https://api.fabric.microsoft.com" — wrong audience = 401.
- Handle pagination — repeat requests with
continuationToken until absent/null.
- Handle LRO for
getDefinition — may return 202 Accepted with Location header; poll until complete.
- Decode base64 before inspecting — definition parts are base64-encoded.
- Use POST for
getDefinition — it is NOT a GET endpoint.
AVOID
- Hardcoded GUIDs — always discover via list-then-filter pattern.
- Assuming
getDefinition is GET — it is POST (common mistake).
- Ignoring pagination — list endpoints may return partial results.
- Polling too aggressively — respect
Retry-After headers on 429s.
- Expecting
getDefinition with Viewer role — requires Read+Write (Contributor+).
PREFER
az rest over raw curl — handles auth automatically.
- List-then-filter pattern — no server-side name filter for dataflows.
- Exponential backoff for job polling — 5s → 10s → 20s → 30s cap.
jq for response parsing — cleaner than shell string manipulation.
- JMESPath
--query for simple field extraction directly in az rest.
- Env vars (
WS_ID, DF_ID, API) for script reuse.
TROUBLESHOOTING
| Symptom |
Cause |
Fix |
401 Unauthorized |
Token expired or wrong audience |
az login; ensure --resource "https://api.fabric.microsoft.com" |
403 Forbidden on getDefinition |
Viewer role (Read-only) |
Requires Contributor role or higher (Read+Write) |
404 Not Found |
Wrong workspace or dataflow ID |
Re-discover via List Dataflows API |
getDefinition returns 202 |
Large definition or server load |
Poll the Location header URL until operation completes |
| Empty parameters array |
Dataflow has no parameters |
Expected behavior — check mashup.pq for IsParameterQuery |
| Base64 decode shows garbled text |
BOM in encoded content |
Strip UTF-8 BOM (\xEF\xBB\xBF) when decoding |
429 TooManyRequests |
Rate limited |
Respect Retry-After header; implement exponential backoff |
| Duplicate results in list |
Re-using stale continuationToken |
Always use the token from the most recent response |
OperationNotSupportedForItem |
Wrong item type |
Verify item is type Dataflow via Get Item |
Examples
Example 1: List All Dataflows in a Workspace
az rest --method get \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items?type=Dataflow" \
--resource "https://api.fabric.microsoft.com" \
--query "value[].{Name:displayName, Id:id, Type:type}" -o table
Example 2: Decode a Dataflow Definition
# Step 1: Request definition (POST — returns 202 with Location header)
LOCATION=$(az rest --method post \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items/${DF_ID}/getDefinition" \
--resource "https://api.fabric.microsoft.com" \
--headers "Content-Length=0" \
--output none --include-response-headers 2>&1 | grep -i "^location:" | awk '{print $2}' | tr -d '\r')
# Step 2: Poll until definition is ready
DEF=$(az rest --method get --url "${LOCATION}" \
--resource "https://api.fabric.microsoft.com")
# Step 3: Decode mashup.pq to see the Power Query M code
echo "$DEF" | python3 -c "
import json, base64, sys
parts = json.load(sys.stdin)['definition']['parts']
for p in parts:
if p['path'] == 'mashup.pq':
print(base64.b64decode(p['payload']).decode('utf-8'))
"
Example 3: Check Refresh Job History
# Get recent job instances for a dataflow
az rest --method get \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items/${DF_ID}/jobs/instances?limit=5" \
--resource "https://api.fabric.microsoft.com" \
--query "value[].{Status:status, Start:startTimeUtc, End:endTimeUtc, Id:id}" -o table
Example 4: Discover Parameters from Definition
# After decoding the definition (see Example 2), extract parameters:
echo "$DEF" | python3 -c "
import json, base64, sys
parts = json.load(sys.stdin)['definition']['parts']
for p in parts:
if p['path'] == 'queryMetadata.json':
meta = json.loads(base64.b64decode(p['payload']).decode('utf-8'))
for qname, qmeta in meta.get('queriesMetadata', {}).items():
if qmeta.get('queryGroupId') == 'parameters' or 'IsParameterQuery' in str(qmeta):
print(f'Parameter: {qname}')
"
1---2name: dataflows-consumption-cli3description: Monitor, inspect, and discover Fabric Dataflows Gen2 via read-only CLI operations (az rest / curl). List dataflows across workspaces, decode base64 definitions to inspect Power Query M queries and queryMetadata.json, discover typed parameters with defaults, poll refresh operations for status, retrieve job history with timing and error details, and classify queries by staging settings. Use when the user wants to: (1) list dataflows, (2) inspect a dataflow definition and decode its mashup, (3) discover parameters, (4) check refresh status, (5) retrieve job history, (6) analyze staging settings, (7) examine connections and data source bindings. Triggers: "dataflow status", "refresh history", "dataflow monitor", "list dataflows", "dataflow parameters", "explore dataflow", "inspect dataflow", "dataflow run status".4---56> **Update Check — ONCE PER SESSION (mandatory)**7> The first time this skill is used in a session, run the **check-updates** skill before proceeding.8> - **GitHub Copilot CLI / VS Code**: invoke the `check-updates` skill.9> - **Claude Code / Cowork / Cursor / Windsurf / Codex**: compare local vs remote package.json version.10> - Skip if the check was already performed earlier in this session.1112> **CRITICAL NOTES**13> 1. To find the workspace details (including its ID) from workspace name: list all workspaces and, then, use JMESPath filtering14> 2. To find a dataflow by name: list all dataflows in the workspace and filter by `displayName` client-side — there is no server-side name filter15> 3. `getDefinition` is a **POST**, not GET — even though it reads data1617# Dataflows Gen2 — Consumption via CLI1819## Table of Contents2021| Task | Reference | Notes |22|---|---|---|23| Finding Workspaces and Items in Fabric | [COMMON-CLI.md § Finding Workspaces and Items in Fabric](../../common/COMMON-CLI.md#finding-workspaces-and-items-in-fabric) | **Mandatory** — *READ link first* |24| Fabric Topology & Key Concepts | [COMMON-CORE.md § Fabric Topology & Key Concepts](../../common/COMMON-CORE.md#fabric-topology--key-concepts) ||25| Environment URLs | [COMMON-CORE.md § Environment URLs](../../common/COMMON-CORE.md#environment-urls) ||26| Authentication & Token Acquisition | [COMMON-CORE.md § Authentication & Token Acquisition](../../common/COMMON-CORE.md#authentication--token-acquisition) | Wrong audience = 401; read before any auth issue |27| Core Control-Plane REST APIs | [COMMON-CORE.md § Core Control-Plane REST APIs](../../common/COMMON-CORE.md#core-control-plane-rest-apis) | Includes pagination, LRO polling, and rate-limiting patterns |28| Job Execution | [COMMON-CORE.md § Job Execution](../../common/COMMON-CORE.md#job-execution) ||29| Gotchas, Best Practices & Troubleshooting | [COMMON-CORE.md § Gotchas, Best Practices & Troubleshooting](../../common/COMMON-CORE.md#gotchas-best-practices--troubleshooting) ||30| Tool Selection Rationale | [COMMON-CLI.md § Tool Selection Rationale](../../common/COMMON-CLI.md#tool-selection-rationale) ||31| Authentication Recipes | [COMMON-CLI.md § Authentication Recipes](../../common/COMMON-CLI.md#authentication-recipes) | `az login` flows and token acquisition |32| Fabric Control-Plane API via `az rest` | [COMMON-CLI.md § Fabric Control-Plane API via az rest](../../common/COMMON-CLI.md#fabric-control-plane-api-via-az-rest) | **Always pass `--resource`**; includes pagination and LRO helpers |33| Job Execution (CLI) | [COMMON-CLI.md § Job Execution](../../common/COMMON-CLI.md#job-execution) ||34| Gotchas & Troubleshooting (CLI-Specific) | [COMMON-CLI.md § Gotchas & Troubleshooting (CLI-Specific)](../../common/COMMON-CLI.md#gotchas--troubleshooting-cli-specific) | `az rest` audience, shell escaping, token expiry |35| Quick Reference | [COMMON-CLI.md § Quick Reference](../../common/COMMON-CLI.md#quick-reference) | `az rest` template + token audience/tool matrix |36| Consumption Capability Matrix | [DATAFLOWS-CONSUMPTION-CORE.md § Consumption Capability Matrix](../../common/DATAFLOWS-CONSUMPTION-CORE.md#consumption-capability-matrix) | **Read first** — shows what ops are available |37| REST API Surface (Consumption) | [DATAFLOWS-CONSUMPTION-CORE.md § REST API Surface](../../common/DATAFLOWS-CONSUMPTION-CORE.md#rest-api-surface-consumption) | List, Get, Parameters, getDefinition, Jobs |38| Dataflow Definition Exploration | [DATAFLOWS-CONSUMPTION-CORE.md § Dataflow Definition Exploration](../../common/DATAFLOWS-CONSUMPTION-CORE.md#dataflow-definition-exploration) | Decode mashup.pq, queryMetadata.json, .platform |39| Parameter Discovery and Analysis | [DATAFLOWS-CONSUMPTION-CORE.md § Parameter Discovery and Analysis](../../common/DATAFLOWS-CONSUMPTION-CORE.md#parameter-discovery-and-analysis) | Types, formats, M code patterns |40| Refresh and Job Monitoring | [DATAFLOWS-CONSUMPTION-CORE.md § Refresh and Job Monitoring](../../common/DATAFLOWS-CONSUMPTION-CORE.md#refresh-and-job-monitoring) | LRO pattern, job instances, polling best practices |41| Agentic Exploration Pattern | [DATAFLOWS-CONSUMPTION-CORE.md § Agentic Exploration Pattern](../../common/DATAFLOWS-CONSUMPTION-CORE.md#agentic-exploration-pattern-chat-with-my-dataflows) | 6-step discovery sequence |42| Security and Permissions Model | [DATAFLOWS-CONSUMPTION-CORE.md § Security and Permissions Model](../../common/DATAFLOWS-CONSUMPTION-CORE.md#security-and-permissions-model) | Permission matrix by operation |43| Common Errors | [DATAFLOWS-CONSUMPTION-CORE.md § Common Errors](../../common/DATAFLOWS-CONSUMPTION-CORE.md#common-errors) | Error codes and resolutions |44| Gotchas and Troubleshooting Reference | [DATAFLOWS-CONSUMPTION-CORE.md § Gotchas and Troubleshooting](../../common/DATAFLOWS-CONSUMPTION-CORE.md#gotchas-and-troubleshooting-reference) | 12 numbered issues with cause + resolution |45| Quick Reference One-Liners | [consumption-cli-quickref.md](references/consumption-cli-quickref.md) | `az rest` one-liners for all consumption ops |46| Discovery Patterns | [discovery-queries.md](references/discovery-queries.md) | Definition decoding, parameter extraction, connection analysis |47| Script Templates | [script-templates.md](references/script-templates.md) | Copy-paste bash and PowerShell templates |48| Tool Stack | [SKILL.md § Tool Stack](#tool-stack) ||49| Connection | [SKILL.md § Connection](#connection) ||50| Agentic Exploration ("Chat With My Dataflows") | [SKILL.md § Agentic Exploration](#agentic-exploration-chat-with-my-dataflows) | **Start here** for dataflow exploration |5152---5354## Tool Stack5556| Tool | Role | Install |57|---|---|---|58| `az` CLI | **Primary**: Auth (`az login`), Fabric REST API via `az rest` | Pre-installed in most dev environments |59| `curl` | Alternative HTTP client for REST calls | Pre-installed |60| `jq` | Parse JSON responses, extract fields, format output | Pre-installed or trivial |61| `base64` | Decode definition parts from base64 | Built into bash; PowerShell uses `[Convert]::FromBase64String` |62| `bash`/`pwsh` | Script execution | Pre-installed |6364> **Agent check** — verify before first operation:65> ```bash66> az account show >/dev/null 2>&1 || echo "RUN: az login"67> command -v jq >/dev/null 2>&1 || echo "INSTALL: apt-get install jq OR brew install jq"68> ```6970---7172## Connection7374### Resolve Workspace ID and Dataflow ID7576Per [COMMON-CLI.md](../../common/COMMON-CLI.md) Finding Workspaces and Items in Fabric:7778```bash79# Find workspace ID by name80WS_ID=$(az rest --method get \81 --resource "https://api.fabric.microsoft.com" \82 --url "https://api.fabric.microsoft.com/v1/workspaces" \83 --query "value[?displayName=='My Workspace'].id" --output tsv)8485# Find dataflow ID by name within workspace86DF_ID=$(az rest --method get \87 --resource "https://api.fabric.microsoft.com" \88 --url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/dataflows" \89 --query "value[?displayName=='Sales Data Pipeline'].id" --output tsv)90```9192### Reusable Connection Variables9394```bash95# Set once at script top96WS_ID="<workspaceId>"97DF_ID="<dataflowId>"98API="https://api.fabric.microsoft.com/v1"99AZ="az rest --resource https://api.fabric.microsoft.com"100```101102---103104## Agentic Exploration ("Chat With My Dataflows")105106### Discovery Sequence107108Run these in order to fully explore a workspace's dataflows. See [references/discovery-queries.md](references/discovery-queries.md) for extended patterns.109110```bash111# 1. List workspaces → find target112az rest --method get --resource "https://api.fabric.microsoft.com" \113 --url "$API/workspaces" --query "value[].{name:displayName, id:id}" -o table114115# 2. List dataflows → enumerate all116az rest --method get --resource "https://api.fabric.microsoft.com" \117 --url "$API/workspaces/$WS_ID/dataflows" \118 --query "value[].{name:displayName, id:id, desc:description}" -o table119120# 3. Get dataflow properties121az rest --method get --resource "https://api.fabric.microsoft.com" \122 --url "$API/workspaces/$WS_ID/dataflows/$DF_ID"123124# 4. Discover parameters125az rest --method get --resource "https://api.fabric.microsoft.com" \126 --url "$API/workspaces/$WS_ID/dataflows/$DF_ID/parameters" \127 --query "value[].{name:name, type:type, required:isRequired, default:defaultValue}" -o table128129# 5. Get definition → decode mashup.pq130RESPONSE=$(az rest --method post --resource "https://api.fabric.microsoft.com" \131 --url "$API/workspaces/$WS_ID/dataflows/$DF_ID/getDefinition")132echo "$RESPONSE" | jq -r '.definition.parts[] | select(.path=="mashup.pq") | .payload' | base64 --decode133134# 6. Check job history135az rest --method get --resource "https://api.fabric.microsoft.com" \136 --url "$API/workspaces/$WS_ID/items/$DF_ID/jobs/instances" \137 --query "value[].{status:status, type:invokeType, start:startTimeUtc, end:endTimeUtc, error:failureReason}" -o table138```139140### Agentic Workflow1411421. **Discover** → Run Steps 1–3 to list and identify dataflows.1432. **Parameters** → Step 4 to understand inputs and defaults.1443. **Definition** → Step 5 to inspect M queries, connections, staging config.1454. **Monitor** → Step 6 for refresh history and error patterns.1465. **Iterate** → Drill into specific queries or connection details.1476. **Present** → Summarize findings or generate a reusable script (see [script-templates.md](references/script-templates.md)).148149---150151## Gotchas, Rules, Troubleshooting152153For full platform gotchas: [DATAFLOWS-CONSUMPTION-CORE.md](../../common/DATAFLOWS-CONSUMPTION-CORE.md) Gotchas and Troubleshooting Reference and [COMMON-CLI.md](../../common/COMMON-CLI.md) Gotchas & Troubleshooting (CLI-Specific).154155### MUST DO156157- **Always `az login` first** — `az rest` uses the active session. No session → cryptic failure.158- **Always `--resource "https://api.fabric.microsoft.com"`** — wrong audience = 401.159- **Handle pagination** — repeat requests with `continuationToken` until absent/null.160- **Handle LRO for `getDefinition`** — may return `202 Accepted` with `Location` header; poll until complete.161- **Decode base64 before inspecting** — definition parts are base64-encoded.162- **Use POST for `getDefinition`** — it is NOT a GET endpoint.163164### AVOID165166- **Hardcoded GUIDs** — always discover via list-then-filter pattern.167- **Assuming `getDefinition` is GET** — it is POST (common mistake).168- **Ignoring pagination** — list endpoints may return partial results.169- **Polling too aggressively** — respect `Retry-After` headers on 429s.170- **Expecting `getDefinition` with Viewer role** — requires Read+Write (Contributor+).171172### PREFER173174- **`az rest` over raw `curl`** — handles auth automatically.175- **List-then-filter pattern** — no server-side name filter for dataflows.176- **Exponential backoff** for job polling — 5s → 10s → 20s → 30s cap.177- **`jq` for response parsing** — cleaner than shell string manipulation.178- **JMESPath `--query`** for simple field extraction directly in `az rest`.179- **Env vars** (`WS_ID`, `DF_ID`, `API`) for script reuse.180181### TROUBLESHOOTING182183| Symptom | Cause | Fix |184|---|---|---|185| `401 Unauthorized` | Token expired or wrong audience | `az login`; ensure `--resource "https://api.fabric.microsoft.com"` |186| `403 Forbidden` on `getDefinition` | Viewer role (Read-only) | Requires Contributor role or higher (Read+Write) |187| `404 Not Found` | Wrong workspace or dataflow ID | Re-discover via List Dataflows API |188| `getDefinition` returns `202` | Large definition or server load | Poll the `Location` header URL until operation completes |189| Empty parameters array | Dataflow has no parameters | Expected behavior — check mashup.pq for `IsParameterQuery` |190| Base64 decode shows garbled text | BOM in encoded content | Strip UTF-8 BOM (`\xEF\xBB\xBF`) when decoding |191| `429 TooManyRequests` | Rate limited | Respect `Retry-After` header; implement exponential backoff |192| Duplicate results in list | Re-using stale continuationToken | Always use the token from the most recent response |193| `OperationNotSupportedForItem` | Wrong item type | Verify item is type `Dataflow` via Get Item |194195---196197## Examples198199### Example 1: List All Dataflows in a Workspace200201```bash202az rest --method get \203 --url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items?type=Dataflow" \204 --resource "https://api.fabric.microsoft.com" \205 --query "value[].{Name:displayName, Id:id, Type:type}" -o table206```207208### Example 2: Decode a Dataflow Definition209210```bash211# Step 1: Request definition (POST — returns 202 with Location header)212LOCATION=$(az rest --method post \213 --url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items/${DF_ID}/getDefinition" \214 --resource "https://api.fabric.microsoft.com" \215 --headers "Content-Length=0" \216 --output none --include-response-headers 2>&1 | grep -i "^location:" | awk '{print $2}' | tr -d '\r')217218# Step 2: Poll until definition is ready219DEF=$(az rest --method get --url "${LOCATION}" \220 --resource "https://api.fabric.microsoft.com")221222# Step 3: Decode mashup.pq to see the Power Query M code223echo "$DEF" | python3 -c "224import json, base64, sys225parts = json.load(sys.stdin)['definition']['parts']226for p in parts:227 if p['path'] == 'mashup.pq':228 print(base64.b64decode(p['payload']).decode('utf-8'))229"230```231232### Example 3: Check Refresh Job History233234```bash235# Get recent job instances for a dataflow236az rest --method get \237 --url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items/${DF_ID}/jobs/instances?limit=5" \238 --resource "https://api.fabric.microsoft.com" \239 --query "value[].{Status:status, Start:startTimeUtc, End:endTimeUtc, Id:id}" -o table240```241242### Example 4: Discover Parameters from Definition243244```bash245# After decoding the definition (see Example 2), extract parameters:246echo "$DEF" | python3 -c "247import json, base64, sys248parts = json.load(sys.stdin)['definition']['parts']249for p in parts:250 if p['path'] == 'queryMetadata.json':251 meta = json.loads(base64.b64decode(p['payload']).decode('utf-8'))252 for qname, qmeta in meta.get('queriesMetadata', {}).items():253 if qmeta.get('queryGroupId') == 'parameters' or 'IsParameterQuery' in str(qmeta):254 print(f'Parameter: {qname}')255"256```