Skip to content
Developers

Script it. Extend it. Make it yours.

Every Solid Vibes design is readable code. Drive it from your own scripts with the REST API and the typed SDK, write your own parametric features in TypeScript, and add panels and commands to the editor with sandboxed plugins.

REST API + SDK

Read and change Things with versioned ops, build on the server, read mass properties, export STL / 3MF / STEP / DXF, run the agent.

Read more

Custom features

FeatureScript-style macros in TypeScript. Typed parameters become a dialog; the code runs in a sandbox, in the browser and on the server.

Read more

Editor plugins

Panels, ⌘K commands and bundled features in a locked-down frame. Plugins propose changes; people accept them.

Read more
REST API

Quickstart

  1. Create a key in Workspace → Developer (Maker plan and up). Pick only the scopes it needs. You see the key once.
  2. Call the API with it as a bearer token, from a script or a server — never from a web page.
  3. Read a doc, send ops with the version you read, retry on 409. Open editors show your change live.
curl https://app.solidvibes.ai/api/v1/things \
  -H "Authorization: Bearer $SOLIDVIBES_API_KEY"
import { SolidVibes } from "@sv/sdk";

const sv = new SolidVibes({ apiKey: process.env.SOLIDVIBES_API_KEY! });

const [box] = await sv.things.all({ q: "router mount" });
await sv.things.setParameter(box.id, "width", 80);      // retries on version conflicts
const build = await sv.things.build(box.id);              // step errors + mass properties
const stl = await sv.exports.create(box.id, { format: "stl" });
console.log(build.total.massG, "g →", stl.url);

The full reference is the OpenAPI 3.1 document at /api/v1/openapi.json — import it into Postman, Insomnia or a code generator. The typed TypeScript client lives in packages/sdk.

EndpointScope
GET /api/v1/meThe key's workspace, scopes and rate limitany
GET /api/v1/thingsList Thingsthings:read
GET /api/v1/things/{thingId}Get a Thingthings:read
GET /api/v1/things/{thingId}/docGet the ThingDocthings:read
PATCH /api/v1/things/{thingId}/docChange the doc with opsthings:write
POST /api/v1/things/{thingId}/buildBuild the piecesthings:read
GET /api/v1/things/{thingId}/mass-propertiesMass propertiesthings:read
GET /api/v1/things/{thingId}/exportsList exportsexports
POST /api/v1/things/{thingId}/exportsExport a fileexports
POST /api/v1/things/{thingId}/agentRun the agent on a promptagent

Scopes

things:read
List Things, read their docs, build them and read mass properties.
things:write
Change a Thing's doc with ops (with version checks), like an edit in the editor.
exports
Export STL, 3MF, STEP or DXF files and list past exports.
agent
Send prompts to the agent. Uses your workspace's AI credits.
PATCH /api/v1/things/{thingId}/doc
{
  "expectedVersion": 12,
  "ops": [
    { "op": "piece_recipe", "pieceId": "p1",
      "ops": [{ "op": "set_parameter", "name": "width", "value": 80 }] }
  ],
  "message": "Wider for the new router"
}
→ 200 { "docVersion": 13, "describe": ["Box: Set width = 80 mm"] }
→ 409 { "error": { "code": "version_conflict", "details": { "expected": 12, "current": 13 } } }
Webhooks

Hear back when things change

Add an HTTPS endpoint in Workspace → Developer. Changes made through the API (doc updates, finished exports, agent proposals) are POSTed as JSON with an X-SolidVibes-Signature header. Verify it with the secret you saw once.

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(body: string, header: string, secret: string) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((kv) => kv.split("=")));
  const mac = createHmac("sha256", secret).update(`${t}.${body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  return fresh && timingSafeEqual(Buffer.from(mac), Buffer.from(v1));
}
Custom features

Your own smart features, in TypeScript

Declare typed parameters — number, length, angle, switch, choice, a picked face or edges — and a build() that adds recipe steps with the same calls as the script view. Insert it from ⌘K: the parameters are a dialog with a live preview, and the recipe shows one sentence.

  • • Runs in QuickJS (WebAssembly) with a 1.5 s, 32 MB budget, no network, no clock — the same code builds in your browser and on our servers.
  • • Versioned per workspace. Steps keep the version they were made with; the code travels with the recipe.
  • • Publish one to the Marketplace as a Feature listing; others add it to their workspace in one click.
Writing a custom feature →
export default feature({
  name: "Peg row",
  summary: "{count} pegs, {spacing} mm apart",
  params: {
    count: number({ label: "Pegs", default: 4, min: 1, max: 20, integer: true }),
    spacing: length({ label: "Spacing", default: 15 }),
    on: face({ label: "On face", default: "top" }),
  },
  build(p) {
    for (let i = 0; i < p.count; i++) {
      cylinder("peg_" + i, { radius: 2, height: 6, position: [i * p.spacing, 0, 0] });
    }
  },
});
Plugins

Extend the editor, safely

A plugin is a manifest plus one HTML page. Solid Vibes loads it in a sandboxed frame with no network and talks to it over postMessage: window.solidVibes.call(method, params).

Permissions (granted at install)

doc:read
Its pieces, parameters and recipe steps, and what you have selected. Nothing leaves your browser: plugins have no network access.
ops:propose
Suggest edits that appear as a ghost preview. Nothing changes until you press Accept.
commands
Add its own commands to the command palette.
panel
Show its own panel in the right column of the editor.
features
Install the custom features it comes with into this workspace (they run in the feature sandbox).

Methods: doc.get, selection.get, ops.propose, proposal.cancel, commands.register, features.list, features.open, ui.notify. Events: init, command, selection, doc, proposal.

Plugins and permissions →
{
  "manifestVersion": 1,
  "id": "my-plugin",
  "name": "My plugin",
  "version": "1.0.0",
  "description": "What it does, in one sentence.",
  "author": "You",
  "permissions": ["doc:read", "ops:propose", "panel"],
  "entry": "index.html",
  "panel": { "title": "My panel" }
}
Security

Built to be safe to open up

  • API keys are stored as SHA-256 fingerprints, scoped, expiring, revocable, rate limited per minute and every call is logged.
  • The API accepts bearer keys only — never cookies — so other sites can’t use your session (no CSRF).
  • Webhook URLs must be public HTTPS; every delivery re-checks the address, pins it and never follows redirects.
  • Custom features and plugins run in sandboxes with no network, no access to the page and hard resource limits.

API keys in the help center