Tutorial: Add Version Metadata to a Federated Speckle Model in Power BI

This tutorial evolved from a conversation in broken Spanish (non-existent, it was all using Google) on the Speckle Help chat with Damian Díaz from Argentina. Thanks, Damian, for raising a great question about how to manage version metadata across federated models in PowerBI.

versions

This guide shows how to:

  1. Load individual versions of a model
  2. Federate them using Speckle.Models.Federate helper function, recently added.
  3. Fetch version metadata via GraphQL
  4. Enable filtering by version in the 3D visual

Note: This tutorial mentions Power BI’s Model View, which is the relationships diagram and not referring to the 3D model viewer.


Step 1: Load Individual Versions

For simplicity, each model version I want to include has its query. Here’s an example:

let
    versionUrl = "https://app.speckle.systems/projects/3b81e5731b/models/684f61a8e2@645c8a8c0a",
    parsedUrl = Speckle.Parser(versionUrl),
    versionId = parsedUrl[versionId],
    Source = Speckle.GetByUrl(versionUrl),
    #"June 4" = Table.AddColumn(Source, "versionId", each versionId)
in
    #"June 4"

This is slightly more involved than simply GetByUrl but all it is doing is adding the specific versionId that you can get if you copy the link from the Versions view on app.speckle.systems.

Repeat this for additional versions (like June 5) and name the queries accordingly.


Step 2: Create a Federated Dataset

Use the Speckle.Models.Federate helper to combine multiple versions into one unified table:

let
    Source = Speckle.Models.Federate({#"June 4", #"June 5"}, false)
in
    Source

This query returns a flat table of all objects, automatically tagged with their versionId.

Rename this query to Federation.


Step 3: Fetch Version Metadata

Use GraphQL to query metadata (date and message) for each version in the model:

let
    modelUrl = BaseUrl,
    parsedUrl = Speckle.Parser(BaseUrl),
    projectId = parsedUrl[projectId],
    modelId = parsedUrl[modelId],

    versionsQuery = "query GetModelVersionMetadata($projectId: String!, $modelId: String!) {
        project(id: $projectId) {
            model(id: $modelId) {
                versions {
                    items {
                        id
                        createdAt
                        message
                    }
                }
            }
        }
    }",

    versionMetadataVariables = [
        projectId = projectId,
        modelId = modelId
    ],

    versionMetadataResponse = Speckle.Api.Fetch(parsedUrl[baseUrl], versionsQuery, versionMetadataVariables),
    versions = versionMetadataResponse[project][model][versions],
    metadataTable = Table.ExpandRecordColumn(
        Table.ExpandListColumn(
            Record.ToTable(versions), "Value"
        ),
        "Value", {"id", "createdAt", "message"},
        {"Version ID", "Version Date", "Version Message"}
    ),
    cleaned = Table.TransformColumns(metadataTable, {
        {"Version Date", each Date.From(DateTimeZone.From(_)), type date}
    })
in
    cleaned

Name this query Version History.

Optional: You can drive this query from a parameter called BaseUrl, but hardcoding is fine for most users.

About GraphQL in Power BI:

This example uses GraphQL to retrieve basic metadata for a specific model, but GraphQL is a much more powerful and flexible query language. You can use it to extract any data available in Speckle’s API: element types, properties, commit authors, timestamps, version diffs, comments, and more. These queries can be used in any Power BI dashboard to build custom reporting pipelines.

We’ll be sharing more worked examples soon that demonstrate how to:

  • Pull structured properties from all objects in a stream
  • Join version metadata with other project information
  • Use GraphQL to optimise and reduce the size of Power BI imports, here we are just getting version id, date and message.

You can explore the API and experiment with live queries directly in the documented GraphQL sandbox at:
https://app.speckle.systems/graphql


Step 4: Connect the Data

In Power BI’s Model View:

  • Create a relationship from Federation[versionId] to Version History[Version ID]
  • Many-to-1
  • No need to perform any merges or joins in Power Query


Step 5: Enable Filtering in the 3D Viewer

Add a slicer visual:

  • Field: Version Date from Version History

  • Tooltip: Version Message

  • Enable:

    • Single select
    • Force selection

In the Speckle 3D visual:

  • Set Version Object ID to: Federation → Version Object ID
  • Set Object IDs to: Federation → Object IDs

Just as you would from one of the original queries.

Now, selecting a version date in the slicer will isolate only the objects from that version in the 3D viewer.


Optional: Display Selected Version

You can also add a DAX measure to display the selected commit message or date:

Selected Version = SELECTEDVALUE('Version History'[Version Message])

This is useful for dynamic page titles or annotations.


Summary

Step What it does
Load versions Brings in model snapshots with metadata
Federate Merges them into a unified table
Add metadata Enables context like commit messages
Connect tables Drives filtering via relationships
Add slicer Filters 3D view by version selected
2 Likes