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
- Your flow’s HTTP action POSTs
{"projectId", "modelId", "versionId"}to the function’s URL. - 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.
- Your flow gets one row per property of every element, as JSON it can parse and filter.
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:readscope, 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:@{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:
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 setSPECKLE_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 anx-api-key header.
- Power Automate
- Zapier
- n8n
- Add an HTTP action. Set Method to
POST, URI to the function URL, and a headerContent-Type: application/json. On AWS Lambda, add the headerx-api-keytoo. - Set Body to the IDs, as shown below.
- Add Parse JSON with Content set to the HTTP action’s Body. Generate the schema
from the example row above, wrapped in
[ ]. - Add Filter array on the parsed body. For example,
pathequalsifcTypeandvalue_textequalsIfcDoorgives one row per door. Use theirobject_idvalues in a second Filter array to pick out the rest of their properties.
Body
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:-
Download the DuckDB command-line tool for Windows from duckdb.org
and unzip
duckdb.exeto a folder such asC:\speckle. - Save Get-BundleProperties.ps1 and query.sql to the same folder.
-
Store the token for the Windows account that runs the flow, then restart Power Automate Desktop
so it sees the new variable:
- Add Run DOS command with the command below, using your IDs and folder.
- 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.
- Filter the rows with Filter data table. For example,
pathequalsifcTypeandvalue_textequalsIfcDoorgives one row per door.
Command
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.