Skip to content

Plugin API

The Snaptrude Plugin API (snaptrude) provides a structured way to interact with the Snaptrude model, create building elements, perform transforms, and convert units.

Quick Start

bash
npx @snaptrude/create-snaptrude-plugin@latest

You will be prompted for a plugin name (lowercase letters, numbers, and hyphens only). This creates a new directory with a fully configured plugin project ready to develop.

bash
cd my-plugin
npm install
npm run dev

You can also pass the name directly:

bash
npx @snaptrude/create-snaptrude-plugin@latest create -n my-plugin

For the full development guide, see Plugin Development.

Namespaces

The API is organized into six top-level namespaces:

  • Core (snaptrude.core): Infrastructure primitives — math (vec3, quat), the geometry kernel (geom), undo/redo history, units, camera zoom, project settings, comments, and project organization (buildings, groups, layers, tags).
  • Design (snaptrude.design): Author, query & edit BIM geometry — create (incl. copy), query, selection, doors, windows, furniture, materials, boolean, erase, delete, transform, edit, and lock state.
  • Entity (snaptrude.entity): CRUD operations on building elements — space, story, referenceLine, buildableEnvelope.
  • Program (snaptrude.program): Space programming — areas, departments, site, cores, classification, metrics, adjacency, and spreadsheet reports.
  • Presentation (snaptrude.presentation): Saved views, layout sheets, diagrams, reference imports, and Present-mode AI Inspiration — views, sheets, diagrams, import, aiInspiration.

Unit conversion lives under Core at snaptrude.core.units (it is no longer a top-level namespace).

Key Concepts

Handles, not values

Only JS primitives (number, string, boolean) and enum strings cross the plugin ↔ host boundary by value. Every structured type — a vector, a curve, a profile, a BREP face, a scene entity — is represented by an opaque, kind-tagged string handle (runtime form "<kind>_<token>"). Operations take handles in and return new handles out; value handles are immutable and never mutated. Reads return primitive records, never handles — e.g. vec3.components(v) returns { x, y, z }.

ts
const { vec3 } = snaptrude.core.math;
const a = await vec3.new(1, 0, 0); // Vec3Handle, e.g. "vec3_a1b2c3"
const b = await vec3.new(0, 1, 0);
const c = await vec3.add(a, b); // new handle — a and b are unchanged
const { x, y, z } = await vec3.components(c); // { x: 1, y: 1, z: 0 }

See Handles for the full model — value handles, session-ephemeral resource handles, BREP topology handles, and stable entity handles.

Typed errors

Every failed call rejects with a typed PluginError — branch on its stable string code ("VALIDATION", "HANDLE_INVALID", "RATE_LIMITED", …), read details for structured context (which argument, which handles, how long to back off), and follow hint for the fix. Check with PluginError.is(e), not instanceof. See Error Handling for the full model and code table; each namespace page lists its specific conditions in an Errors section.

Everything is an async host call

Every API method — including math like vec3.add — is an RPC to the Snaptrude host; there is no in-worker compute. Always await every call:

ts
const space = await snaptrude.design.create.space(contour, 3);

Calling convention

Every namespace takes positional parameters, options-last — required params first, then a single optional options object (e.g. vec3.lerp(a, b, 0.5), buildings.copy(buildingId, { name })). Each reference page shows the authoritative signature:

ts
await snaptrude.core.math.vec3.lerp(a, b, 0.5);
await snaptrude.program.departments.assign(departmentId, spaceIds);

Snaptrude units

Snaptrude stores all geometry in an internal coordinate system (Snaptrude units). Use snaptrude.core.units.convert(value, from, to, degree?) to convert real-world measurements into Snaptrude units before passing them to API methods, and back again for display — the optional degree selects length (1, default), area (2), or volume (3):

ts
const height = await snaptrude.core.units.convert(3, "meters", "babylon");
const sqm = await snaptrude.core.units.convert(144, "babylon", "meters", 2);

Undo/redo

Mutating operations (create, update, delete, transform) are recorded for undo/redo, unless a page explicitly notes a write is not undoable (settings writes, active-layer switches).