Skip to main content
A script that looks for the publish message on the root object, or for units on the version, finds nothing. The two live in different records. The Version is the record the server keeps: who published, when, from which application, and which object to fetch. The root object is the top of the data package itself: the file name, the units, the element tree, and the proxies. This page shows how the two connect and how to read each one.

Resolve a version to its root object

Every version carries a referencedObject field. Its value is the object id of the root of that version’s data package. Fetch the version, read the id, then receive that object.
  1. Get the version. List a model’s versions to take the latest, or fetch one by id.
  2. Read referencedObject. It is a plain object id, the same kind of id every object in the package has.
  3. Receive that id. The SDK downloads the root and every object it references, and returns the root as a Base.
The root object is a Root Collection whenever a connector published the version. Scripts that publish their own data can send any Base as the root. Check speckle_type before you assume a Collection.
referencedObject is null when the version is beyond your workspace’s version history limit. There is nothing to receive for such a version.

What lives on the Version

The server stores these fields when the version is created. Read them from the version record. They are not present on the root object. The .NET and Python SDK Version types expose every row except totalChildrenCount and parents. Query those two fields with the GraphQL API when you need them.

What lives on the root object

The root object is a Base. Connectors publish it as a Collection and set the fields below on it before sending. Only name and elements are declared on the Collection class. The rest are dynamic properties, so read them by key.
A dynamic property that a connector did not set is absent. Read every root field with a fallback instead of assuming it exists.
The stored JSON of the root also carries a __closure table that lists every descendant object. The SDK deserializers consume it while receiving, so it is not present on the Base you get back.

The units convention

Connectors write the source document’s unit to units on the root object. The value is one of the SDK unit strings: mm, cm, m, km, in, ft, yd, mi, or none. Treat it as the default unit for the whole package. Geometry objects also carry their own units field. A connector normally writes the same value to both. When you convert coordinates, read the unit from the geometry object you are converting, and use the root value as the fallback when a geometry object has none.
Scripts that publish a bare Base often omit units on the root. Do not assume metres when it is missing.

Read each in a script

Both snippets assume client, project_id / projectId, and model_id / modelId are already in scope, and that you have authenticated with a personal access token. The Python snippet also assumes a ServerTransport named transport. The .NET snippet assumes account and an IOperations named operations.
Example
You should see one line with the publish message and author, and one line with the document name, element count, and unit.

Set each field in the right place when you publish

The same split applies when you publish from a script.
  • Set name, units, and elements on the root Base before you send it. Set them as dynamic properties on a Collection to match what connectors publish.
  • Pass message, sourceApplication, and totalChildrenCount in the create-version input after the send returns the root object id.
See Version (.NET) and VersionResource (Python) for the create call.

FAQ

No. A version’s referencedObject is fixed at creation. Updating a version changes only its message. Send the new root and create a new version for it.
The root object and its children stay in the project’s object store, but nothing references them. They are orphaned and reachable only by object id.

Next steps

Core Concepts

Root Collection, Proxies, and Info in detail

Traversal Recipes

Walk elements once you hold the root

Object Schema

Fields on every object below the root
Last modified on September 16, 2026