Skip to content

Core model

The DUST platform API models physical-object workflows as a small set of composable resources. A Thread is the digital record for a physical item; everything else — identifiers, files, folders, assemblies, sharing, shipments — attaches to, organizes, or moves Threads. This page is the map: one short section per concept, with the key endpoints and a link to the deeper guide.

Some API namespaces predate the current product vocabulary. The DICE web app and these docs use the left-hand names; the API paths keep the names on the right.

DICE / docs nameAPI namespaceNotes
Threads/api/v1/threads—
Identifiers/api/v1/tagsLegacy tags naming in paths
Files/api/v1/filesCalled resources in some schemas
Folders & Categories/api/v1/bundlesBundle is the implementation name
Assemblies/api/v1/assembliesAssemblies are Threads of kind assembly
Teams/api/v1/teamsSelected per-request via the Dust-Ctx-Team-Id header (legacy Dust-Ctx-Grp-Id still accepted)
Connections/api/v1/connectionsWire schemas keep the legacy team link naming
Sharing/api/v1/sharing—
Shipments/api/v1/transfersLegacy transfers naming in paths
Slices/api/v1/slices—
Fabric/api/v1/fabricCross-organization provenance graph
Certificates/api/v1/certificates, /api/v1/certificate-forms—
Public Pages/api/v1/public-pages, /api/v1/public-page-designsPublishing requires the Team publisher grant
Events/api/v1/events—

Every request carries an AuthD bearer token; org-scoped endpoints — nearly all of them — add the Dust-Ctx-Org-Id header (and optionally Dust-Ctx-Team-Id to select a Team). See Authentication and Conventions. The complete parameter-level reference is the API reference.

A Thread is the record for one physical asset, part, document, or workflow item: a name and description, typed field data, attached files, bound identifiers, and an event history. Threads have a kind — ordinary units or assembly (see below).

  • POST /api/v1/threads — create one or many
  • GET /api/v1/threads — search and list (cursor pagination)
  • GET /api/v1/threads/{thread_id} — get one, with field data
  • POST /api/v1/threads/{thread_id}/data — upsert or remove field values
  • PATCH /api/v1/threads/archive / PATCH /api/v1/threads/restore — archive lifecycle

Deep dive: Threads API guide.

Field values are typed (text, number, date, select, resource references, even thread-valued fields) and nested by type. Templates define the expected fields for a repeatable kind of Thread.

  • POST /api/v1/templates / GET /api/v1/templates — create and list templates
  • GET /api/v1/templates/{templateId} / PATCH /api/v1/templates/{templateId} — read and update

An identifier binds a physical marking — a DUST tag, QR code, barcode, Data Matrix symbol, or NFC chip — to a Thread, so a scan in the field resolves to the digital record. The API namespace is /api/v1/tags (legacy naming).

  • POST /api/v1/tags/extract — parse a DUST capture into a canonical fingerprint without binding
  • POST /api/v1/tags/bind — attach an identifier to a Thread
  • POST /api/v1/tags/identify — find the Thread matching a scan
  • POST /api/v1/tags/verify — confirm a scan matches a specific Thread’s identifiers
  • POST /api/v1/tags/unbind — detach an identifier

Deep dive: Identifiers API guide.

Files (called resources in some schemas) are stored in object storage and attached to Threads directly or through resource-typed fields. Large uploads use the resumable tus protocol; small ones use a single multipart POST.

  • POST /api/v1/files — simple multipart upload
  • POST /api/v1/files/finalize — turn completed tus uploads into resource records
  • GET /api/v1/files/{resource_id}/download — download
  • POST /api/v1/files/urls — short-lived signed URLs
  • GET /api/v1/files/search — search across files

Deep dive: Files API guide.

Identity lives in AuthD; the platform API scopes each org-scoped request to an Organization and a Team via context headers. Teams own Threads, and sharing, connections, and shipments all operate between Teams.

  • GET /api/v1/me — current user and available organizations
  • GET /api/v1/teams — Teams visible to the caller
  • POST /api/v1/org/teams / PATCH /api/v1/org/teams/{team_id} — Team management (org admins)
  • POST /api/v1/org/teams/members — manage memberships (org admins)

Deep dive: Teams, sharing, and connections.

Folders and Categories organize Threads. Both are bundles in the API — kind: "folder" for exclusive containment, kind: "category" for non-exclusive labeling — and bundles nest to form trees.

  • POST /api/v1/bundles — create (with kind and optional childOfId parent)
  • GET /api/v1/bundles / GET /api/v1/bundles/children — list, or walk the tree lazily
  • POST /api/v1/bundles/{bundle_id}/add / PATCH /api/v1/bundles/{bundle_id}/move — place Threads
  • PATCH /api/v1/bundles/parent — re-parent a bundle

An assembly is a Thread of kind assembly whose Parts are other Threads — a bill-of-materials structure. Parts can be protected against detachment, and part lists roll up transitively.

  • GET /api/v1/assemblies — list assembly Threads
  • POST /api/v1/assemblies/{assembly_id}/parts / DELETE /api/v1/assemblies/{assembly_id}/parts — attach and detach Parts
  • GET /api/v1/assemblies/{assembly_id}/rolled-up-parts — transitive part list
  • PATCH /api/v1/assemblies/{assembly_id}/kind — convert a Thread between unit and assembly
  • POST /api/v1/imports/plan / POST /api/v1/imports/commit — dry-run and commit a whole assembly import package

Threads can reference each other with typed links. Relation definitions name the relationship kinds; thread links are the instances.

  • POST /api/v1/relations / GET /api/v1/relations — define and list relation kinds
  • POST /api/v1/links / GET /api/v1/links — create and list links between Threads
  • GET /api/v1/threads/{thread_id}/links — links from one Thread’s perspective
  • DELETE /api/v1/links/{link_id} — unlink

Sharing grants another Team viewer or editor access to a Thread or bundle. Grants are stored as relationship tuples; the access summary shows the effective result, including inherited access.

  • POST /api/v1/sharing — share Threads or bundles with Teams
  • GET /api/v1/sharing — list grants (direction=in|out)
  • GET /api/v1/sharing/access-summary — effective access for one object
  • GET /api/v1/sharing/partner-inventory — everything shared with one partner Team

Deep dive: Teams, sharing, and connections.

A Connection (API: team link) is the standing agreement between two Teams — often in different Organizations — that permits sharing and shipments, with an allowed data-flow direction. It has an invite/accept/confirm handshake and a pause/resume lifecycle.

  • POST /api/v1/connections — create (invite)
  • PATCH /api/v1/connections/accept / confirm / reject / cancel — handshake
  • PATCH /api/v1/connections/pause / resume — suspend and restore
  • POST /api/v1/connections/amend/propose — propose a direction change

A Shipment (API: transfer) moves ownership of Threads from one Team to another: build a draft manifest, send it, and the receiver accepts, rejects, or requests changes.

  • POST /api/v1/transfers — create a draft
  • POST /api/v1/transfers/{transfer_id}/items — add manifest items
  • POST /api/v1/transfers/{transfer_id}/send — send to the receiving Team
  • POST /api/v1/transfers/{transfer_id}/respond — accept / reject / request changes
  • GET /api/v1/transfers — inbox, outbox, and sent views

Semantics and lifecycle: Shipments; endpoint summary in Teams, sharing, and connections.

A Slice derives a new Thread from an existing one within the same Team — selected fields, files, and identifiers copied or linked — typically to prepare a shareable subset.

  • POST /api/v1/slices — slice one Thread
  • POST /api/v1/slices/batch — derive many Threads at once
  • GET /api/v1/slices/{slice_id} — a Slice with its Fabric links

Fabric is the cross-organization provenance layer: when Threads move or are disclosed across Team boundaries, Fabric records the graph of linked Threads and controls exactly which data each downstream party can see (disclosure), revision by revision.

  • GET /api/v1/fabric/threads/{thread_id}/graph — the provenance graph visible from a Thread
  • GET /api/v1/fabric/links/{link_id}/context — currently disclosed data on a link
  • POST /api/v1/fabric/threads/{thread_id}/disclosure/revise / redact — change what is disclosed
  • POST /api/v1/fabric/threads/{thread_id}/disclosure/push — push a disclosure downstream
  • GET /api/v1/fabric/notifications — disclosure notifications for downstream owners

Concepts: Fabric.

Certificates render Thread data into issued, verifiable documents. Certificate Forms are the layouts; generation binds a form to a Thread by field name.

A form may contain multiple Vlink QR zones. Certificate generation accepts one Vlink configuration per zone Identifier and returns every issued zone-to-Vlink association.

  • POST /api/v1/certificate-forms / GET /api/v1/certificate-forms — manage forms
  • POST /api/v1/certificates/preflight — check a form resolves against a Thread
  • POST /api/v1/certificates/generate — issue a Certificate
  • GET /api/v1/certificates — list a Thread’s Certificates
  • POST /api/v1/certificates/void — void one

Concepts: Certificates.

A Public Page is the unauthenticated web view of a Thread — the digital product passport a consumer reaches by scanning an Identifier. What it shows is decided entirely by a reusable, Team-owned Public Page Design, so publishing takes no per-Thread content input: publish resolves the design against the Thread. A page’s URL is reserved and bound before anything is published, so labels can be printed first.

Publishing a design freezes an immutable Design Version; each page pins one Design Version plus one Data Snapshot (the values resolved for that Thread). A Publish Wave republishes every page in a scope — Folder, Category, Template, or an explicit selection — through one Design Version, as a background run with its own progress and failure accounting.

Reserving a page URL and binding it to a Thread are member-tier — reserving an address publishes nothing, so labels can be printed before anyone decides to publish. Everything that makes data public — publishing a page, activating or archiving it, authoring a design, publishing a Design Version, rolling out, and Publish Waves — requires the Team publisher grant (Team admin implies it), as do the preflight and preview checks. Each operation’s x-required-role in the API reference is authoritative.

  • POST /api/v1/public-pages / POST /api/v1/public-pages/{publicPageId}/bind — reserve a permanent page URL, then bind it to a Thread
  • GET / PUT /api/v1/public-pages/thread/{threadId} — read, or get-or-create, a Thread’s page
  • GET /api/v1/public-pages/thread/{threadId}/activity — anonymous views and verification scans on the published page
  • POST /api/v1/public-pages/{publicPageId}/publish — publish a snapshot through the design’s latest version
  • PATCH /api/v1/public-pages/{publicPageId} — activate or archive a page without changing its URL
  • GET /api/v1/public-pages/{publicPageId}/publications — publication history
  • POST /api/v1/public-pages/preflight / preflight/batch — check a design resolves against one or many Threads
  • POST /api/v1/public-page-designs / GET / PATCH /api/v1/public-page-designs/{designId} — author a design draft
  • POST /api/v1/public-page-designs/{designId}/versions — publish a Design Version (GET lists them)
  • POST /api/v1/public-pages/designs/{designId}/roll-out — make a design’s latest version live across its pages
  • POST /api/v1/public-pages/waves — start a Publish Wave (GET its run record, items, and list)
  • POST /api/v1/public-pages/waves/{waveId}/retry-failed / cancel — retry the failures, or stop the remaining work

Rollout is forward-only: a Design Version is never restored, and cancelling a wave leaves already-published pages on the version they received.

Concepts: Public Pages.

Every meaningful change — field edits, binds, shares, shipments — is recorded as an event, forming the audit trail shown as Transaction Log in DICE.

  • GET /api/v1/events — list events, filterable by Thread, Team, action, and time, with optional activity grouping (groupBy)
    • lineage=upstream (with threadId) also returns the events of every earlier Thread on the Thread’s Fabric lineage — a received Thread’s full story — bounded by what each source disclosed. Upstream rows carry a lineage object (source Thread, source Team, link, hop) and may be redacted; a source’s later disclosure change appears as a read-only fabric.disclosure.revised row. Omitted, the response holds the Thread’s own events only.
    • resourceId, tagId, or fieldId (one at a time, with threadId) scope the history to one file, identifier, or field; a certificate is addressed by its file. With lineage=upstream the asset’s own lineage is followed.
    • A Thread received in a shipment or created by a slice opens its history with transfer.received / slice.derived, attributed to the person who accepted or sliced; it carries no created.thread or bind of its own.
  • GET /api/v1/summary — headline count metrics
  • GET /api/v1/notifications — the caller’s notifications

Full reference

Every path, parameter, and schema in the API reference.

Download an on-demand PDF with GET /api/v1/receipts/{kind}/{id}, where kind is file, thread, or shipment, and id is the corresponding UUID. Use your usual authentication and active organization and Team context headers. The response is application/pdf with an attachment filename and private, no-store caching. Accept-Language selects the receipt language.

File receipts include metadata, the saved SHA-256 checksum when available, associated thread information, and permitted transaction log entries. Thread receipts include fields, Identifiers, files and checksums, relationships, assembly and lineage information, and permitted logs. Shipment receipts start with shipment information, its current status and manifest, then include visible thread details and logs. Pending shipments use offered snapshots; other states use records the caller can currently access.

For a file visible through a disclosure, supply linkId; for a file offered in a pending shipment, supply transferId. These optional UUID query parameters cannot be combined and apply only to file receipts. They retain the same access and disclosure restrictions as the corresponding preview.

Receipts include a generation timestamp and a QR link back to DICE. They are unsigned snapshots of caller-visible records, not digital signatures. Generation is read-only: no receipt attachment or transaction log event is saved. Exports exceeding 10,000 visible events in a log fail rather than silently truncating. Links in a receipt still require DICE access.