Skip to content

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.

Give your agentFor
/skills/dice-api-integration/SKILL.mdCalling the DUST API: auth, context headers, Threads, Identifiers, files, sharing, Shipments
/skills/dust-go-connect-integration/SKILL.mdAdding DUST scanning to a web app running inside the DUST Go mobile app
/llms.txtA map of every page, so the agent can pick what it needs
/llms-full.txtThe whole documentation as one plaintext document
/openapi.jsonThe exact request and response contract

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.

  1. The identify search scope field is searchTeamIds, a JSON array of Team UUIDs. There is no searchGroupIds request field. Identify payloads reject undeclared properties, so the wrong spelling fails the whole request with 400 INVALID_REQUEST. The only surviving legacy group name is the Dust-Ctx-Grp-Id header, an accepted alias for Dust-Ctx-Team-Id.
  2. tags on 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.
  3. A failed identify is an answer with an error status. 404 IDENTIFIER_NOT_FOUND means nothing matched; 503 SCAN_SEARCH_INCOMPLETE means the search could not be completed and should be retried; 400 SCAN_LOW_KEYPOINTS means rescan. Generated code that treats every non-2xx as an exception reports outages that never happened. The canonical table is Errors and scan outcomes.
  4. 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.

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 base64
form.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.

Following the llms.txt convention, the site root serves:

FileContents
/llms.txtSite map: every page with a one-line description, plus pointers to the OpenAPI spec, the interactive reference, and the npm packages
/llms-full.txtThe full documentation content as a single plaintext document
/llms-small.txtA 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 authoritative API surface is the OpenAPI 3 document:

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.

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.

dice-api-integrationAuthenticate (API key → bearer), set context headers, and drive the core API flows: create Threads, bind Identifiers, upload files, share, ship.Download
  1. Download the skill file from the stable URL above (e.g. /skills/dice-api-integration/SKILL.md).

  2. For Claude Code, place it at .claude/skills/dice-api-integration/SKILL.md in your project (the directory name matches the skill’s name). Claude discovers it automatically and loads it when the task matches.

  3. 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 skillOriginWhat can go stale
The endpoint index in dice-api-integrationGenerated from the public OpenAPI spec at build timeNothing — it is the spec’s own paths, methods and summaries
Version and digest linesGenerated at build timeNothing
Everything else: auth instructions, parameter names, payload shapes, SDK behaviour, failure handlingHand-writtenAnything the API changes without a corresponding docs edit

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 carry Authorization: Bearer; every org-scoped one also carries Dust-Ctx-Org-Id.
  • Identify sends searchTeamIds, never searchGroupIds.
  • Verify sends tags as an array of { tagId, tagType } objects.
  • Error handling branches on code, never on message text, 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, or detail.scan.scanId on a failure) are recorded.
  • 401 triggers one refresh-and-retry, not a loop.