API quickstart
This guide takes you from an API key to a thread you created and read back, entirely over HTTPS. Every request below runs against the DUST API at https://apid.dustid.io; see Environments for all service URLs.
You will need a Service Account API key (created by an organization admin). If you don’t have one yet, start with Authentication and API keys.
-
Exchange your API key for a bearer token
Section titled “Exchange your API key for a bearer token”API keys are never sent to core endpoints directly. Exchange the key for a short-lived bearer token at
GET /api/auth/token, passing the key in thex-api-keyheader:Terminal window export APID_URL="https://apid.dustid.io"export DUST_API_KEY="your-service-account-key"export DUST_TOKEN="$(curl -fsS "$APID_URL/api/auth/token" \-H "x-api-key: $DUST_API_KEY" | jq -r '.token')"const apidUrl = "https://apid.dustid.io";const tokenResponse = await fetch(`${apidUrl}/api/auth/token`, {headers: { "x-api-key": process.env.DUST_API_KEY! },});const { token } = await tokenResponse.json();The response is a JSON object with a single
tokenfield — a JWT you send asAuthorization: Bearer <token>on every/api/v1/*call. Tokens expire; re-run the exchange when they do. Details in Authentication. -
Find your organization and team context
Section titled “Find your organization and team context”Most endpoints run inside an organization and team, named by two request headers.
GET /api/v1/mereturns the organizations your credentials can act in:Terminal window curl -fsS "$APID_URL/api/v1/me" \-H "Authorization: Bearer $DUST_TOKEN"The response includes an
organizationsarray (each withid,name,slug,roles) and anactiveOrganizationId. Pick the organization you want to work in:Terminal window export DUST_ORG_ID="<organization id from /api/v1/me>"# Optional: export DUST_TEAM_ID="<team id from /api/v1/me>" if you want a non-root team.Header Required Purpose Dust-Ctx-Org-IdYes, for org-scoped endpoints Organization UUID. Dust-Ctx-Team-IdNo Team UUID. Defaults to the organization root team. -
Create a thread
Section titled “Create a thread”A thread is the record for one asset or item; its
dataarray holds typed fields.POST /api/v1/threadswithtype: "single"creates one:Terminal window 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","description": "Production asset"},"data": [{ "name": "Serial Number", "type": "text", "value": { "text": "SZ3J-11-ZJ17" } },{ "name": "Max PSI", "type": "number", "value": { "number": 51 } }]}'import { ApidClient } from "@dustid/apid-client";const client = new ApidClient({baseUrl: apidUrl,bearerToken: token,organizationId, // sent as Dust-Ctx-Org-IdteamId, // optional; sent as Dust-Ctx-Team-Id when set});// createOne unwraps the batch response to the single created threadconst created = await client.threads.createOne({type: "single",thread: {name: "Tire SZ3J-11-ZJ17",description: "Production asset",},data: [{ name: "Serial Number", type: "text", value: { text: "SZ3J-11-ZJ17" } },{ name: "Max PSI", type: "number", value: { number: 51 } },],});console.log(created.threadId);The raw response is
201 Createdwith{ "created": [ ... ], "uploadResponses": [ ... ] }; each entry increatedis the full thread record, including its generatedthreadId(a UUID). Fielddataentries requiretypeandvalue;namelabels the field. -
Read it back
Section titled “Read it back”GET /api/v1/threads/{thread_id}returns the thread plus its event history:Terminal window export THREAD_ID="<created[0].threadId from the previous step>"curl -fsS "$APID_URL/api/v1/threads/$THREAD_ID" \-H "Authorization: Bearer $DUST_TOKEN" \-H "Dust-Ctx-Org-Id: $DUST_ORG_ID"const record = await client.threads.get(created.threadId);console.log(record.thread.name); // "Tire SZ3J-11-ZJ17"console.log(record.events.length); // creation events already recordedThe response shape is
{ "thread": { ... }, "events": [ ... ] }— every write to a thread is recorded as an event, so the audit trail starts at creation. -
Where to go next
Section titled “Where to go next”- Request conventions — context headers, error shape, pagination, localization.
- Threads — field types, updates, archiving, listing and search.
- Identifiers — bind and verify physical identifiers against threads (the
/api/v1/tags/*endpoints). - Files — attach evidence files to threads.
- Teams and sharing — cross-team access.
- TypeScript client — the typed client used above.
- Full API reference — every endpoint, generated from the live OpenAPI spec. The server also self-hosts an interactive reference at
https://apid.dustid.io/api/docsand the raw spec at/api/openapi.json.
