Building with AI agents
If you use an AI coding agent (Claude Code, Cursor, Copilot, or similar) to build against the DUST platform, this page is its entry point. Everything here is a stable public URL you can hand to an agent.
Start here
Section titled “Start here”| Give your agent | For |
|---|---|
/skills/dice-api-integration/SKILL.md | Calling the DUST API: auth, context headers, Threads, Identifiers, files, sharing, Shipments |
/skills/dust-go-connect-integration/SKILL.md | Adding DUST scanning to a web app running inside the DUST Go mobile app |
/llms.txt | A map of every page, so the agent can pick what it needs |
/llms-full.txt | The whole documentation as one plaintext document |
/openapi.json | The exact request and response contract |
The four facts agents get wrong
Section titled “The four facts agents get wrong”If you read nothing else into your agent’s context, read these. Each one is a request the API rejects rather than silently tolerating, so getting it wrong fails the integration outright.
- The identify search scope field is
searchTeamIds, a JSON array of Team UUIDs. There is nosearchGroupIdsrequest field. Identify payloads reject undeclared properties, so the wrong spelling fails the whole request with400 INVALID_REQUEST. The only surviving legacygroupname is theDust-Ctx-Grp-Idheader, an accepted alias forDust-Ctx-Team-Id. tagson verify is required, and it is an array of objects:[{"tagId": "…", "tagType": "DUST"}], not an array of id strings. In multipart bodies it is JSON-encoded.- A failed identify is an answer with an error status.
404 IDENTIFIER_NOT_FOUNDmeans nothing matched;503 SCAN_SEARCH_INCOMPLETEmeans the search could not be completed and should be retried;400 SCAN_LOW_KEYPOINTSmeans rescan. Generated code that treats every non-2xx as an exception reports outages that never happened. The canonical table is Errors and scan outcomes. - Credentials stay on the server. A DUST bearer token carries the Service Account’s full access and nothing narrows it for a browser session. The supported shape is browser → customer backend → DUST API. Never generate a component that takes a DUST token as a prop.
Canonical examples
Section titled “Canonical examples”These are the shapes to copy. Both blocks run on a server.
// Identify: which Thread does this capture belong to?const form = new FormData();form.set("tagType", "DUST");form.set("data", captureBlob); // binary, not base64form.set("searchTeamIds", JSON.stringify(allowedTeamIds)); // NOT searchGroupIds
const response = await fetch(`${apidUrl}/api/v1/tags/identify`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Dust-Ctx-Org-Id": organizationId, // "Dust-Ctx-Team-Id": teamId, // optional; omit for the org's root Team }, body: form,});const body = await response.json();
if (response.ok) { // body.type is "identified" | "matches" | "label"} else if (body.code === "IDENTIFIER_NOT_FOUND") { // An answer: nothing matched. Not a failure.} else if (body.code === "SCAN_SEARCH_INCOMPLETE") { // Retry — the item may well be enrolled.}// Verify: is this capture the item it claims to be?const form = new FormData();form.set("threadId", threadId);form.set("tagType", "DUST");form.set("data", captureBlob);form.set("tags", JSON.stringify([{ tagId, tagType: "DUST" }])); // required, objects
const response = await fetch(`${apidUrl}/api/v1/tags/verify`, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Dust-Ctx-Org-Id": organizationId }, body: form,});const body = await response.json();
// One candidate: a mismatch is an error status.// Two or more: a mismatch is HTTP 200 with { success: false } — read `success`.A complete, runnable end-to-end sequence (token exchange, organization discovery, Team discovery, create, read back) with no package dependencies is in the API quickstart.
llms.txt
Section titled “llms.txt”Following the llms.txt convention, the site root serves:
| File | Contents |
|---|---|
/llms.txt | Site map: every page with a one-line description, plus pointers to the OpenAPI spec, the interactive reference, and the npm packages |
/llms-full.txt | The full documentation content as a single plaintext document |
/llms-small.txt | A minified variant for smaller context windows |
Point your agent at /llms.txt to let it pick pages, or feed it /llms-full.txt when it needs the whole picture. Links inside the combined files are absolute URLs back to the page and section they came from, so an agent can cite the source it used.
The OpenAPI spec
Section titled “The OpenAPI spec”The authoritative API surface is the OpenAPI 3 document:
- Live from the API server:
https://apid.dustid.io/api/openapi.json - A build-time copy on this site:
/openapi.json - Interactive reference (Scalar):
https://apid.dustid.io/api/docs
The copy on this site is the public surface: DUST-internal operations are stripped from it. Use the live document when you need to be certain you are describing the server you are actually calling.
Integration skills
Section titled “Integration skills”A skill is a single Markdown file in the SKILL.md format (YAML frontmatter with name and description, then instructions) that teaches an agent one integration end to end — auth, headers, the core flows, and the failure modes. The skills are self-contained: an agent that has only the skill file can complete the integration.
Installing a skill
Section titled “Installing a skill”-
Download the skill file from the stable URL above (e.g.
/skills/dice-api-integration/SKILL.md). -
For Claude Code, place it at
.claude/skills/dice-api-integration/SKILL.mdin your project (the directory name matches the skill’sname). Claude discovers it automatically and loads it when the task matches. -
For other agents, include the file in the agent’s context or system prompt — the file is plain Markdown and self-contained.
What “generated” does and does not mean
Section titled “What “generated” does and does not mean”Each skill file carries a provenance block naming the docs version, the OpenAPI spec version, the number of paths in it, and a digest of the exact public spec the file was built against. Those four facts let you tell which API era your copy describes, and whether two copies came from the same spec.
Be precise about what that buys you:
| Part of a skill | Origin | What can go stale |
|---|---|---|
The endpoint index in dice-api-integration | Generated from the public OpenAPI spec at build time | Nothing — it is the spec’s own paths, methods and summaries |
| Version and digest lines | Generated at build time | Nothing |
| Everything else: auth instructions, parameter names, payload shapes, SDK behaviour, failure handling | Hand-written | Anything the API changes without a corresponding docs edit |
Checking generated code
Section titled “Checking generated code”A short review list for a human looking at what an agent produced:
- Every path and method appears in the spec. No invented endpoints.
/api/v1/*calls carryAuthorization: Bearer; every org-scoped one also carriesDust-Ctx-Org-Id.- Identify sends
searchTeamIds, neversearchGroupIds. - Verify sends
tagsas an array of{ tagId, tagType }objects. - Error handling branches on
code, never onmessagetext, and distinguishes “no match” from “try again” from “rescan”. - No API key or bearer token appears in anything shipped to a browser or mobile client.
- Scan receipts (
scan.scanId, ordetail.scan.scanIdon a failure) are recorded. 401triggers one refresh-and-retry, not a loop.
npm packages
Section titled “npm packages”@dustid/dust-go-connect— the DUST Go scanning bridge for web apps (see Integrate with DUST Go).@dustid/apid-client— the typed TypeScript API client. Not on the public npm registry; see TypeScript client for availability and prerequisites. An agent should not emit an install command for it.