Goal
Build a working C# console app that loads a published Speckle model, counts elements by category, and writes a CSV report you can open in Excel.What you will build
A console application that:- Reads credentials and target IDs from environment variables
- Loads the latest version of a model from Speckle Server
- Traverses the object graph and groups elements by category
- Writes
model-health-report.csvwith category names and counts
When to use this
Use this pattern when you need a first real automation — BIM QA summaries, quantity checks, or a starting point for door schedules and property audits. This is the recommended onboarding path before connector development or advanced architecture.Recommended approach
The simplest path for most AEC automation scripts:- Paste the one-time
AddSpeckleSdkbootstrap (see Automate with scripts) - Authenticate with a personal access token from
SPECKLE_TOKEN - Fetch the latest version with
client.Version.GetVersions - Load the object graph with
Receive2 - Use
Flatten()and readDataObject.propertiesfor BIM fields - Write results to CSV with
StreamWriter
Prerequisites
- .NET SDK installed
- A personal access token from Speckle
- A published model on Speckle Server (from a connector or prior send)
- Project ID and model ID from the Speckle web app URL:
https://app.speckle.systems/projects/{projectId}/models/{modelId}
Complete example
Complete example
How it works
Bootstrap.AddSpeckleSdk registers IOperations, IClientFactory, and IAccountFactory. You paste this once per app — see Automate with scripts.
Authentication. IAccountFactory.CreateAccount builds an in-memory Account from your PAT. No local account database is required for scripts.
Latest version. client.Version.GetVersions returns versions for a model; the API returns the newest first when limit is 1. The version’s referencedObject id points at the root of the object graph.
Receive. Receive2 downloads and deserializes the full graph. This is the recommended server-facing receive path for scripts — no transport factory required.
Traverse. Flatten() walks every Base in the graph. Connector-published BIM data is usually DataObject with semantic fields in properties — for example category, level, or fireRating.
Report. Grouping by category produces a simple model health summary. Extend the same pattern for door schedules or property audits — see Export model data to CSV.
Common mistakes
Next steps
Export model data to CSV
Door schedules and room lists with specific columns
Find objects by property
Filter walls, check required properties, find duplicate IDs
BIM data patterns
How connector data is structured in v3