Skip to main content
Use this guide if you build automations in Power Automate, Zapier, or n8n and want the properties of a Speckle model in your flow: every element’s type, name, dimensions, and parameters, as rows you can filter, count, and send on. Models uploaded to Speckle since the 2026.9 release are stored as bundles: Parquet files that low-code tools cannot read. The properties export your flow may already call (eav/query) serves only versions in the earlier format. This guide adds one small function between your flow and Speckle. Your flow sends it a project, model, and version id; it returns the version’s properties as JSON, in the same columns as the properties export.
Someone has to set the function up once: a developer, or anyone comfortable deploying a small piece of code. Where it runs depends on the tools you already use; see Choose where it runs. After that, building and changing the flow is all low-code.

How it works

  1. Your flow’s HTTP action POSTs {"projectId", "modelId", "versionId"} to the function’s URL.
  2. The function asks Speckle for the version’s files and reads the property files directly. Your Speckle token stays in the function’s settings, never in the flow.
  3. Your flow gets one row per property of every element, as JSON it can parse and filter.
Each row looks like this:
Type properties (Revit type parameters, IFC type properties) are included, so each element carries its type’s properties too.

Prerequisites

  • A Speckle personal access token with the streams:read scope, from a user who can read the project (Building with PATs)
  • Somewhere to run the function; see Choose where it runs
  • Power Automate with the premium HTTP action, Zapier with Webhooks by Zapier, or n8n
This works on Speckle Cloud and Speckle Enterprise Server 2026.9 and later. The open-source Speckle Server has no bundles: there, keep using the properties export.

Find your IDs

Open the model version in Speckle and read the IDs from the address bar:
If the address has no @{versionId}, the viewer is showing the latest version. Open the specific version you want so its id appears.

Choose where it runs

The function only has to be reachable over HTTPS and able to run Python, Node.js, or .NET. Pick the host your organisation already uses: If your flow feeds a Power BI or Excel report rather than an automation, you may not need a function at all: Power Query can load the bundle’s Parquet files directly.

As the person who deploys the function

You do this once. The function is a ready-made sample in Python, TypeScript, and C#: examples/bundle-properties-function. Pick the language your team maintains; they behave the same.

On Azure Functions

Get just the sample folder, then publish one language folder to a Function App, for example with the Azure Functions Core Tools:
For Python, create the Function App on Python 3.12. The sample’s README covers running it locally first, and the TypeScript and C# folders. Then add the token. In the Azure portal, open the Function App, go to Settings → Environment variables, and add: Then open the properties function, copy its function URL, and give it to the flow builder. The URL ends in ?code=..., the key that lets a flow call it, so share it as a secret.

On AWS Lambda

The Python and TypeScript folders include a Lambda handler for a function URL. Package the folder for Linux, create the function on Python 3.12 or Node.js 22, and set SPECKLE_TOKEN and a FUNCTION_KEY of your choosing as environment variables. The sample’s README has the exact package commands, handler names, and memory settings. Create a function URL with auth type NONE: the handler only answers requests that carry the FUNCTION_KEY in an x-api-key header. Give the flow builder the URL and the key, and share both as secrets.

On another host

Each sample keeps the query apart from the Azure wrapper: python/properties.py, typescript/src/properties.ts, and csharp/BundleProperties.cs run anywhere. On another host, copy that file and write the host’s own HTTP handler around it: read the three IDs from the request body, fetch the version’s file list from Speckle with the token, pass the files to the query, and return the rows as JSON. The Azure and Lambda handlers in the same folder are 30-line models to follow. Keep the token in the host’s secret settings as SPECKLE_TOKEN, and protect the URL with the host’s own key or authentication, since anyone with it can read the model’s properties.

As the flow builder

You need the function URL from whoever deployed it, and the three IDs. On AWS Lambda you also need the key, which every request sends as an x-api-key header.
  1. Add an HTTP action. Set Method to POST, URI to the function URL, and a header Content-Type: application/json. On AWS Lambda, add the header x-api-key too.
  2. Set Body to the IDs, as shown below.
  3. Add Parse JSON with Content set to the HTTP action’s Body. Generate the schema from the example row above, wrapped in [ ].
  4. Add Filter array on the parsed body. For example, path equals ifcType and value_text equals IfcDoor gives one row per door. Use their object_id values in a second Filter array to pick out the rest of their properties.
Body
You should see one row per property of every element in the version, as in the example above.

On Power Automate Desktop

A desktop flow runs on a Windows machine, so it needs no function: a PowerShell script on that machine fetches the version’s files, runs the query, and writes the properties to a CSV file the flow reads. Set up the machine once:
  1. Download the DuckDB command-line tool for Windows from duckdb.org and unzip duckdb.exe to a folder such as C:\speckle.
  2. Save Get-BundleProperties.ps1 and query.sql to the same folder.
  3. Store the token for the Windows account that runs the flow, then restart Power Automate Desktop so it sees the new variable:
Then build the flow:
  1. Add Run DOS command with the command below, using your IDs and folder.
  2. Add Read from CSV file on the output file, with First line contains column names turned on. Each property becomes a row of a data table.
  3. Filter the rows with Filter data table. For example, path equals ifcType and value_text equals IfcDoor gives one row per door.
Command
If the script fails, Run DOS command puts the reason in CommandErrorOutput and a non-zero CommandExitCode; check them before reading the file. End -OutFile in .json instead to get the same JSON rows as the function returns.

Troubleshooting

Last modified on November 14, 2026