Aller au contenu

Démarrage rapide avec l’API

À la fin de cette page, vous aurez échangé une clé d’API contre un jeton porteur, identifié l’organisation et l’équipe dans lesquelles votre identifiant d’accès peut agir, créé une fiche, puis relu celle-ci avec son historique d’événements.

Les deux parcours ci-dessous sont complets et indépendants : chaque élément est défini avant d’être utilisé, et aucun parcours n’emprunte une étape à l’autre. Choisissez un onglet et restez-y.

Vous avez besoin des éléments suivants :

  • Une clé d’API de compte de service, émise par un administrateur de l’organisation. Les clés d’API personnelles n’existent pas — consultez Authentification et clés d’API si vous n’en avez pas encore.
  • Le compte de service doit être membre de l’équipe dans laquelle vous écrivez. La création de fiches nécessite une appartenance actuelle à l’équipe sélectionnée ; un identifiant d’accès au niveau de l’organisation qui n’appartient à aucune équipe peut lire /api/v1/me, mais ne peut pas créer de fiches. Demandez à votre administrateur de l’ajouter à une équipe si l’étape 3 renvoie 403 FORBIDDEN.
  • Parcours curl : curl et jq (les exemples l’utilisent pour analyser le JSON ; si vous préférez ne pas installer jq, copiez manuellement les valeurs depuis les réponses).
  • Parcours TypeScript : un environnement d’exécution qui exécute directement TypeScript et dispose d’un fetch global — Node.js 22.18 ou version ultérieure, Bun ou Deno. Sous Node.js 18 ou 20, exécutez le fichier avec un chargeur tel que tsx. Aucun paquet à installer : les exemples utilisent uniquement fetch sans bibliothèque supplémentaire. Un client typé est disponible séparément ; consultez Client TypeScript.

Toutes les requêtes sont envoyées à https://apid.dustid.io ; consultez Environnements pour connaître les autres URL de service.

  1. Fenêtre de terminal
    export APID_URL="https://apid.dustid.io"
    export DUST_API_KEY="your-service-account-key" # read this from your secrets manager
  2. Les clés d’API ne sont jamais envoyées aux points de terminaison /api/v1/*. Échangez une fois la clé auprès de GET /api/auth/token, en la transmettant dans l’en-tête x-api-key, puis envoyez le JWT obtenu sous la forme Authorization: Bearer <token> lors de chaque appel suivant.

    Fenêtre de terminal
    curl -fsS "$APID_URL/api/auth/token" -H "x-api-key: $DUST_API_KEY"
    { "token": "eyJhbGciOi...", "expiresIn": 900, "expiresAt": "2026-09-20T22:40:00.000Z" }
    Fenêtre de terminal
    export DUST_TOKEN="$(
    curl -fsS "$APID_URL/api/auth/token" -H "x-api-key: $DUST_API_KEY" | jq -r '.token'
    )"

    La réponse contient token et, lorsque le JWT lui-même comporte une déclaration d’expiration, expiresIn (secondes restantes) et expiresAt (ISO 8601). Lisez la durée de vie dans la réponse au lieu de la coder en dur : les jetons ont actuellement une courte durée de vie (environ 15 minutes) et il n’existe aucun jeton d’actualisation. Une tâche de longue durée doit donc effectuer un nouvel échange en cours d’exécution. Le contrat complet relatif à la durée de vie, une implémentation de mise en cache et le modèle consistant à actualiser une seule fois après un 401 sont présentés dans Authentification → Expiration et actualisation du jeton.

  3. GET /api/v1/me est l’un des rares points de terminaison qui ne nécessite aucun en-tête de contexte. Il décrit l’identifiant d’accès lui-même : le principal, les organisations auxquelles il appartient et celle qui est active.

    Fenêtre de terminal
    curl -fsS "$APID_URL/api/v1/me" -H "Authorization: Bearer $DUST_TOKEN"
    {
    "userId": "6a1f…",
    "email": "sap-connector@example.com",
    "name": "SAP Connector",
    "activeOrganizationId": "b2c7…",
    "organizations": [
    { "id": "b2c7…", "name": "Anchor Electronics", "slug": "anchor-electronics", "roles": ["member"] }
    ]
    }
    Fenêtre de terminal
    # Prefer the active organization; fall back to the first membership.
    export DUST_ORG_ID="$(
    curl -fsS "$APID_URL/api/v1/me" -H "Authorization: Bearer $DUST_TOKEN" \
    | jq -er '.activeOrganizationId // .organizations[0].id'
    )"
    echo "Organization: $DUST_ORG_ID"
  4. Les fiches appartiennent à une équipe au sein de l’organisation. Deux options sont prises en charge :

    • Ne rien faire. Omettez Dust-Ctx-Team-Id et l’API agit dans l’équipe racine de l’organisation. Pour une organisation ne comptant qu’une seule équipe, cela constitue l’intégralité de l’étape 4, et les exemples de l’étape 5 suivent ce parcours.
    • Indiquer une équipe. GET /api/v1/teams répertorie les équipes dont votre identifiant d’accès est membre, sous la forme { "teams": [ … ], "total": n }, chacune comportant teamId, orgId et name. Envoyez l’équipe souhaitée dans Dust-Ctx-Team-Id.
    Fenêtre de terminal
    curl -fsS "$APID_URL/api/v1/teams?pageSize=50" \
    -H "Authorization: Bearer $DUST_TOKEN" \
    -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \
    | jq '.teams[] | { teamId, name }'
    { "teamId": "b2c7…", "name": "Anchor Electronics" }
    { "teamId": "4e90…", "name": "Line 3 Receiving" }
    Fenêtre de terminal
    # Optional. Leave DUST_TEAM_ID unset to use the organization's root Team.
    export DUST_TEAM_ID="4e90…"

    Chaque requête ci-dessous transmet -H "Dust-Ctx-Team-Id: ${DUST_TEAM_ID:-}". Une valeur vide est traitée exactement comme un en-tête absent — l’équipe racine de l’organisation — de sorte que le même script fonctionne que vous ayez ou non défini la variable.

  5. Une fiche constitue l’enregistrement d’un actif ou d’un élément. Une requête POST /api/v1/threads avec type: "single" en crée une ; thread.name est le seul champ obligatoire, et le tableau facultatif data contient les champs typés.

    Fenêtre de terminal
    curl -fsS "$APID_URL/api/v1/threads" \
    -H "Authorization: Bearer $DUST_TOKEN" \
    -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \
    -H "Dust-Ctx-Team-Id: ${DUST_TEAM_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 } }
    ]
    }' | tee /tmp/created.json | jq '.created[0] | { threadId, name }'
    { "threadId": "0f13c0de-2f1a-4a2e-9f60-6d2f7b9f0a11", "name": "Tire SZ3J-11-ZJ17" }
    Fenêtre de terminal
    export THREAD_ID="$(jq -r '.created[0].threadId' /tmp/created.json)"

    Le statut est 201 Created et le corps est { "created": [ … ], "uploadResponses": [] } — une structure par lots, car le même point de terminaison crée plusieurs fiches à la fois avec type: "list" ou type: "raw". Chaque entrée de created est une fiche complète, comprenant son threadId généré.

    Les entrées de champ nécessitent type et value, et la structure de value dépend du type : { "text": "…" } pour text, { "number": 51 } pour number. name est le libellé du champ. La liste complète des types de champs figure dans le guide des fiches.

  6. GET /api/v1/threads/{thread_id} renvoie la fiche ainsi que son historique d’événements — chaque écriture est consignée, de sorte que la piste d’audit commence dès la création.

    Fenêtre de terminal
    curl -fsS "$APID_URL/api/v1/threads/$THREAD_ID" \
    -H "Authorization: Bearer $DUST_TOKEN" \
    -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \
    -H "Dust-Ctx-Team-Id: ${DUST_TEAM_ID:-}" \
    | jq '{ name: .thread.name, fields: [.thread.data[]?.name], events: (.events | length) }'
    { "name": "Tire SZ3J-11-ZJ17", "fields": ["Serial Number", "Max PSI"], "events": 1 }

    La structure de la réponse est { "thread": { … }, "events": [ … ] }. Le nombre exact d’événements ne fait pas partie du contrat — attendez-vous à en recevoir au moins un.

Ce que vous avez obtenuCe que cela signifie
401 UNAUTHORIZED lors de l’échangeLa clé d’API est incorrecte, révoquée ou n’est pas une clé de compte de service. Les clés personnelles ne permettent pas de s’authentifier.
401 UNAUTHORIZED lors d’un appel /api/v1/*Le jeton porteur a expiré (ces jetons ont une courte durée de vie). Effectuez un nouvel échange et réessayez une fois.
400 ORG_ID_REQUIREDVous avez omis Dust-Ctx-Org-Id sur un point de terminaison limité à une organisation.
400 INVALID_REQUEST mentionnant un en-têteUn en-tête de contexte n’était pas un UUID. Les en-têtes sont validés avant l’exécution du point de terminaison.
403 FORBIDDEN lors de la créationLe compte de service n’est pas membre de l’équipe sélectionnée. Demandez à votre administrateur de l’y ajouter.
404 lors de la relectureIl s’agit généralement d’un contexte incorrect, et non d’une fiche manquante — une fiche n’est visible que dans l’organisation et l’équipe qui la possèdent ou avec lesquelles elle a été partagée.

Le corps de chaque erreur est { code, message, status, detail? }, et chaque réponse comporte un en-tête x-request-id qu’il est utile de journaliser. La liste complète des codes, les tableaux de résultats de scan et les recommandations relatives aux nouvelles tentatives figurent dans Erreurs et résultats de scan.

  • Conventions des requêtes — en-têtes de contexte, pagination et localisation.
  • Erreurs et résultats de scan — le contrat d’échec complet.
  • Fiches — types de champs, mises à jour, archivage, listes et recherche.
  • Identifiants — lier et vérifier des identifiants physiques par rapport aux fiches (les points de terminaison /api/v1/tags/*).
  • Fichiers — joindre des fichiers d’éléments probants aux fiches.
  • Équipes et partage — accès entre équipes.
  • Client TypeScript — une solution typée à la place de l’utilisation directe de fetch.
  • Référence complète de l’API — chaque point de terminaison, généré à partir de la spécification OpenAPI. Le serveur d’API héberge également lui-même une référence interactive à l’adresse https://apid.dustid.io/api/docs et la spécification brute à l’adresse /api/openapi.json.