agentsclimarketplace

Fabric rest api

Skill wardawgmalvicious/claude-config/skills/fabric-rest-api

Personal Claude Code config — skills, subagents, hooks, and rules for Microsoft Fabric and Power BI workflows on Windows. Cherry-pickable, no semver.

Install
npx -y skills add wardawgmalvicious/claude-config --skill fabric-rest-api

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use for Microsoft Fabric REST API patterns: listing and paginating workspaces/items with continuationToken/continuationUri, calling /v1/workspaces/{wsId}/items, handling long-running operations (202 Accepted, Location header, polling /v1/operations/{id}, Retry-After, /result), the runtime item ID vs .platform logicalId distinction (PowerBIEntityNotFound root cause), the 201-or-202 create pattern, jobType values for /jobs/instances (RunNotebook, Pipeline, SparkJob, Refresh — NOT DefaultJob), the `definition` envelope and `?updateMetadata=true` `.platform` flag, job scheduling (Daily/Weekly/Monthly), 429 rate limiting with Retry-After, capacity assignment, and the GA `sensitivityLabel` field on List/Get/Update Item responses (GUID only, not settable via PATCH).

SKILL.md

12.7 KB, as published. Nobody here has run it

Fabric REST API patterns

Base URL: https://api.fabric.microsoft.com/v1

Finding Workspaces and Items

  1. List workspaces: GET /v1/workspaces → paginate with continuationToken
  2. Find by name: iterate results until displayName matches
  3. List items in workspace: GET /v1/workspaces/{wsId}/items?type={ItemType}
  4. Type-specific endpoints return extra properties (connection strings, etc.): GET /v1/workspaces/{wsId}/{lakehouses|warehouses|notebooks|semanticModels|...}
  5. Cross-workspace discovery (no wsId in path): POST /v1/catalog/search with { "search": "Sales Revenue", "pageSize": 50, "filter": "Type eq 'Lakehouse'" } → permission-trimmed items (each with id GUID + workspaceId) across your whole accessible estate, by catalog metadata (name/description/workspace name). OneLake Catalog Search API (Preview, March 2026); same capability as the fab find CLI verb (fabric-cli skill) and the Fabric Core MCP server's search_catalog tool.

Sensitivity Labels on Item Responses

As of March 2026 GA, List Items / Get Item / Update Item responses include a sensitivityLabel property on the Item object when the item has a Purview information-protection label applied:

{
  "id": "34fa05fc-e7ba-435a-b1ab-63534b6aa4f9",
  "displayName": "PDF_Env",
  "type": "Environment",
  "workspaceId": "2ae4b0b9-895b-4676-bfcd-125b1f20e34d",
  "sensitivityLabel": { "sensitivityLabelId": "4922deb9-fe99-4f4f-971c-9bdf556ec6a9" }
}

Field name gotcha — spec vs runtime drift. The MS Learn Item definition page documents this inner field as id, but the live API returns sensitivityLabelId. Verified across 233 labeled items in 7 workspaces (May 2026) on both GET /v1/workspaces/{wsId}/items and GET /v1/workspaces/{wsId}/items/{itemId} — 233/233 use sensitivityLabelId. Trust the runtime, not the schema page.

The sensitivityLabel object carries only the label GUID — there is no displayName / name on the response. Resolving the GUID to a human-readable label name requires a separate call (Microsoft Graph /security/informationProtection/sensitivityLabels or Purview). The sensitivityLabel field is omitted entirely on unlabeled items.

Read-only on these endpoints. The Update Item PATCH body schema (UpdateItemRequest) accepts only displayName and description — it does NOT accept a sensitivityLabel field. To apply, change, or remove labels programmatically, call the admin APIs POST /v1/admin/labels/bulkSetLabels / bulkRemoveLabels (require Tenant.ReadWrite.All + Fabric admin role; ≤ 25 req/hour, ≤ 2000 items/request).

Item IDs: Runtime vs logicalId

Every Fabric item has two GUIDs, and they are NOT interchangeable. Using the wrong one is a leading cause of PowerBIEntityNotFound / EntityNotFound errors when referencing items by ID from a pipeline, notebook parameter, REST call, or Variable Library variable.

IdentifierSourceResolved byUse for
Runtime item IDFabric portal URL (…/items/{guid}); GET /v1/workspaces/{wsId}/items response idThe Fabric engine at execution timePipeline activity notebookId / pipelineId, Variable Library values consumed at runtime, REST /items/{id} calls, notebookutils.runtime.context lookups
logicalId.platform file → config.logicalIdGit integration / source-control tooling.platform payloads, PBIP + pbir-cli + fab import source-control operations

The two values can look visually similar — Git integration sometimes derives one as a byte-swapped permutation of the other (segments reshuffled) — but Fabric will NOT silently fall back from one to the other at runtime.

Rule of thumb: if the value ends up in a payload the Fabric engine reads (pipeline definition, Variable Library value, REST body), use the runtime item ID. If it ends up in a file the Git integration layer reads (.platform, PBIP manifest), use the logicalId.

To fetch the runtime ID:

  • Portal: open the item, copy the trailing GUID from the URL
  • REST: GET /v1/workspaces/{wsId}/items → find by displayName, return id
  • fab CLI: fab get "Workspace.Workspace/Item.ItemType" -q id

Variable Library specifically: variable string values are passed verbatim to consumers — they are NOT resolved against .platform logicalIds. Always store the runtime item ID.

Long-Running Operations (LRO)

Many mutating calls return 202 Accepted with Location and x-ms-operation-id headers.

  • Poll: GET /v1/operations/{operationId}status: Running|Succeeded|Failed
  • Get result: GET /v1/operations/{operationId}/result (after Succeeded)
  • Honor Retry-After header. Use exponential backoff if absent.

Item creation is 201-OR-202, not "always sync" or "always LRO" — the same endpoint can return either depending on current provisioning load. Always branch on status code; never assume sync. A function that only inspects the body on 2xx will silently return before the item is queryable whenever Fabric picks the LRO path, racing any immediately-downstream call that expects the new item to exist.

Canonical create_* pattern for Fabric item creation:

def create_item(access_token: str, item_name: str, ...) -> str:
    """Return the newly-created item's GUID. Handles 201 and 202."""
    workspace_id = notebookutils.runtime.context["currentWorkspaceId"]
    endpoint = f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/<items_path>"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json",
    }
    body = {"displayName": item_name}

    response = requests.post(endpoint, headers=headers, json=body)

    if response.status_code == 201:
        # Synchronous creation — the body is the created item
        item_id = response.json()["id"]
    elif response.status_code == 202:
        # LRO — poll to completion, then fetch /result for the item body
        result_response = poll_lro(response, headers, return_result=True)
        item_id = result_response.json()["id"]
    else:
        response.raise_for_status()

    return item_id

The poll_lro helper honors Retry-After, polls Location until the operation reaches Succeeded, and (with return_result=True) fetches /result to return the actual created-item body.

Definition APIs

Item types with content (Notebook, SemanticModel, Report, DataPipeline) accept a definition object containing format, parts, and base64-encoded payloads.

PATCH /v1/workspaces/{wsId}/items/{itemId}/definition[?updateMetadata=true]
  • ?updateMetadata=true controls whether .platform is honored. Without it, any .platform part in definition.parts is silently ignored — displayName/description won't update.
  • Conversely, setting ?updateMetadata=true requires a .platform part. The flag without .platform returns 400.
  • For content-only updates (typical), omit the flag.
  • Notebook-specific alternative: POST /v1/workspaces/{wsId}/notebooks/{id}/updateDefinition — same body shape.
  • getDefinition is a POST with empty body ('{}') — bare POST returns HTTP 411 Length Required. Result is fetched via the LRO's {Location}/result URL (note the /result suffix).
  • Per-item-type specifics live in fabric-tmdl-api (semantic models), fabric-spark (notebooks, SparkJobDefinition, Environment, Lakehouse shortcuts), fabric-eventhouse (Eventhouse, KQLDatabase), fabric-variable-library (VariableLibrary), and pbir-cli/pbir-report-workflow (Report).

Support matrix

Item TypeFormatsMain parts
Notebookipynb (default), FabricGitSourcenotebook-content.ipynb or .py/.sql/.scala/.r
DataPipeline(default)pipeline-content.json
SemanticModelTMSL, TMDL (prefer)definition/database.tmdl, model.tmdl, tables/*.tmdl, definition.pbism
ReportPBIR-Legacy, PBIR (prefer)definition/report.json, version.json, pages/*, definition.pbir
LakehouseLakehouseDefinitionV1lakehouse.metadata.json (+ optional shortcuts.metadata.json)
SparkJobDefinitionSparkJobDefinitionV1, SparkJobDefinitionV2SparkJobDefinitionV1.json (+ Main/, Libs/ for V2)
Environment(default — set null)Libraries/PublicLibraries/environment.yml, Setting/Sparkcompute.yml
VariableLibraryomit format entirelyvariables.json, settings.json, valueSets/<name>.json
EventhouseJSONEventhouseProperties.json
KQLDatabaseJSONDatabaseProperties.json (+ optional DatabaseSchema.kql)
Other (KQLDashboard, CopyJob, Dataflow, Eventstream, MirroredDatabase, GraphQLApi, etc.)variessee MS schema index

definition.pbir byConnection only: Fabric REST API supports only byConnection semantic-model references in PBIR. The byPath form (used locally with pbir-cli) is not accepted by the Fabric REST endpoints — switch to byConnection before deploying.

Job Execution

POST /v1/workspaces/{wsId}/items/{itemId}/jobs/instances?jobType={jobType}
Item TypejobType
NotebookRunNotebook
DataPipelinePipeline
SparkJobDefinitionSparkJob
SemanticModelRefresh

Gotcha: DefaultJob does NOT work for most item types. Use the type-specific value above.

Job Scheduling

POST /v1/workspaces/{wsId}/items/{itemId}/jobs/{jobType}/schedules

URL path is /jobs/{jobType}/schedules — NOT /jobs/instances/schedules. Body:

{
  "enabled": true,
  "configuration": {
    "startDateTime": "2026-01-01T06:00:00.000Z",
    "endDateTime":   "2027-01-01T06:00:00.000Z",
    "type": "Daily",
    "interval": 1,
    "localTimeZoneId": "UTC",
    "times": ["06:00"]
  }
}

enabled, configuration.startDateTime, configuration.endDateTime, and configuration.type are all required. Omitting endDateTime returns 400. typeDaily | Weekly | Monthly; Weekly also requires weekDays (array of day names). List with GET .../schedules; delete with DELETE .../schedules/{scheduleId}.

Rate Limiting

429 Too Many Requests includes a Retry-After header (seconds). Honor it; never tight-loop. Use exponential backoff with jitter when Retry-After is absent.

CategoryApproximate limit
Admin APIs200 req/hour per principal per tenant
OneLake (ADLS)Standard Azure Storage throttling, per workspace
Warehouse TDS~128 concurrent connections (varies by SKU)

Watch x-ms-ratelimit-remaining-* response headers to back off before hitting the limit.

Capacity

  • GET /v1/capacities — list available capacities. Filter state == "Active".
  • POST /v1/workspaces/{wsId}/assignToCapacity with { "capacityId": "..." } — assigns workspace to capacity.
  • Lakehouse, Warehouse, Notebook execution, and Spark Job Definitions all require workspace capacity. Without it, item creation returns FeatureNotAvailable.
  • After assignment, verify GET /v1/workspaces/{wsId} shows capacityAssignmentProgress: "Completed" before creating capacity-dependent items.

Pagination

All list APIs use continuation-token pagination. Keep calling with ?continuationToken={value} until the token is null. The response also includes continuationUri — the fully-formed next-page URL — which you can call directly without re-constructing the query string. The token itself is opaque; never modify it.

Reference

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.