Threads API guide
A Thread is the digital record for one physical item — an asset, part, document, or workflow item. It carries a name and description, typed field data, attached files, bound identifiers, and an event history. Threads are owned by a Team, so every request needs a bearer token plus the Dust-Ctx-Org-Id header (and Dust-Ctx-Team-Id to act as a specific Team) — see Authentication and Conventions.
This guide covers the main flows. For every parameter and response schema, see the API reference.
Endpoints at a glance
Section titled “Endpoints at a glance”| Operation | Method & path |
|---|---|
| Create one or many Threads | POST /api/v1/threads |
| List / search Threads | GET /api/v1/threads |
| Count Threads | GET /api/v1/threads/count |
| Get one Thread | GET /api/v1/threads/{thread_id} |
| Update metadata and fields | POST /api/v1/threads/{thread_id} |
| Update fields only | POST /api/v1/threads/{thread_id}/data |
| List archived field data | GET /api/v1/threads/{thread_id}/data/archived |
| Restore archived field data | POST /api/v1/threads/{thread_id}/data/restore |
| Archive Threads | PATCH /api/v1/threads/archive |
| Restore Threads | PATCH /api/v1/threads/restore |
| Check caller permissions | POST /api/v1/threads/permissions |
| Presence heartbeat | POST /api/v1/threads/{thread_id}/presence |
| List a Thread’s files | GET /api/v1/threads/{thread_id}/files |
| Set / upload thumbnail | PATCH / POST /api/v1/threads/{thread_id}/thumbnail |
Create a Thread
Section titled “Create a Thread”POST /api/v1/threads accepts three body shapes, selected by type: single (one Thread), list (many normalized Threads), and raw (flat key-value records). All three accept an optional bundleId to create the Threads inside a Folder.
curl -fsS "$APID_URL/api/v1/threads" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "type": "single", "thread": { "name": "Tire SZ3J-11-ZJ17" }, "data": [ { "name": "Serial Number", "type": "text", "value": { "text": "SZ3J-11-ZJ17" } }, { "name": "Max PSI", "type": "number", "value": { "number": 51 } } ] }'const created = await client.threads.create({ type: "single", thread: { name: "Tire SZ3J-11-ZJ17" }, data: [ { name: "Serial Number", type: "text", value: { text: "SZ3J-11-ZJ17" } }, { name: "Max PSI", type: "number", value: { number: 51 } }, ],});Field values are nested under value by type — { "text": … }, { "number": … }, and so on. The spec defines inputs for text, long text, number, boolean, date, date range, date-time, time, duration, email, phone, URL, JSON, select, select-many, tags, resource (file) references, and thread references.
Bulk import
Section titled “Bulk import”Use type: "list" when you already have normalized { thread, data } objects, or type: "raw" to hand the API flat records — it derives fields from each object’s key-value pairs, using nameKey and descriptionKey (default name / description) for the Thread’s own metadata:
{ "type": "raw", "nameKey": "serial", "raw": [ { "serial": "SZ3J-11-ZJ17", "part": "P355/30R19", "maxPsi": 51 } ]}For importing whole assembly structures atomically, see POST /api/v1/imports/plan and POST /api/v1/imports/commit in the reference.
Read Threads
Section titled “Read Threads”GET /api/v1/threads/{thread_id} returns the Thread with its field data (an optional maxEvents query includes recent events). GET /api/v1/threads lists with cursor pagination (cursor, pageSize, order, orderCol) and supports filters including:
| Filter | Meaning |
|---|---|
q, queryCol |
Text search, optionally restricted to one column |
bundleId |
Threads in a Folder or Category |
templateId |
Threads created from a Template |
tagType |
Threads with an identifier of this type bound |
hasResources |
Threads with attached files |
includeArchived, archivedOnly |
Archive visibility |
createdBy, ownedByTeam |
Provenance filters |
excludeTransferred, transferredOnly |
Shipped-away Threads |
withActiveShipment |
Annotate each item with its active Shipment, if any |
GET /api/v1/threads/count takes the same filters and returns only the count — useful for dashboards and pagination summaries.
Update a Thread
Section titled “Update a Thread”Two endpoints, one intent split:
POST /api/v1/threads/{thread_id}— takes{ thread, update?, remove? }: Thread metadata (name, description, template, …) plus optional field changes in one call.POST /api/v1/threads/{thread_id}/data— fields only:{ threadId, update, remove?, expectedUpdatedAt? }. Fields inupdateare upserted (matched by name/ID);removetakes field IDs.
{ "threadId": "9f6a…", "update": [ { "name": "VIN", "type": "text", "value": { "text": "1HGCM82633A004352" } } ], "remove": []}Archived field data
Section titled “Archived field data”Removing a field archives it rather than destroying it. GET /api/v1/threads/{thread_id}/data/archived lists archived fields, and POST /api/v1/threads/{thread_id}/data/restore brings them back by ID ({ threadId, restore: ["field-id", …] }).
Archive and restore Threads
Section titled “Archive and restore Threads”Archiving is bulk and reversible:
PATCH /api/v1/threads/archive—{ threadIds: […], toggle? }. Withtoggle: true, archived Threads in the list are unarchived and active ones archived in a single call.PATCH /api/v1/threads/restore— restore archived Threads.
Archived Threads disappear from default listings; use includeArchived or archivedOnly to see them.
Permissions
Section titled “Permissions”Before rendering edit controls or attempting writes across many Threads, ask what the caller can actually do:
curl -fsS "$APID_URL/api/v1/threads/permissions" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "threadIds": ["9f6a…", "c2d1…"] }'POST /api/v1/threads/permissions returns the caller’s effective permissions per Thread in the current Team context. Related reads: GET /api/v1/threads/{thread_id}/access (which Teams provide access) and GET /api/v1/threads/{thread_id}/shared (who the Thread is shared with) — both covered in Teams, sharing, and connections.
Presence
Section titled “Presence”POST /api/v1/threads/{thread_id}/presence is a heartbeat: send it periodically while a user views a Thread (optionally with display name / image, and leaving: true on exit) and the response lists the Thread’s current viewers. DICE uses this for the “who else is here” indicator.
Files and thumbnails
Section titled “Files and thumbnails”Files attach to Threads through the Files API; the Thread-side reads live here:
GET /api/v1/threads/{thread_id}/files— the Thread’s files, cursor-paginated (includeArchivedis required).GET /api/v1/threads/{thread_id}/files/{res_id}/POST …/files/{res_id}— read and update a single attached file.POST /api/v1/threads/{thread_id}/thumbnail— upload an image (multipart,thumbnailfield) and set it as the Thread’s thumbnail in one step.PATCH /api/v1/threads/{thread_id}/thumbnail— set the thumbnail from an existing resource ID or an image URI.
Related pages
Section titled “Related pages”- Core model — how Threads relate to everything else
- Identifiers API guide — binding physical identifiers to Threads
- Files API guide — uploads and downloads
- API reference — full schemas for every endpoint above
