Skip to content

SDK reference

Everything the thingport object has: what a widget’s or a tool’s default export is called with. Most of it is the same for both; the At a glance table says which has what, and a member that differs shows each form. How a script runs, and what it may reach, is in the overview.

Signatures are written in TypeScript; scripts are plain JavaScript. For an editor that completes thingport. and checks your calls, put thingport.d.ts beside the script and start it with:

// @ts-check
/** @param {import("./thingport").WidgetSdk} thingport */
export default function mount(thingport) {}

For a tool, the type is ToolSdk.

Member Widget Tool What it is
root✓✓The element to draw into: the panel or the window, with the HTML already in it.
selector✓✓A CSS selector for root, unique on the page, to scope styles to it.
size✓✓The size of root in pixels, kept current as it’s resized.
onResize✓✓Hears when root is resized.
theme✓✓Thingport’s colours and font, light or dark.
settings✓The panel’s settings, as the metadata’s settings declares them, with their defaults filled in.
widget✓The widget itself.
widgetId✓The widget’s id, as widget.id.
instanceId✓This panel’s id, for a widget that’s on the dashboard more than once and keeps something per panel.
language✓✓The language Thingport is in, as a code like "en" or "lt", already matched to one it has ("pt-BR" gets "pt" where that exists, else "en").
languages✓✓Every language Thingport has, English first.
t✓✓The script’s own words, from its locales/<code>.json labels, in the user’s language.
labels✓✓Fills in the script’s words in its markup: data-t sets an element’s text, and data-t-title, data-t-aria and data-t-placeholder fill those attributes.
models✓✓The user’s models, as the user.
collections✓✓The user’s collections.
fetch✓✓A request to one of the hosts the metadata’s hosts lists, made by the Thingport server, so CORS and the local network aren’t in the way.
api✓✓Thingport’s own REST API, as the user, signed in as the page is.
download✓✓Hands the user a file to keep, as a browser download.
ui✓✓Thingport’s own toast and confirmation.
achievements✓✓The user’s achievements: badges for what they do in Thingport, while an admin has them on.
close✓Closes the tool’s window.
library✓✓A library Thingport carries, for a job a script can’t fit inside itself.
libraries✓✓The names library() takes.
tool✓The tool itself.
context✓What the tool was opened on: { modelId } when it’s opened on a model, and empty when it’s opened from the Tools page.
storage✓JSON kept for this user and this tool, so the window opens where they left it.
toolModels✓The models a tool from the repository brings, by the keys its metadata gives them.
fetchToolModels✓Fetches the tool’s models that aren’t here yet and gives the user their copies.

Widgets and tools

thingport.root: HTMLElement

The element to draw into: the panel or the window, with the HTML already in it. The theme is on it as CSS variables (see theme). Draw only inside it; it’s emptied when the script stops.

thingport.root.querySelector("h2").textContent = "Hello";

Widgets and tools

thingport.selector: string

A CSS selector for root, unique on the page, to scope styles to it.

style.textContent = `${thingport.selector} .row { display: flex; }`;

In a widget:

thingport.size: WidgetSize

The size of the panel in pixels and in grid cells, kept current as the user resizes it.

See WidgetSize.

In a tool:

thingport.size: SdkSize

The size of root in pixels, kept current as it’s resized.

See SdkSize.

In a widget:

thingport.onResize(listener: (size: WidgetSize) => void): () => void

Hears when the panel is resized.

Parameter What it is
listenerCalled with the new size.

Returns: A function that stops it, for the cleanup.

See WidgetSize.

const stop = thingport.onResize(({ cols }) => list.classList.toggle("wide", cols >= 6));

In a tool:

thingport.onResize(listener: (size: SdkSize) => void): () => void

Hears when root is resized.

Parameter What it is
listenerCalled with the new size.

Returns: A function that stops it, for the cleanup.

See SdkSize.

const stop = thingport.onResize(({ width }) => root.classList.toggle("narrow", width < 400));

Widgets and tools

thingport.theme: SdkTheme

Thingport’s colours and font, light or dark. The same values are on root as CSS variables, so a stylesheet can use them without the script copying anything across. The script runs again when the user changes theme.

See SdkTheme.

canvas.style.background = thingport.theme.paper;

Widgets only

thingport.settings: Record<string, any>

The panel’s settings, as the metadata’s settings declares them, with their defaults filled in. A toggle is a boolean; text, number and choice settings are strings, numbers included. The widget runs again when they change.

const every = Number(thingport.settings.refresh) * 1000;

Widgets only

thingport.widget: { id: string; slug: string; name: string; version: string; source: "own" | "community" }

The widget itself. source is "own" for one the user made, "community" for one installed from the repository.

Widgets only

thingport.widgetId: string

The widget’s id, as widget.id.

Widgets only

thingport.instanceId: string

This panel’s id, for a widget that’s on the dashboard more than once and keeps something per panel.

Widgets and tools

thingport.language: string

The language Thingport is in, as a code like "en" or "lt", already matched to one it has ("pt-BR" gets "pt" where that exists, else "en"). The script runs again when the user changes language, so this is read once rather than watched.

Widgets and tools

thingport.languages: SdkLanguage[]

Every language Thingport has, English first.

See SdkLanguage.

Widgets and tools

thingport.t(key: string, vars?: Record<string, unknown>): string

The script’s own words, from its locales/<code>.json labels, in the user’s language. A missing word falls back to English key by key, and a key with no words anywhere comes back as itself, so the gap shows.

A number as count picks the plural form: the label has a key per form, <key>.one, .two, .few, .many and .other, and each language gives the ones its own rules use (English one and other, Russian one, few, many and other, the last for fractions such as 1.5), with .other standing in for a form it hasn’t. Thingport before this returns the key itself: a script that must run on one picks the form there, as Intl.PluralRules names it, and asks for <key>.<form>, then <key>.other.

Parameter What it is
keyThe label’s key.
varsValues for the {name} placeholders in it, and count to pick a plural form.

Returns: The sentence.

t("rings.ring", { n: 2 }); // "Ring 2", or "Žiedas 2" in Lithuanian
t("bar.pieces", { count: 21 }); // "pieces", or "деталь" in Russian, where 21 takes the one form

Widgets and tools

thingport.labels(where?: ParentNode): void

Fills in the script’s words in its markup: data-t sets an element’s text, and data-t-title, data-t-aria and data-t-placeholder fill those attributes. Running it again after adding markup is harmless.

Parameter What it is
whereThe element to fill in under: root when left out.
// <h2 data-t="wall.title">Wall size</h2>
thingport.labels();

Widgets and tools

thingport.models: SdkModels

The user’s models, as the user. A widget usually only reads.

thingport.models.list(options?: SdkModelQuery): Promise<SdkModelPage>

A page of the library’s models, newest first.

Parameter What it is
optionsWhat to narrow it to, and which page.

See SdkModelQuery, SdkModelPage.

const { models, hasMore } = await thingport.models.list({ tags: ["gridfinity"], limit: 20 });
thingport.models.search(q: string): Promise<SdkSearchResult>

The best matches for a search, as the search box finds them: models, collections and tags.

Parameter What it is
qThe words to look for.

See SdkSearchResult.

const { models, tags } = await thingport.models.search("benchy");
thingport.models.get(id: string): Promise<SdkModel>

One model.

Parameter What it is
idThe model’s id.

See SdkModel.

const model = await thingport.models.get(id);
thingport.models.file(id: string, fileId?: string): Promise<ArrayBuffer>

One of a model’s 3D files.

Parameter What it is
idThe model’s id.
fileIdOne of its files; the first when left out.

Returns: The file’s bytes. Throws when the model has no such file, or when the file is missing from storage.

const stl = await thingport.models.file(model.id);
thingport.models.relatedFiles(id: string): Promise<SdkRelatedFile[]>

The files kept beside a model that aren’t plates: the script it was generated from, a readme, a diagram.

Parameter What it is
idThe model’s id.

See SdkRelatedFile.

const scad = (await thingport.models.relatedFiles(id)).find((file) => file.name.endsWith(".scad"));
thingport.models.relatedText(id: string, fileId: string): Promise<string>

One of those files, as text.

Parameter What it is
idThe model’s id.
fileIdOne of its relatedFiles.
const source = await thingport.models.relatedText(id, scad.id);
thingport.models.create(input: SdkNewModel): Promise<SdkModel>

Makes a model of the files given, each one a plate, in a collection when one is given.

Parameter What it is
inputIts name, description, tags, collection and files.

Returns: The new model.

See SdkNewModel, SdkModel.

const model = await thingport.models.create({
name: "Cube 20 mm",
tags: ["generated"],
files: [{ name: "cube-20.stl", data: stl }],
});
thingport.models.addFiles(id: string, files: SdkFileInput[]): Promise<SdkModel>

Adds files to a model, each a plate.

Parameter What it is
idThe model’s id.
filesThe files to add.

Returns: The model as it is now.

See SdkFileInput, SdkModel.

thingport.models.addImages(id: string, images: SdkFileInput[]): Promise<SdkModel>

Adds pictures (PNG, JPEG, WebP) to a model’s gallery. The first becomes its cover in place of the render.

Parameter What it is
idThe model’s id.
imagesThe pictures.

Returns: The model as it is now.

See SdkFileInput, SdkModel.

const png = await new Promise((done) => canvas.toBlob(done));
await thingport.models.addImages(model.id, [{ name: "cover.png", data: png }]);
thingport.models.replaceFile(id: string, fileId: string, file: SdkFileInput): Promise<SdkModel>

Replaces one of a model’s files with a new one, in the same place in its order.

Parameter What it is
idThe model’s id.
fileIdThe file to replace, one of its files.
fileThe new file.

Returns: The model as it is now.

See SdkFileInput, SdkModel.

thingport.models.update(id: string, patch: { name?: string; description?: string; tags?: string[] }): Promise<SdkModel>

Changes a model’s name, description or tags. Only what’s given changes; tags replaces the list.

Parameter What it is
idThe model’s id.
patchWhat to change.

Returns: The model as it is now.

See SdkModel.

await thingport.models.update(model.id, { tags: [...model.tags, "printed"] });
thingport.models.open(id: string): void

Leaves for the model’s page. A tool’s window closes first.

Parameter What it is
idThe model’s id.

In a widget:

thingport.collections: SdkCollections

The user’s collections.

In a tool:

thingport.collections: ToolCollections

The user’s collections, and a dialog asking them for one.

thingport.collections.list(): Promise<SdkCollection[]>

The user’s collections, without the built-in Favourites and Browsing History.

See SdkCollection.

const collections = await thingport.collections.list();
thingport.collections.get(id: string): Promise<SdkCollection>

One collection.

Parameter What it is
idThe collection’s id.

See SdkCollection.

thingport.collections.create(input: SdkNewCollection): Promise<SdkCollection>

Makes a collection.

Parameter What it is
inputIts name, description and tags.

Returns: The new collection.

See SdkNewCollection, SdkCollection.

const shelf = await thingport.collections.create({ name: "Labels" });
thingport.collections.models(id: string, options?: SdkPage): Promise<SdkModelPage>

A page of the models in a collection, newest first.

Parameter What it is
idThe collection’s id.
optionsWhich page.

See SdkPage, SdkModelPage.

const { models } = await thingport.collections.models(id, { limit: 10 });
thingport.collections.add(id: string, modelIds: string[]): Promise<void>

Puts models from the library into a collection.

Parameter What it is
idThe collection’s id.
modelIdsThe models to put in.
thingport.collections.remove(id: string, modelIds: string[]): Promise<void>

Takes models out of a collection. They stay in the library.

Parameter What it is
idThe collection’s id.
modelIdsThe models to take out.

Tools only

thingport.collections.pick(options?: { title?: string }): Promise<SdkCollection | null>

Asks the user which collection, or for a new one, as a Save dialog would. A dashboard has no such dialog, so a widget saves into a collection its settings name instead.

Parameter What it is
optionstitle: what the dialog asks.

Returns: The collection, or null when the user cancels.

See SdkCollection.

const collection = await thingport.collections.pick({ title: t("save.where") });
if (!collection) return;

Widgets and tools

thingport.fetch(url: string, init?: RequestInit): Promise<Response>

A request to one of the hosts the metadata’s hosts lists, made by the Thingport server, so CORS and the local network aren’t in the way. Answers as fetch does, with the body as text (a binary answer doesn’t survive) and Content-Type its only header. Any other host throws, as does a cloud metadata address. Redirects aren’t followed, the Cookie header isn’t sent, a string is the only body it carries, and it gives up after 15 seconds and cuts an answer off at 5 MB. The editor’s preview of a widget or a tool that hasn’t been saved yet can’t reach any host.

Parameter What it is
urlAn http or https address on a declared host.
initThe method (GET, POST, PUT, PATCH or DELETE), headers and a string body.
const res = await thingport.fetch("http://octopi.local/api/job", { headers: { "X-Api-Key": key } });
const job = await res.json();

Widgets and tools

thingport.api(path: string, init?: RequestInit): Promise<Response>

Thingport’s own REST API, as the user, signed in as the page is.

Parameter What it is
pathA path under /api, such as /dashboard/summary.
initAs fetch takes it.
const summary = await (await thingport.api("/dashboard/summary")).json();

Widgets and tools

thingport.download(file: SdkFileInput): void

Hands the user a file to keep, as a browser download.

Parameter What it is
fileIts name and content.

See SdkFileInput.

thingport.download({ name: "label.stl", data: stl });

In a widget:

thingport.ui: SdkUi

Thingport’s own toast and confirmation.

In a tool:

thingport.ui: ToolUi

Thingport’s own toast and confirmation, the collection picker, and closing the window.

thingport.ui.toast(message: string, severity?: SdkSeverity, options?: SdkToastOptions): void

Shows a short message in Thingport’s own toast.

Parameter What it is
messageWhat to say.
severityHow it looks: "info" when left out.
optionsopenModel: a model’s id, for an Open button on the toast that leaves for its page.

See SdkSeverity, SdkToastOptions.

const model = await thingport.models.create({ name, files });
thingport.ui.toast(t("save.done", { name: model.name }), "success", { openModel: model.id });
thingport.ui.confirm(options: SdkConfirmOptions): Promise<boolean>

Asks the user to confirm, in Thingport’s own dialog.

Parameter What it is
optionsWhat to ask, and how.

Returns: Whether they confirmed.

See SdkConfirmOptions.

if (!(await thingport.ui.confirm({ message: t("clear.ask"), destructive: true }))) return;
thingport.ui.openModel(id: string): void

Leaves for a model’s page, as models.open does. A tool’s window closes first.

Parameter What it is
idThe model’s id.

Tools only

thingport.ui.pickCollection(options?: { title?: string }): Promise<SdkCollection | null>

The same dialog as collections.pick.

Parameter What it is
optionstitle: what the dialog asks.

Returns: The collection, or null when the user cancels.

See SdkCollection.

Tools only

thingport.ui.close(): void

Closes the tool’s window, as close() does.

Widgets and tools

thingport.achievements: SdkAchievements

The user’s achievements: badges for what they do in Thingport, while an admin has them on.

thingport.achievements.unlock(key: string): Promise<boolean>

Gives the user a secret badge this widget or tool hides: an easter egg Thingport knows by the script’s slug and key. Thingport shows them the badge the first time; asked again, nothing happens. Resolves false when there’s no such secret for this script, when an admin has achievements off, and in an unsaved draft. Never throws, so an easter egg can’t break the script around it; and as Thingport versions before achievements have no thingport.achievements, call it as thingport.achievements?.unlock(key).

Parameter What it is
keyThe secret’s name, as Thingport’s catalogue has it for this script.

Returns: Whether the user has it now.

root.addEventListener("dblclick", () => thingport.achievements?.unlock("guest"));

Tools only

thingport.close(): void

Closes the tool’s window.

Widgets and tools

thingport.library<K extends SdkLibraryName>(name: K): Promise<SdkLibraries[K]>

A library Thingport carries, for a job a script can’t fit inside itself. Fetched the first time anything asks and shared with every widget and tool after that, so ask only when the script needs it: a panel drawn in HTML shouldn’t wait on a WebAssembly download.

Parameter What it is
nameWhich library.

See SdkLibraryName.

const [{ Manifold }, fonts] = await Promise.all([thingport.library("manifold"), thingport.library("fonts")]);

Three.js, the copy Thingport draws models with, plus mergeGeometries and mergeVertices from its BufferGeometryUtils.

const THREE = await thingport.library("three");
const box = new THREE.BoxGeometry(20, 20, 20);

opentype.js: reads a TTF or OTF and gives a glyph’s real outline, counters and all.

const opentype = await thingport.library("opentype");
const font = opentype.parse(await file.arrayBuffer());

Manifold, started and ready: solid modelling whose results stay watertight, with the 2D cross-sections and offsetting that go with it.

const { Manifold } = await thingport.library("manifold");
const ring = Manifold.cylinder(4, 20, 20, 64).subtract(Manifold.cylinder(4, 16, 16, 64));
const mesh = ring.getMesh();

The typefaces Thingport carries, under the Open Font License. They are all static faces: a variable font’s outlines are only right once its deltas are applied, which opentype.js doesn’t do.

fonts.list: readonly SdkFont[]

Every typeface, in the order a picker should show them.

See SdkFont.

const fonts = await thingport.library("fonts");
select.append(...fonts.list.map((font) => new Option(font.name, font.id)));
fonts.bytes(id: string): Promise<ArrayBuffer>

The font file itself.

Parameter What it is
idOne of list’s ids.

Returns: The TTF’s bytes.

const ttf = await fonts.bytes("pt-sans");
fonts.load(id: string): Promise<ExternalLibrary>

The font parsed by opentype.js, the same Font every widget and tool asking for it gets.

Parameter What it is
idOne of list’s ids.

Returns: An opentype.js Font.

See ExternalLibrary.

const font = await fonts.load("bebas-neue");
const path = font.getPath("HELLO", 0, 0, 72);

OpenSCAD itself, built for the browser, for the models that came with the script they were generated from. A render runs in a worker, so the page keeps drawing, and nothing leaves the browser: the script, the parameters and the result stay in the tab until something saves them. A script may include the libraries in libraries.

openscad.parameters(source: string): Promise<ScadParameters>

What parameters a script offers, read by OpenSCAD itself, so it’s the list the script’s author saw. That includes the ones a script declares below its first {, which OpenSCAD alone wouldn’t read but a site’s customizer may.

Parameter What it is
sourceThe script’s text.

See ScadParameters.

const openscad = await thingport.library("openscad");
const { parameters } = await openscad.parameters(source);
openscad.render(source: string, options?: ScadRenderOptions): Promise<ScadRender>

The model a script makes of a given set of parameters.

Parameter What it is
sourceThe script’s text.
optionsThe parameters, the format and a signal to cancel it.

Returns: The file, the engine’s log and the time it took. A 3MF unless format says otherwise.

See ScadRenderOptions, ScadRender.

const { bytes, log } = await openscad.render(source, { parameters: { width: 60 }, name: "Box" });
thingport.download({ name: "box.3mf", data: bytes });
openscad.includedFiles(source: string, read: (fileName: string) => Promise<string | null>): Promise<Record<string, string>>

The .scad files a script includes or uses, and what those include in turn, ready for render()’s files. A script that came with a model often needs the others kept beside it.

Parameter What it is
sourceThe script’s text.
readReads a file by its name, without any folder; resolves to null when there’s no such file.

Returns: Each file’s text, by the path the script asks for it by. What read couldn’t find is left out, and the render’s log says so.

const files = await openscad.includedFiles(source, async (name) => {
const file = related.find((candidate) => candidate.name === name);
return file ? thingport.models.relatedText(id, file.id) : null;
});
const { bytes } = await openscad.render(source, { files });
openscad.libraries: string[]

The OpenSCAD libraries a script may include, by folder name.

openscad.concurrency: number

How many renders to have in flight at once: one fewer than the machine has cores, from one to four.

openscad.writeThreeMf(input: SdkMesh | ThreeMfPart[], options?: { name?: string }): Uint8Array

One mesh, or several named parts, as the bytes of one 3MF file.

Parameter What it is
inputA mesh, or a list of parts to place side by side (see layoutRow).
optionsThe model’s name, which slicers show.

See SdkMesh, ThreeMfPart.

const file = openscad.writeThreeMf(
openscad.layoutRow([
{ mesh: a, name: "Lid" },
{ mesh: b, name: "Box" },
]),
);
openscad.layoutRow(parts: ThreeMfPart[], options?: { gap?: number }): ThreeMfPart[]

Lays parts out in a row, in the order given, each standing on z = 0, so a 3MF of them doesn’t have them inside one another.

Parameter What it is
partsThe parts to place.
optionsgap: millimetres between them, 5 when left out.

Returns: The same parts, each with an at.

See ThreeMfPart.

openscad.meshBounds(mesh: SdkMesh): { min: [number, number, number]; max: [number, number, number] }

A mesh’s bounding box, in millimetres.

See SdkMesh.

const { min, max } = openscad.meshBounds(mesh);
const width = max[0] - min[0];

Widgets and tools

thingport.libraries: SdkLibraryName[]

The names library() takes.

See SdkLibraryName.

Tools only

thingport.tool: { id: string | null; slug: string; name: string; version: string; source: "repo" | "own" }

The tool itself. id is null in the editor’s preview of a tool not saved yet; source is "repo" for one installed from the repository and "own" for the user’s own.

Tools only

thingport.context: { modelId?: string }

What the tool was opened on: { modelId } when it’s opened on a model, and empty when it’s opened from the Tools page.

Tools only

thingport.storage: SdkStorage

JSON kept for this user and this tool, so the window opens where they left it. In the editor’s preview of a tool not saved yet, it lasts only as long as the preview.

thingport.storage.get(key: string): Promise<any>

What’s kept under a key.

Parameter What it is
key1 to 200 letters, digits, ., -, : and _.

Returns: The value as it was kept, or undefined when nothing is.

const last = (await thingport.storage.get("last")) ?? { width: 40 };
thingport.storage.set(key: string, value: unknown): Promise<void>

Keeps a value under a key, replacing what was there. At most 1 MB a value as JSON, 20 MB and 2,000 keys a tool.

Parameter What it is
key1 to 200 letters, digits, ., -, : and _.
valueAnything JSON can hold.
await thingport.storage.set("last", { width: 60 });
thingport.storage.remove(key: string): Promise<void>

Forgets a key.

Parameter What it is
keyThe key.
thingport.storage.keys(): Promise<string[]>

Every key kept.

const drafts = (await thingport.storage.keys()).filter((key) => key.startsWith("draft:"));

Tools only

thingport.toolModels(): Promise<SdkToolModel[]>

The models a tool from the repository brings, by the keys its metadata gives them. An admin may install a tool without them, which is usual where they’re large, so printId is null for one that isn’t here yet. A user’s own tool brings none.

See SdkToolModel.

const joint = (await thingport.toolModels()).find((model) => model.key === "joint");

Tools only

thingport.fetchToolModels(keys: string[]): Promise<SdkToolModelsFetched>

Fetches the tool’s models that aren’t here yet and gives the user their copies. Ask for the few a piece of work needs, and only once the user has agreed to wait for them.

Parameter What it is
keysThe models’ keys.

Returns: What came, and why the rest didn’t, in the provider’s own words.

See SdkToolModelsFetched.

const { failed } = await thingport.fetchToolModels(["tile-8x8"]);
if (failed.length) thingport.ui.toast(failed[0].reason, "warning");

Thingport’s colours and font, as the theme the user has on shows them.

Field Type CSS variable What it is
mode"light" | "dark"Which theme is on.
primarystring--tp-accentThe accent colour the user picked.
primaryContraststring--tp-accent-inkWhat reads on primary: white for most accents, dark for light ones such as amber. Text and icons on an accent-filled button take this, never paper, which is dark in the dark theme.
backgroundstring--tp-backgroundThe page behind the panels and windows.
paperstring--tp-paperThe surface of a panel, a window or a card.
textstring--tp-textBody text.
textSecondarystring--tp-text-mutedQuieter text: hints, captions, counts.
dividerstring--tp-dividerLines and borders.
errorstring--tp-errorSomething failed.
warningstring--tp-warningSomething needs a look.
successstring--tp-successSomething worked.
fontFamilystring--tp-fontThe font stack Thingport’s own text is set in.

A size in pixels.

Field Type What it is
widthnumber
heightnumber

A dashboard panel’s size: pixels, and the grid cells it covers.

Field Type What it is
widthnumber
heightnumber
colsnumberColumns of the dashboard’s grid, which is 12 wide on a wide screen.
rowsnumberRows of the grid, each 64 px tall with 16 px between them.

A language Thingport has.

Field Type What it is
codestringIts code, as language gives it: "en", "lt".
labelstringNamed in itself (“Lietuvių”), so it reads from any language.
englishNamestringNamed in English.

A model in the user’s library.

Field Type What it is
idstring
namestring
descriptionstring | null
tagsstring[]
thumbnailstring | nullA picture of it, an address an <img> can show.
filesSdkModelFile[]Its 3D files (plates), in order.
relatedCountnumberHow many files are kept beside it that aren’t plates, so a list can be narrowed without asking for each.
toolOwnedbooleanBrought by a tool from the repository: it can be read, not changed.
createdAtstring | nullWhen it was added, as an ISO 8601 date.

One of a model’s 3D files.

Field Type What it is
idstring
namestringIts file name, with the extension.
sizenumberIn bytes.
urlstringAn address it can be read from as the user, e.g. by fetch.

A file kept beside a model rather than being one of its plates: a generator script, a readme, a diagram.

Field Type What it is
idstring
namestring
typestringIts MIME type.
sizenumberIn bytes.
urlstring

A page of models.

Field Type What it is
modelsSdkModel[]
hasMorebooleanMore models match than this page holds: ask again with a larger offset.
totalnumber | nullHow many match in all, where the server counted them.

What models.search finds, as the search box shows it.

Field Type What it is
modelsSdkModel[]
collections{ id: string; name: string; modelCount: number }[]
tags{ tag: string; count: number }[]

One of the user’s collections.

Field Type What it is
idstring
namestring
descriptionstring | null
tagsstring[]
modelCountnumber
toolOwnedbooleanA tool’s own collection, which can’t be saved into.

A file to save or hand over: its name, with the extension, and its content.

Field Type What it is
namestringE.g. "bin-2x3.stl".
dataBlob | ArrayBuffer | ArrayBufferView | stringThe content. A string is saved as UTF-8 text.
type?stringIts MIME type. Left out, a Blob’s own type is used, else application/octet-stream.

Which models a list holds, and which page of them.

Field Type What it is
q?stringWords to search for, as the models page searches.
tags?string[]Only models with every one of these tags.
collectionId?stringOnly the models in this collection.
limit?numberHow many to return: 1 to 200, 50 when left out.
offset?numberHow many to skip, for the next page.

A page of a collection’s models.

Field Type What it is
limit?numberHow many to return: 1 to 200, 50 when left out.
offset?numberHow many to skip, for the next page.

A model to make.

Field Type What it is
namestring
description?string
tags?string[]
collectionId?stringA collection to save it into.
filesSdkFileInput[]Its files, each a plate. At least one.

A collection to make.

Field Type What it is
namestring
description?string
tags?string[]

What a confirmation asks.

Field Type What it is
title?string
messagestring
confirmLabel?stringThe confirming button’s label: “Confirm” when left out, or “Delete” for a destructive one.
destructive?booleanShows the confirming button in the error colour, for something that can’t be undone.

How a toast looks.

type SdkSeverity = "success" | "info" | "warning" | "error";

What a toast can carry besides its message.

Field Type What it is
openModel?stringA model’s id: the toast gets an Open button that leaves for the model’s page, as ui.openModel does, and stays up longer so it can be reached. Pass it whenever the toast says a model was saved or changed. An older Thingport instance shows the message without the button.

A model a tool from the repository brings, as toolModels() lists it.

Field Type What it is
keystringWhat the tool’s metadata calls it.
namestring
sourcestring | nullThe page it’s imported from, for one that isn’t a file in the tool’s folder.
printIdstring | nullThe user’s copy, to read with models; null while it isn’t here.

What fetchToolModels brought, and what it couldn’t.

Field Type What it is
readystring[]The keys that are here now.
failed{ key: string; reason: string }[]The rest, each with the provider’s own reason, a daily download limit included.

A library with types of its own, which this file doesn’t repeat: see its own documentation.

type ExternalLibrary = any;

A library’s name, as library() takes it.

type SdkLibraryName = keyof SdkLibraries;

A typeface library("fonts") offers.

Field Type What it is
idstringWhat bytes and load take.
namestringIts name, to show.
groupstringThe kind of face it is, for a picker to group by: “Sans”, “Serif”, “Script”…

A parameter an OpenSCAD script offers, as OpenSCAD’s own customizer describes it.

Field Type What it is
namestring
groupstringThe /* [Group] */ heading it was declared under; “Parameters” for the ones before any heading.
type"number" | "string" | "boolean" | "vector" | string
initialunknownThe value the script gives it.
caption?stringThe comment above the declaration, which explains it.
min?number
max?number
step?number
options?{ name: string; value: unknown }[]Where the declaration ends in // [a, b, c]: a choice rather than free entry.
widget?"color" | "font" | "file"A control OpenSCAD has no word for, in the spelling of MakerWorld, whose scripts use them. "color" holds a "#rrggbb" (declared with // color). "font" holds a typeface’s name (// font), of which only the ones in library("fonts") are there to draw with; any other comes out in the plainest. "file" holds the name of a file the script reads (declared with a default called default.png, .svg or .stl), passed to render() in files; until there is one the script gets a plain stand-in.
accept?stringFor a "file" widget, the file’s extension: ".png", ".svg" or ".stl".

What an OpenSCAD script offers.

Field Type What it is
titlestring
parametersScadParameter[]

The formats a render can come back as. "mesh" is the geometry alone, with no file built from it.

type ScadFormat = "3mf" | "mesh" | "stl" | "obj" | "off" | "amf";

How to render a script.

Field Type What it is
parameters?Record<string, unknown>By parameter name, as parameters() gives them. Anything left out keeps the script’s own value.
files?Record<string, Uint8Array | string>The files the script reads, by the name a "file" parameter was set to, or as includedFiles() gives them.
format?ScadFormat"3mf" when left out.
name?stringThe title written into a 3MF, which slicers show. Ignored by the other formats.
signal?AbortSignalCancels the render: the worker running it is let go there and then.

What a render produced: the file, and everything the engine said while making it.

Field Type What it is
bytesUint8Array
logstring[]Warnings and errors, in the order they were printed. A typeface Thingport doesn’t carry isn’t among them: it comes out in the plainest without a word.
secondsnumberSeconds the engine spent.
mesh?SdkMeshThe geometry behind the bytes, for the formats Thingport builds itself (3MF and mesh).

A triangle mesh, in millimetres.

Field Type What it is
verticesFloat64ArrayFlat x, y, z triples.
trianglesUint32ArrayFlat vertex-index triples.
palette?string[]The distinct colours the script gave the model, as "#rrggbb"; absent where it never coloured it.
colors?Uint16ArrayOne entry per triangle, indexing palette. Present whenever palette is.
uncolored?numberThe palette entry standing in for the faces the script never coloured, where it coloured some.

One of the things a 3MF holds.

Field Type What it is
meshSdkMesh
name?stringWhat a slicer’s object list calls it. A count belongs here, “8x8 Core Tile x4”, since a 3MF holds one copy of a shape however many are wanted.
at?{ x: number; y: number; z?: number }Millimetres from the origin. Left out, the part stays where its mesh is, so several land on top of each other: see layoutRow.

Something unclear, wrong or missing on this page? Say so here, or react. It’s kept in GitHub Discussions. Something broken? Report it as a bug.