Skip to main content
This is 2026.9 documentation. Coverage here is incremental: a page exists only where 2026.9 differs or is newly documented. For any other topic, switch to Current (2026.8 and earlier) in the version selector.
If your script starts from version.referencedObject, reads units off the root object, or walks down from it, that script breaks on a 2026.9 version. Bundle data has no root object. The jobs the root object used to do are split across four places: the version record on the server, the model ingestion that publishes it, a one-row provenance stamp inside the bundle, and model-scoped properties. This page says where each piece went and what a script reads instead. Before 2026.9, as the Data Schema describes, a version points at one object: version.referencedObject is the id of the Root Collection, historically called the commit object. That object is the entry point for every traversal, and it carries the model-wide facts a script reads first: units, a name, the nested elements tree, Proxies, and Info such as views and the reference point transform. The version record beside it carries the message, source application, author, and creation date. Versions and the root object covers that split for 2026.8 and earlier in full. For how objects relate to each other in 2026.9, see Relations in 2026.9. For the two-store picture, see Object model in 2026.9.

What the root object carried, and where it lives now

Two rows need more detail because scripts depend on them today. The bundle reference is a pointer, not a hash. On a bundle-only version, referencedObject names the version, not its content. Resolve the version through the project and version id you already hold, then read its data with receive3 / Receive3. The embedded model id is the model at creation time and goes stale if the version is later moved. Units are per object, not per version. A bundle can carry more than one unit. The SDK’s Model.units is the first non-empty unit it finds, which is the builder’s default on data you published yourself. When precision matters, read the object’s own units property.

How a publish creates a version

send3 / Send3 runs all of this for you. Knowing the sequence explains why the version is not queryable the moment the call returns, and where each piece of metadata is set.
1

Open a model ingestion

The SDK creates an ingestion on the model, carrying the producer slug and version from your bundle builder and the message from your send options. The outcome is an ingestion with a reserved version id.
2

Build the bundle

The builder writes its parquet files, named by the reserved version id, and stamps the meta row with the spec version and producer. The outcome is a complete bundle on local disk.
3

Upload the files

Each file goes to storage through a presigned upload. The outcome is every file stored under the version id.
4

Complete the upload

The SDK completes the ingestion with the bundle reference and the object count. The outcome is the server creating the version in one step, with referencedObject set to the bundle reference and schemaVersion set to 3.
5

Wait for the version

send3 returns the reserved id immediately. Poll the ingestion, or call WaitForVersion in .NET, before you query, link, or receive it. The outcome is a version that answers queries and fires version_created.
account, project_id / projectId, and model_id / modelId are already in scope.
version.create / Version.Create still exist for object graphs from 2026.8 and earlier, and they too return a reserved id now. See Publish through model ingestions for that path.
Automate functions publish the same way. CreateNewVersionInProject accepts a bundle builder and returns the reserved version id.

Read version metadata from a script

Read the version record for identity and provenance: message, sourceApplication, authorUser, createdAt, schemaVersion, and referencedObject. This is the same query you run today. Read model-wide facts from the received Model, not from a root object. units gives the default unit. properties holds the model-scoped rows: the reference point (referencePoint.kind, referencePoint.transform, referencePoint.units) and any document settings or project information the connector published. camera_views holds saved cameras.
Legacy receive / Receive2 on a bundle-only version returns a compatibility projection. Its root is a Collection named Received model with the constant id artifact-root, carrying units, version = 4, and rebuilt proxy lists. That root is built when you receive, not stored in the bundle. Do not key on its id, and do not read a message or source application from it.

FAQ

No. Start from the version and receive it as a Model, then key objects by applicationId and follow relations. A container with subtype Model exists as the IN_MODEL target, but it is a grouping tier for federated source files, not a root, and it carries only a name.
They are different numbers. Version.schemaVersion is the server’s storage-shape flag: 3 means the version is served as a bundle, null means an object graph from 2026.8 or earlier. meta.schema_version inside the bundle is the semver of the bundle format the producer wrote against. Neither moves when the other does.
It gets a 404 with a BUNDLE_REFERENCE_NOT_FOUND body. That is the contract, not empty data. Dispatch on the bundle. prefix and receive the version through the SDK instead.
Add them as model-scoped properties on the bundle builder, not on an object. That is the home for document settings, project information, and a reference point. Units go on the builder, or on an individual object when it differs from the default.
Last modified on September 16, 2026