Leitfaden zur Identifiers API
Eine Kennung verbindet eine physische Markierung mit einem Datensatz: ein DUST-Tag, einen QR-Code, einen Barcode, ein Data-Matrix-Symbol, einen NFC-Chip oder einen gedruckten Textcode. Nach der Verknüpfung wird ein Scan vor Ort dem digitalen Datensatz zugeordnet. Der API-Namespace lautet /api/v1/tags – eine veraltete Benennung, die in Pfaden und Schemas fortbesteht; in diesen Dokumenten wird im Fließtext Kennung verwendet.
Vollständige Anfrage-/Antwortschemas: API-Referenz. Jedes Ergebnis, das die einzelnen Operationen liefern können – einschließlich jener, die als HTTP-Fehler zurückgegeben werden –, ist einmal unter Fehler und Scanergebnisse tabellarisch aufgeführt.
Operationen im Überblick
Abschnitt betitelt „Operationen im Überblick“| Operation | Methode & Pfad | Semantik |
|---|---|---|
| Extrahieren | POST /api/v1/tags/extract | Eine DUST-Aufnahme in einen kanonischen Fingerabdruck umwandeln, ohne ihn zu verknüpfen |
| Verknüpfen | POST /api/v1/tags/bind | Eine Kennung einem Datensatz zuordnen |
| Identifizieren | POST /api/v1/tags/identify | Suchen: Welcher Datensatz stimmt mit diesem Scan überein? |
| Verifizieren | POST /api/v1/tags/verify | Einen Scan mit den Kennungen eines bestimmten Datensatzes vergleichen |
| Verknüpfung lösen | POST /api/v1/tags/unbind | Eine Kennung von ihrem Datensatz trennen |
| Text festlegen | POST /api/v1/tags/text | Eine verknüpfte Kennung umbenennen bzw. neu beschreiben |
| Aktualisieren | POST /api/v1/tags/update | Lebenszyklus: Datenschutz, Archivieren/Wiederherstellen (Wert und Typ sind unveränderlich) |
Identifizieren oder verifizieren: Die Identifizierung beantwortet die Frage „Was ist das?“ – sie durchsucht die für Sie sichtbaren Datensätze (eingegrenzt durch searchTeamIds) und gibt gegebenenfalls die Übereinstimmung zurück. Die Verifizierung beantwortet die Frage „Ist dies das Objekt, das es zu sein vorgibt?“ – Sie geben eine threadId und die damit verknüpften möglichen Kennungen an, und die API bestätigt oder verneint die Übereinstimmung. Verwenden Sie die Verifizierung für Authentifizierungsentscheidungen und die Identifizierung zum Nachschlagen.
Zwei Nutzdatenfamilien
Abschnitt betitelt „Zwei Nutzdatenfamilien“Scan-Endpunkte akzeptieren multipart/form-data; die Struktur von data hängt vom Kennungstyp ab:
tagType | data | Herkunft |
|---|---|---|
DUST | Ein Bild – ein binärer Dateiteil oder eine Base64-Daten-URL (data:image/jpeg;base64,…) | Eine optische DUST-Aufnahme von einem Scanner |
QR, BAR_CODE, DATA_MATRIX, NFC | Der decodierte Zeichenfolgeninhalt (oder die hexadezimale NFC-ID) | Ein beliebiger Symbolscanner |
TEXT | Der gedruckte, menschenlesbare Code in der Form, in der eine Person ihn liest | Tastatureingabe oder Registrierung eines Etiketts |
Eine DUST-Aufnahme ist ein Foto des Tags, kein decodierter Wert – der Server extrahiert den Fingerabdruck. Aufnahmen stammen von DUST-Scanhardware: Informationen zur mobilen Aufnahme finden Sie unter Integration mit DUST Go, und der React Scanner ist eine direkt einsetzbare Webkomponente, die alle Modi unterstützt.
In Multipart-Nutzdaten werden strukturierte Felder (options, tags, searchTeamIds) als JSON-Zeichenfolgen übergeben.
Textkennungen
Abschnitt betitelt „Textkennungen“TEXT ist der menschenlesbare Code, der auf einen Gegenstand oder ein Etikett gedruckt ist – beispielsweise eine Seriennummer wie AB00017. Es gibt kein zu decodierendes Symbol; der Wert wird daher eingegeben (oder stammt aus dem Registrierungsdatensatz eines Etiketts) und exakt wie eingegeben gespeichert. Da eine Person den Code liest, ist TEXT der einzige Typ, bei dem die Plattform ohne Beachtung der Groß-/Kleinschreibung nach Übereinstimmungen sucht: Bei der Identifizierung oder Verifizierung mit ab00017 wird ein verknüpftes AB00017 gefunden. Bei jedem anderen Typ erfolgt der Abgleich Byte für Byte.
Wie QR-, Barcode-, Data-Matrix- und NFC-Werte kann auch ein Textcode kopiert werden und besitzt keine eigene Eindeutigkeit – derselbe Code kann berechtigterweise auf mehreren Datensätzen oder auf jedem Etikett einer Etikettenrolle vorkommen. Ein wiederholter Wert wird nicht abgelehnt; die Etikettenrolle meldet Wiederholungen lediglich als Warnung.
Eine DUST-Aufnahme extrahieren
Abschnitt betitelt „Eine DUST-Aufnahme extrahieren“Beim Extrahieren wird eine Aufnahme in einen kanonischen Fingerabdruck umgewandelt und dessen Qualität zurückgegeben. Dies ist hilfreich, um eine Aufnahme vor der Registrierung zu prüfen oder eine Verknüpfung vorzubereiten:
curl -fsS "$APID_URL/api/v1/tags/extract" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "data=@scan.jpeg" \ -F 'options={"enrollmentSessionId":"3d5e…"}'Die Antwort lautet { id, qualityScore, annotatedImage?, forensics?, scan? } – id ist eine Fingerabdruck-ID, die Sie später verknüpfen können, ohne das Bild erneut hochzuladen (siehe unten). options enthält außerdem Aufnahmemetadaten (Gerät, Optik, Geolokalisierung), die von der Plattform zusammen mit dem Scan gespeichert werden.
Der Scanbeleg
Abschnitt betitelt „Der Scanbeleg“Jede Operation, die ein Bild übermittelt – Extrahieren, Verknüpfen, Identifizieren, Verifizieren und Manipulationsanalyse –, gibt ein scan-Objekt zurück, das angibt, was gespeichert wurde:
{ "scanId": "…", "fingerprintId": "…", "dustId": "…" }scanIdist immer vorhanden, sobald das Bild gespeichert wurde. Sie ist die stabile Identität der Aufnahme und der Wert, den Sie aufbewahren sollten, wenn Sie Scanvorgänge auf Ihrer Seite erfassen.fingerprintIdist vorhanden, wenn die Extraktion erfolgreich war (andernfallsnull).dustIdist vorhanden, wenn die Operation Ihnen eine DUST-Kennung zurückgegeben hat: die durch eine Verknüpfung erstellte Kennung, eine durch eine Verifizierung bestätigte Kennung oder eine durch eine Identifizierung aufgelöste Kennung. Bei einer Nichtübereinstimmung, keiner Übereinstimmung, einer Extraktion oder einer Manipulationsanalyse ist der Wertnull(die dortige Kennung haben Sie angegeben; sie wurde nicht anhand des Bildes aufgelöst). Das gilt auch für eine Identifizierung, die mehrere Kandidaten zurückgibt, da jeder Kandidat seine eigene Kennung enthält.
Bei einer fehlgeschlagenen Verifizierungsübereinstimmung und einer Identifizierung ohne Übereinstimmung bleiben der bestehende Fehlerstatus und Fehlercode erhalten; derselbe Beleg wird unter detail.scan mitgeführt – der Scan wurde gespeichert, obwohl das Ergebnis negativ war. Dasselbe gilt für eine wegen ihrer Qualität abgelehnte Aufnahme – zu wenige oder keine nutzbaren Schlüsselpunkte –, unabhängig davon, welchen Fehlercode die jeweilige Operation dafür meldet (/tags/extract antwortet mit SCAN_EXTRACTION_FAILURE, die Identifizierung liefert SCAN_LOW_KEYPOINTS / SCAN_NO_KEYPOINTS, und die Verifizierung antwortet mit dem üblichen IDENTIFIER_VERIFY_FAILED): Das Bild wird aufbewahrt, und sein Beleg enthält fingerprintId: null, da nichts Nutzbares daraus extrahiert wurde. Nur wenn die Plattform ein Bild überhaupt nicht decodieren konnte, wird nichts gespeichert und kein Beleg erstellt.
Eine Kennung mit einem Datensatz verknüpfen
Abschnitt betitelt „Eine Kennung mit einem Datensatz verknüpfen“POST /api/v1/tags/bind akzeptiert drei anhand von tagType und den Nutzdaten unterscheidbare Formen:
curl -fsS "$APID_URL/api/v1/tags/bind" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "threadId=$THREAD_ID" \ -F "tagType=DUST" \ -F "tagDescription=Inbound receiving scan" \ -F "data=@scan.jpeg" \ -F 'options={"enrollmentSessionId":"3d5e…"}'# QR, BAR_CODE, DATA_MATRIX, NFC: the decoded contentscurl -fsS "$APID_URL/api/v1/tags/bind" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "threadId=$THREAD_ID" \ -F "tagType=QR" \ -F "data=https://example.com/item/SZ3J-11-ZJ17"# TEXT: the printed code as a person reads itcurl -fsS "$APID_URL/api/v1/tags/bind" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "threadId=$THREAD_ID" \ -F "tagType=TEXT" \ -F "data=AB00017"# Reuse a fingerprint from a prior /extract — no image re-uploadcurl -fsS "$APID_URL/api/v1/tags/bind" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "threadId=$THREAD_ID" \ -F "tagType=DUST" \ -F "fingerprintId=$FINGERPRINT_ID"options.enrollmentSessionId ist bei einer DUST-Verknüpfung optional. Geben Sie eine vom Client erzeugte UUID an – dieselbe für einen gesamten Durchlauf –, wenn mehrere Aufnahmen zusammengehören, etwa wenn eine Registrierungsstation einen Stapel verarbeitet oder ein Objekt aus mehreren Blickwinkeln aufgenommen wird; die Plattform gruppiert diese Scans dann unter dieser Sitzung. Lassen Sie die Angabe bei einer einmaligen Verknüpfung vollständig weg. Bei DUST-Bildverknüpfungen kann mit options.returnAnnotatedImage: true außerdem die kommentierte Aufnahme zurückgegeben werden.
Ein Etikett verknüpfen
Abschnitt betitelt „Ein Etikett verknüpfen“Wenn die gescannte Kennung zu einem Etikett gehört, dessen Eigentümer das Team des Datensatzes ist (siehe Etiketten), erstellt die Verknüpfung keine einzelne Kennung. Stattdessen wird das gesamte Etikett verknüpft: Jede aktive Mitgliedskennung wird in einer einzigen Operation an den Datensatz angefügt. Die Antwort enthält zusätzlich zum üblichen tag, also dem von Ihnen gescannten Mitglied, auch label (das Etikett, seine Etikettenrolle und seine Position) sowie boundTags (alle verknüpften Mitglieder). Übergeben Sie activateLabel: true, um im Rahmen der Verknüpfung auch die DUST-Kennungen des Etiketts identifizierbar zu machen; dies ist optional. Ist ein Etikett bereits mit einem anderen Datensatz verknüpft, wird IDENTIFIER_ALREADY_BOUND mit detail.compositeTagId zurückgegeben.
Einen Datensatz anhand eines Scans identifizieren
Abschnitt betitelt „Einen Datensatz anhand eines Scans identifizieren“curl -fsS "$APID_URL/api/v1/tags/identify" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "tagType=DUST" \ -F "data=@scan.jpeg" \ -F 'searchTeamIds=["'"$TEAM_ID"'"]'const result = await client.tags.identify({ tagType: "DUST", data: scanBlob, searchTeamIds: [teamId],});Die Identifizierung akzeptiert auch Wertnutzdaten (tagType gleich QR/BAR_CODE/DATA_MATRIX/NFC mit den decodierten data oder TEXT mit dem gedruckten Code, der ohne Beachtung der Groß-/Kleinschreibung abgeglichen wird) sowie eine alleinstehende Kennungs-ID (tagType: "ANY" mit tagId).
Mögliche Ergebnisse der Identifizierung
Abschnitt betitelt „Mögliche Ergebnisse der Identifizierung“Ein Treffer gibt 200 mit der übereinstimmenden Kennung und ihrem Datensatz zurück. Ein Fehlschlag hat einen Fehlerstatus und ist keine 200-Antwort mit einem leeren Ergebnis: Eine definitive Nichtübereinstimmung ist 404 IDENTIFIER_NOT_FOUND, während eine Suche, die nicht abgeschlossen werden konnte, 503 SCAN_SEARCH_INCOMPLETE ergibt – eine andere Situation, die einer Bedienperson nicht als „nicht gefunden“ angezeigt werden darf. Beide enthalten den Scanbeleg unter detail.scan.
Die kanonische Tabelle aller acht Ergebnisse – identifizierter Datensatz, mehrere Kandidaten, unverknüpftes Etikett, keine Übereinstimmung, unvollständige Suche, mehrdeutige Übereinstimmung, abgelehnte Aufnahme und nicht verknüpfte Kennung – einschließlich Status, Code und korrekter Clientreaktion finden Sie unter Fehler und Scanergebnisse → Kanonische Identifizierungsergebnisse. Verzweigen Sie anhand von code, und lesen Sie detail.outcome (no_match, search_incomplete, ambiguous, quality_reject), wenn Sie die genauere Unterscheidung benötigen.
Jede zurückgegebene Kennung, die zu einem Etikett gehört, enthält tag.label (ihr Etikett, ihre Etikettenrolle und ihre Position). Wenn der Scan mit einem Mitglied eines unverknüpften Etiketts im Bestand des aktiven Teams übereinstimmt, lautet das Ergebnis { type: "label", label: { label, tags } }: Es gibt noch keinen Datensatz, aber das Etikett und seine Mitgliedskennungen werden zurückgegeben, sodass ein Client die Verknüpfung anbieten kann (siehe Etiketten).
Den Suchumfang auswählen
Abschnitt betitelt „Den Suchumfang auswählen“searchTeamIds ist ein JSON-Array von Team-UUIDs (in Multipart-Nutzdaten eine JSON-Zeichenfolge). Wenn Sie es weglassen, durchsucht die Identifizierung genau ein Team: das durch Dust-Ctx-Team-Id angegebene Team, wobei standardmäßig das Stammteam der Organisation verwendet wird.
Die IDs sind nicht beliebig. Teams derselben Organisation, denen Sie angehören, liegen immer im Umfang; das Team einer Partnerorganisation ist nur über eine aktive Verbindung erreichbar, die den Datenfluss zu Ihnen zulässt. Alles andere wird stillschweigend aus dem Umfang entfernt, statt die Anfrage fehlschlagen zu lassen. Ein scheinbar großer Umfang kann daher nur eine kleine Menge durchsuchen. Ermitteln Sie die gültigen IDs, statt sie fest zu codieren:
GET /api/v1/teams– die Teams in Ihrer Organisation, denen Ihre Anmeldedaten zugeordnet sind ({ teams: [{ teamId, orgId, name, … }], total }).GET /api/v1/teams/connected– die Partnerteams, die Sie durchsuchen dürfen, als Verbindungsdatensätze, in denen die beiden verknüpften Teams genannt sind.
Einen Scan anhand eines Datensatzes verifizieren
Abschnitt betitelt „Einen Scan anhand eines Datensatzes verifizieren“Die Verifizierung ist das grundlegende Authentifizierungsverfahren: Anhand eines neuen Scans, einer threadId und der bereits mit diesem Datensatz verknüpften möglichen tags ist sie erfolgreich, wenn ein Kandidat übereinstimmt.
tags ist erforderlich und ein Array von Objekten – jeweils { "tagId": "…", "tagType": "…" } –, kein Array aus ID-Zeichenfolgen. In Multipart-Nutzdaten wird es als JSON-Zeichenfolge gesendet:
curl -fsS "$APID_URL/api/v1/tags/verify" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -F "threadId=$THREAD_ID" \ -F "tagType=DUST" \ -F "data=@scan.jpeg" \ -F 'tags=[{"tagId":"'"$TAG_ID"'","tagType":"DUST"}]'const form = new FormData();form.set("threadId", threadId);form.set("tagType", "DUST");form.set("data", scanBlob);form.set("tags", JSON.stringify([{ tagId, tagType: "DUST" }]));Herkunft der Kandidaten-IDs
Abschnitt betitelt „Herkunft der Kandidaten-IDs“Die tagId-Werte sind die bereits mit dem zu prüfenden Datensatz verknüpften Kennungen. Lesen Sie sie aus dem Datensatz: GET /api/v1/threads/{thread_id} gibt sie in thread.tags zurück, jeweils mit tagId und tagType. Eine typische Verifizierung ruft daher den Datensatz ab, filtert seine Kennungen nach dem soeben aufgenommenen Typ und sendet sie als Kandidatenliste:
const record = await getThread(threadId); // GET /api/v1/threads/{thread_id}const candidates = (record.thread.tags ?? []) .filter((tag) => tag.tagType === "DUST") .map((tag) => ({ tagId: tag.tagId, tagType: tag.tagType }));Wenn Sie eine Kennung senden, die nicht mit diesem Datensatz verknüpft ist, schlägt die Verifizierung fehl, statt eine Übereinstimmung mit etwas anderem zu finden.
Das Ergebnis auswerten
Abschnitt betitelt „Das Ergebnis auswerten“Die Anzahl der Kandidaten verändert die Antwortstruktur, was hier der mit Abstand häufigste Integrationsfehler ist:
Länge von tags | Übereinstimmung | Keine Übereinstimmung |
|---|---|---|
| Genau einer | 200 mit { tag, scan? } | IDENTIFIER_VERIFY_FAILED (HTTP 500), Beleg unter detail.scan |
| Zwei oder mehr | 200 mit { success: true, verifiedTag, attemptedCount, failedCount, scan? } | 200 mit { success: false, attemptedCount, failedCount, error, scan? } |
Eine Verifizierung mehrerer Kandidaten ohne Übereinstimmung ist somit ein erfolgreicher HTTP-Aufruf, der success: false enthält. Behandeln Sie response.ok niemals als Nachweis der Authentizität – lesen Sie immer success, wenn Sie mehr als einen Kandidaten senden. Siehe Fehler und Scanergebnisse → Verifizierungsergebnisse.
Verknüpfte Kennungen verwalten
Abschnitt betitelt „Verknüpfte Kennungen verwalten“Dies sind einfache JSON-Endpunkte; sie alle erfordern sowohl die tagId als auch die threadId des Datensatzes, mit dem die Kennung verknüpft ist:
POST /api/v1/tags/text–nameund/oderdescriptionfestlegen.POST /api/v1/tags/update–name,description,isPrivateundarchivedAtfestlegen (ein ISO-Zeitstempel archiviert die Kennung;nullstellt sie wieder her). Wert und Typ der Kennung sind unveränderlich – führen Sie stattdessen eine erneute Verknüpfung durch.POST /api/v1/tags/unbind– die Kennung vom Datensatz trennen.
Manipulationsanalyse
Abschnitt betitelt „Manipulationsanalyse“Unter /api/v1/tamper vergleicht eine Manipulationsanalyse einen neuen Scan einer DUST-Kennung mit der bei ihrer Verknüpfung erstellten Referenzaufnahme und erfasst die ermittelten Messwerte. Die API gibt ausschließlich Messwerte und Nachweise zurück – es gibt auf der gesamten Oberfläche weder eine zusammenfassende Zahl noch ein Band, einen Schwellenwert oder ein von der Plattform erstelltes Ergebnisfeld. alignmentOutcome gibt ausschließlich an, ob die beiden Scans überhaupt verglichen werden konnten. Wenn dies nicht möglich war, sind die Messwerte nicht vergleichbar; dies ist keine Aussage über die Kennung.
| Operation | Methode & Pfad |
|---|---|
| Eine Analyse ausführen | POST /api/v1/tamper/analyses – formularcodiert: threadId, tagId und genau eines von data oder queryFingerprintId |
| Eine Beobachtung erfassen | POST /api/v1/tamper/observations – { analysisId, result } |
| Analysen eines Datensatzes auflisten | GET /api/v1/tamper/analyses?threadId=… (optional tagId, limit) |
| Eine Analyse abrufen | GET /api/v1/tamper/analyses/{analysis_id} |
| Eine Ergebnis-Bitmap abrufen | GET /api/v1/tamper/analyses/{analysis_id}/artifacts/{name} |
Zum Ausführen einer Analyse wird eine multipart/form-data- oder application/x-www-form-urlencoded-Nutzdatenstruktur mit threadId, tagId und genau einer der folgenden Angaben benötigt:
data– der DUST-Scan selbst als Datei oder Base64-codiertes Bild. Der Dienst extrahiert ihn für Sie.queryFingerprintId– eine Fingerabdruck-ID, die Sie bereits überPOST /api/v1/tags/extract(siehe oben) erhalten haben, falls Sie sie separat extrahiert haben.
Werden beide oder keine der Angaben gesendet, wird die Anfrage abgelehnt. In beiden Fällen ist eine gewöhnliche DUST-Aufnahme eine gültige Eingabe – für die Manipulationsanalyse gibt es keinen separaten Aufnahmepfad. Kann der übermittelte Scan nicht gelesen werden, schlägt die Anfrage fehl und es wird keine Analyse erfasst.
Eine Manipulationsbeobachtung ist die einzige Schlussfolgerung, die von der Plattform gespeichert wird, und sie wird von einer Person verfasst: result ist entweder consistent, expected, inconsistent oder unknown, besitzt keinen Standardwert und ist erforderlich. expected erfasst die für den Anwendungsfall und das Trägermaterial der Kennung normale Abnutzung. Beobachtungen sind unveränderlich und einer Person zugeordnet; eine neue Beobachtung ersetzt niemals eine frühere, und Lesevorgänge geben die gesamte Reihe (observations, neueste zuerst) statt eines einzelnen aktuellen Ergebnisses zurück. Leiten Sie kein Ergebnis aus den Messwerten ab und reduzieren Sie die Reihe in Ihrer eigenen Benutzeroberfläche nicht auf einen einzelnen Wert.
Eine Analyse enthält metrics (ein unverändert weitergereichtes Objekt mit den Abdeckungsanteilen und Markerzahlen des Algorithmus), optionale markerPoints und artifactNames. Die Markerkoordinatensätze befinden sich jeweils im Pixelraum ihres eigenen Scans – führen Sie sie in einem Koordinatensystem zusammen, indem Sie metrics.transformation_matrix auf die Abfragepunkte anwenden. Ergebnis-Bitmaps sind geschützte Inhalte: Rufen Sie sie über den Artefaktendpunkt ab, der jede Anfrage erneut autorisiert und nicht zwischenspeicherbare Bytes zurückgibt.
Etiketten
Abschnitt betitelt „Etiketten“Ein Etikett (Bezeichnung im Übertragungsformat: composite tag, Namespace /api/v1/composite-tags) ist ein physisches Etikett mit einer oder mehreren Kennungen beliebigen Typs; DUST ist nicht erforderlich. Etiketten befinden sich an einer Position auf einer Etikettenrolle (collection.kind = "reel", identifiziert durch ihre UUID; ihr name ist die gedruckte Rollennummer oder ein beliebiger Titel und niemals eindeutig). Etikettenrollen können in einer Etikettensammlung (kind = "reel_collection") abgelegt werden, einem Ordner, der niemals versendet wird. expectedIdentifiers einer Etikettenrolle gibt in der Form [{ "tagType", "count" }] an, wie viele Kennungen jedes Typs ein vollständiges Etikett darauf enthält (standardmäßig eine TEXT-, eine DUST- und eine QR-Kennung; ein Eingabewert count von 0 bedeutet, dass der Typ nicht erwartet wird). Dies ist ein Hinweis für Registrierungsstationen, keine Einschränkung. Das complete-Flag eines Etiketts bedeutet, dass es mindestens die erwartete Anzahl aktiver Kennungen jedes Typs besitzt.
| Operation | Methode & Pfad |
|---|---|
| Etikettensammlungen auflisten/erstellen | GET, POST /api/v1/composite-tags/collections; PATCH …/collections/{collection_id} |
| Etikettenrollen auflisten | GET /api/v1/composite-tags/reels?collectionId=…&unfiled=…&transferred=any|only|hide&q=… |
| Eine Etikettenrolle erstellen | POST /api/v1/composite-tags/reels – { name, description?, collectionId?, expectedIdentifiers? } |
| Eine Etikettenrolle abrufen/aktualisieren | GET, PATCH /api/v1/composite-tags/reels/{reel_collection_id} (umbenennen, erwartete Zusammensetzung, collectionId zum Verschieben; null entfernt sie aus dem Ordner) |
| Ein Etikett erstellen | POST /api/v1/composite-tags/reels/{reel_collection_id}/labels (Multipart) |
| Eine Mitgliedskennung hinzufügen/entfernen | POST /api/v1/composite-tags/{composite_tag_id}/identifiers (Multipart); DELETE …/identifiers/{tag_id} |
| Etiketten auflisten/abrufen | GET /api/v1/composite-tags?reelCollectionId=…&bound=any|only|unbound&transferred=…&q=…; GET …/{composite_tag_id} |
| Ein Etikett anhand eines Mitgliedswerts auflösen | POST /api/v1/composite-tags/resolve – { tagType, value, reelCollectionId? } (TEXT wird ohne Beachtung der Groß-/Kleinschreibung abgeglichen); die Antwort enthält detail (erste Übereinstimmung) und candidates[] (alle Übereinstimmungen, bei Angabe einer Etikettenrolle nach Position sortiert) |
| Etiketten verschieben oder abtrennen | POST /api/v1/composite-tags/move; Vorabprüfung mit POST /api/v1/composite-tags/move/preview |
| Ein Etikett verknüpfen/Verknüpfung lösen | POST /api/v1/composite-tags/{composite_tag_id}/bind – { threadId, options?: { indexing: "default" } }; POST …/unbind |
| Einen Rollenbereich massenverknüpfen | POST /api/v1/composite-tags/reels/{reel_collection_id}/bulk-bind – { fromPosition, toPosition, threadIds, activate?, dryRun? } |
| Ein Etikett archivieren/wiederherstellen | POST …/{composite_tag_id}/archive, POST …/unarchive |
| Aktivieren | POST …/{composite_tag_id}/activate; POST /api/v1/composite-tags/reels/{reel_collection_id}/activate (im Hintergrund) |
| Einzelne DUST-Kennungen aktivieren | POST /api/v1/tags/activate – { tagIds[] } (bis zu 200); ein Ergebnis je Kennung, nur vorwärtsgerichtet |
Eine Etikettenrolle erstellen und Etiketten registrieren
Abschnitt betitelt „Eine Etikettenrolle erstellen und Etiketten registrieren“curl -fsS "$APID_URL/api/v1/composite-tags/reels" \ -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" \ --data '{ "name": "0030", "expectedIdentifiers": [{ "tagType": "TEXT", "count": 1 }, { "tagType": "DUST", "count": 1 }, { "tagType": "QR", "count": 1 }] }'Die Antwort lautet { reel }, eine Zusammenfassung der Etikettenrolle mit Zählerständen von null. Bewahren Sie reel.collectionId auf; damit wird die Etikettenrolle identifiziert. Beim Erstellen einer Etikettenrolle wird immer eine neue erstellt: Eine Wiederverwendung anhand des Namens findet nicht statt.
Jedes Etikett wird mit einer eigenen Multipart-Anfrage erstellt. Geben Sie höchstens ein DUST-Bild als data an; jedes weitere Mitglied wird über identifiers übergeben, ein JSON-Array mit Einträgen der Form { tagType, value }, oder als { tagType: "DUST", fingerprintId } für eine weitere DUST-Kennung, die bereits über POST /api/v1/tags/extract extrahiert wurde. humanReadable und qrValue sind Kurzformen für ein TEXT- bzw. ein QR-Mitglied. position verwendet standardmäßig die nächste freie Position auf der Etikettenrolle.
curl -fsS "$APID_URL/api/v1/composite-tags/reels/$REEL_COLLECTION_ID/labels" \ -H "Authorization: Bearer $DUST_TOKEN" \ -H "Dust-Ctx-Org-Id: $DUST_ORG_ID" \ -H "Dust-Ctx-Team-Id: $DUST_TEAM_ID" \ -F "position=1" \ -F "data=@scan.jpeg" \ -F 'identifiers=[{"tagType":"TEXT","value":"AB00001"},{"tagType":"QR","value":"https://v.example/ab00001"}]' \ -F 'options={"indexing":"none"}'Es muss mindestens eine Kennung entstehen. Eine erfolgreiche Antwort enthält outcome: "created"; ein erneuter Versuch mit derselben DUST-Markierung an derselben Position wird als outcome: "already_enrolled" abgeglichen. Ist eine DUST-Kennung bereits einem anderen Etikett zugeordnet oder bereits verknüpft, wird 409 COMPOSITE_TAG_CONFLICT zurückgegeben. Wiederholte TEXT- oder QR-Werte werden niemals abgelehnt: Die Etikettenrolle meldet sie stattdessen unter warnings, da manche Etikettenrollen berechtigterweise einen Wert wiederholen.
options.indexing wählt den DUST-Indexierungsmodus für das Bild in data: default (identifizierbar), sofern Sie nicht none (nur verifizierbar) anfordern. Unbeaufsichtigte Registrierungsstationen registrieren in der Regel zunächst nur verifizierbare Kennungen und aktivieren sie später. Bei der Aktivierung wird jede DUST-Kennung indexiert und die Duplikatprüfung der Plattform ausgeführt. Ein Etikett, dessen DUST-Kennung eine bereits indexierte Kennung dupliziert, wird daher gemeldet und übersprungen.
Der entsprechende Ablauf mit dem typisierten Client lautet:
const created = await client.compositeTags.createReel({ name: "0030" });
const form = new FormData();form.set("position", "1");form.set("data", scanBlob);form.set("identifiers", JSON.stringify([{ tagType: "TEXT", value: "AB00001" }]));await client.compositeTags.createLabel(created.reel.collectionId, form);
const state = await client.compositeTags.getReel(created.reel.collectionId);await client.compositeTags.activateReel(created.reel.collectionId);Verschieben und abtrennen
Abschnitt betitelt „Verschieben und abtrennen“POST /api/v1/composite-tags/move akzeptiert eine source, ein target und einen optionalen expectedCount.
Es gibt drei Formen für die Quelle:
{ compositeTagIds }– einzeln ausgewählte Etiketten, die in der angegebenen Reihenfolge verschoben werden.{ reelCollectionId, fromPosition, toPosition? }– ein typisierter Positionsbereich (ein abgetrennter Bereich);toPositionverwendet standardmäßig die letzte Position der Etikettenrolle.{ fromCompositeTagId, toCompositeTagId }– ein durch Scans begrenzter abgetrennter Bereich: das erste und letzte Etikett des Abschnitts, in beliebiger Reihenfolge. Der Server liest ihre Positionen unter einer Sperre; beide müssen aktive Etiketten auf derselben Etikettenrolle sein (andernfalls stehtendpoints_on_different_reels,endpoint_archivedoderendpoint_not_on_reelindetail.reason). Lösen Sie jedes Etikett anhand eines gescannten Werts mit/resolveauf. Grenzen Sie die Suche dabei auf die Etikettenrolle ein, damit ein wiederholter gedruckter Code als mehrerecandidateserscheint, zwischen denen der Aufrufer unterscheiden kann. Bei einer aktivierten DUST-Kennung können Sie alternativPOST /api/v1/tags/identifyverwenden.
Das target ist { reelCollectionId } oder { newReel: { name, description?, collectionId?, expectedIdentifiers? } } (eine neue Etikettenrolle übernimmt die Zusammensetzung der Quellrolle, wenn keine angegeben wird).
Jedes aktive Etikett innerhalb eines Abschnitts wird verschoben; Positionen mit einem archivierten oder versendeten Etikett oder ganz ohne Etikett sind Lücken, die auf der Quellrolle verbleiben. Die Positionen bleiben erhalten, wenn jede davon auf dem Ziel frei ist; andernfalls wird der gesamte Stapel in der Reihenfolge der Quelle an die letzte Position des Ziels angehängt. Die Antwort listet moved[] auf und enthält bei einer Bereichsquelle oder einer durch Scans begrenzten Quelle außerdem cut: { sourceReel, fromPosition, toPosition, count, boundCount, boundPositions, gaps[] }.
Mit expectedCount wird die Anzahl zum verbindlichen Wert: Ist die Angabe vorhanden, wird das Verschieben mit 400 INVALID_REQUEST und detail.reason: "count_mismatch" (expected, actual, fromPosition, toPosition) abgelehnt, sofern nicht genau so viele aktive Etiketten verschoben würden.
POST /api/v1/composite-tags/move/preview akzeptiert dieselbe source, ein optionales target und expectedCount, ändert nichts und gibt span, count, boundCount, das first und last Etikett des Stapels, predictedOutcome (kept_positions / appended / null), countMatches und suggestedLast zurück – das weiter hinten auf der Etikettenrolle liegende Etikett, mit dem expectedCount erfüllt würde, wenn der Abschnitt zu kurz ist. Es ist lediglich ein Vorschlag an die Bedienperson, welches Etikett gescannt werden sollte, und wird vom Server niemals angewendet. Die Vorschau erfordert die Mitgliedsstufe; für das Verschieben ist ein Team- oder Organisationsadministrator erforderlich.
Einen Rollenbereich massenverknüpfen
Abschnitt betitelt „Einen Rollenbereich massenverknüpfen“POST /api/v1/composite-tags/reels/{reel_collection_id}/bulk-bind verknüpft die Etiketten an den Positionen fromPosition..toPosition (einschließlich) der Reihe nach mit threadIds: die k-te Position mit dem k-ten Datensatz. Die Operation erfolgt vollständig oder gar nicht und ist strikt: Der Bereich muss genau threadIds.length Positionen umfassen (toPosition ist erforderlich und wird nicht abgeleitet, sodass der Aufrufer den auf der Spule verifizierten Bereich ausdrücklich angibt), pro Aufruf sind höchstens 500 Paare zulässig, und jede Position muss ein aktives, unverknüpftes Etikett enthalten. Der Server überspringt niemals eine Position, da dadurch jedes nachfolgende Paar unbemerkt verschoben würde.
Übergeben Sie dryRun: true, um eine Vorabprüfung ohne Verknüpfung auszuführen. Die Antwortstruktur ist in beiden Fällen identisch:
outcome–"bound"nach einer tatsächlichen Verknüpfung,"preflight"bei einem Probelauf.rows[]– ein Eintrag je Paarung:index,position,compositeTagId(nullbei einer leeren Position),labelName,textValue(dasTEXT-Mitglied des Etiketts, also der gedruckte Code),threadId,threadName,threadDescription.blockers[]undwarnings[]–{ kind, index, position, compositeTagId?, threadId?, tagType?, existing? }.activation–"queued","not_requested","already_active"oder"no_dust".reel– die Zusammenfassung der Etikettenrolle mit aktualisierten Zählerständen.
Arten von Blockierungen: position_empty, label_archived, label_transferred, label_bound, label_no_identifiers, identifier_bound_elsewhere, identifier_in_other_team_label, thread_not_owned, thread_unavailable, thread_in_transfer, thread_not_editable, thread_repeated. Arten von Warnungen: label_incomplete (ein Etikett mit weniger Kennungen, als von der Etikettenrolle erwartet werden) und thread_has_label (der Datensatz trägt bereits ein Etikett; existing[] nennt diese). Warnungen verhindern eine Verknüpfung niemals.
Ein Übernahmeversuch mit mindestens einer Blockierung schlägt mit 409 COMPOSITE_TAG_CONFLICT fehl; detail enthält dieselben rows, blockers und warnings wie ein Probelauf, sodass ein Client immer nur eine Struktur verarbeiten muss. Unterscheidet sich die Länge eines Bereichs von threadIds.length, wird 400 INVALID_REQUEST zurückgegeben.
Berechtigung: Teammitgliedschaft für die Etikettenrolle sowie Bearbeitungsberechtigung für jeden Datensatz. Ein Datensatz, den der Aufrufer nicht bearbeiten darf, erzeugt für die betreffende Zeile die Blockierung thread_not_editable, statt die gesamte Anfrage unmittelbar abzulehnen. Außerdem muss jeder Datensatz Eigentum des Teams der Etikettenrolle sein – ein lediglich mit dem Team geteilter Datensatz ergibt thread_not_owned.
Bei activate: true wird zunächst die Verknüpfung übernommen; anschließend aktiviert ein einzelner Hintergrundauftrag genau die DUST-Markierungen der verknüpften Etiketten. Ein Etikett, dessen Aktivierung fehlschlägt, bleibt verknüpft und nur verifizierbar. Fragen Sie den Wert counts.identifiableCount der Etikettenrolle ab, um den Fortschritt zu verfolgen.
# Preflightcurl -fsS "$APID_URL/api/v1/composite-tags/reels/$REEL_COLLECTION_ID/bulk-bind" \ -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" \ --data '{ "fromPosition": 1, "toPosition": 3, "threadIds": ["'$THREAD_1'", "'$THREAD_2'", "'$THREAD_3'"], "dryRun": true }'
# Commit, activating the bound Labels afterwardscurl -fsS "$APID_URL/api/v1/composite-tags/reels/$REEL_COLLECTION_ID/bulk-bind" \ -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" \ --data '{ "fromPosition": 1, "toPosition": 3, "threadIds": ["'$THREAD_1'", "'$THREAD_2'", "'$THREAD_3'"], "activate": true }'Mit dem typisierten Client:
const preview = await client.compositeTags.bulkBind(reelCollectionId, { fromPosition: 1, toPosition: threadIds.length, threadIds, dryRun: true,});if (preview.blockers.length === 0) { await client.compositeTags.bulkBind(reelCollectionId, { fromPosition: 1, toPosition: threadIds.length, threadIds, activate: true, });}Die Verknüpfung hinterlässt genau die Ereignisse, die N einzelne Verknüpfungen erzeugen würden: ein bind-Ereignis je Mitgliedskennung, das jeweils den Datensatz, die Kennung und das Etikett als Ziele enthält; alle teilen dieselbe Operations-ID.
Verknüpfen, Verknüpfung lösen und versenden
Abschnitt betitelt „Verknüpfen, Verknüpfung lösen und versenden“Ein Etikett wird als Ganzes verknüpft: POST …/{composite_tag_id}/bind fügt das Etikett und jede aktive Mitgliedskennung an den Datensatz an; mit options.indexing: "default" wird es außerdem aktiviert. Dasselbe geschieht, wenn Sie das gewöhnliche POST /api/v1/tags/bind mit einer beliebigen Mitgliedskennung aufrufen (siehe Ein Etikett verknüpfen), wie es Scanner tun. Für die Verknüpfung sind eine Bearbeitungsberechtigung für den Datensatz und das Eigentum des Teams am Etikett erforderlich; zudem muss der Datensatz Eigentum desselben Teams sein. Wird eine Mitgliedskennung auf einen Datensatz gescannt, den ein anderes Team mit Ihnen geteilt hat, wird dies abgelehnt (409 COMPOSITE_TAG_CONFLICT, reason: "label_owned_by_other_team"), statt die Kennung als einzelne Kopie zu verknüpfen. POST …/unbind trennt das Etikett und alle seine Mitglieder vom Datensatz.
Das Eigentum von Team und Organisation wird ausschließlich aus Kontext-Headern abgeleitet, und der Ersteller aus dem verifizierten Bearer-Token. Zum Lesen und Aktivieren von Etiketten ist eine Teammitgliedschaft erforderlich. Das Erstellen von Etikettenrollen sowie das Registrieren, Verschieben und Archivieren ist für angemeldete Team- oder Organisationsadministratoren oder für ein organisationsweit gültiges Servicekonto zulässig, das Mitglied des ausgewählten Teams ist; ein Servicekonto kann die Berechtigung eines Organisationsadministrators nicht übernehmen.
In Sendungen ist eine Etikettenrolle ein Manifestobjekt ({ kind: "reel", collectionId }) und wird vollständig versendet, jedoch nur, solange jedes Etikett darauf unverknüpft ist. Ein verknüpftes Etikett wird mit seinem Datensatz versendet und zieht niemals seine Etikettenrolle in die Sendung hinein. Versendete Etikettenrollen und Etiketten bleiben auf der Absenderseite lesbar, wobei transferredAt gesetzt ist; filtern Sie sie mit transferred=only oder transferred=hide.
Informationen zum DICE-Workflow finden Sie unter Etiketten und Etikettenrollen.
Verwandte Seiten
Abschnitt betitelt „Verwandte Seiten“- Fehler und Scanergebnisse – die kanonischen Ergebnistabellen für Identifizierung und Verifizierung sowie Informationen dazu, wie ein Scanbeleg bei einem Fehlschlag aufbewahrt wird
- Integration mit DUST Go – DUST-Scans auf Mobilgeräten aufnehmen
- React Scanner – eine direkt kopierbare Aufnahmekomponente
- Leitfaden zur Threads API – die Datensätze, mit denen Kennungen verknüpft werden
- API-Referenz – vollständige Schemas einschließlich Optionen für Aufnahmemetadaten