Skip to main content

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.csv with 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. The simplest path for most AEC automation scripts:
  1. Paste the one-time AddSpeckleSdk bootstrap (see Automate with scripts)
  2. Authenticate with a personal access token from SPECKLE_TOKEN
  3. Fetch the latest version with client.Version.GetVersions
  4. Load the object graph with Receive2
  5. Use Flatten() and read DataObject.properties for BIM fields
  6. Write results to CSV with StreamWriter
Avoid dependency injection beyond the bootstrap, repository patterns, and custom abstractions until you have a script that runs end to end.

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}
Create a console project and install packages:

Complete example

Complete example
Set environment variables before running:

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
Last modified on July 18, 2026