SealTrustSealTrustSealTrust
Accueil
Comment ça marcheVérifierDemo
Se connecterS'inscrire
SealTrust
AccueilComment ça marcheVérifierDemo

Produit

Passeport Numérique de ProduitFonctionnalitésOffresSolutionsRadar réglementaireCas d'usageIntégrations

Entreprise

À proposCarrièresPresseContact

Ressources

BlogDocumentationAPI DocsDéveloppeursSécuritéCentre de confianceToutes les ressources
ConnexionCréer un compte

© 2026 SealTrust

SealTrust

Authentification produit par NFC et blockchain. Protégez votre marque contre la contrefaçon.

Produit

  • Comment ça marche
  • Fonctionnalités
  • Tarifs
  • Solutions
  • Radar réglementaire
  • Cas d'usage
  • Intégrations
  • Documentation

Entreprise

  • À propos
  • Contact
  • Carrières
  • Presse

Légal

  • CGU
  • CGV
  • Politique de confidentialité
  • Mentions légales
  • RGPD
  • Politique cookies
  • Retour et garantie

Ressources

  • Toutes les ressources
  • Documentation technique
  • Blog
  • Passeport Numérique de Produit
  • Guide DPP 2027
  • Développeurs
  • Badge de vérification
  • Sécurité
  • Centre de confiance
  • API Docs
  • Aide
  • Support

EN 18219 · EN 18220 · ESPR-ready · RGPD

© 2026 SealTrust. Tous droits réservés.

Suivez-nous sur LinkedInFait avec confiance en France

Développeurs

L'API de la preuve produit

Certificats, passeports et preuves on-chain sont servis par des endpoints REST simples, publics pour la plupart, parce qu'une preuve que vous ne pouvez pas vérifier vous-même n'est pas une preuve. Clés à portée limitée, webhooks signés et SDK typé couvrent le reste.

https://api.sealtrust.io

Commencez par un curl

La surface de vérification n'exige ni compte ni clé API. Récupérez un certificat, un passeport ou la preuve Merkle d'un produit et contrôlez notre ancrage vous-même sur Base L2 (basescan.org). La preuve est publique et vérifiable en toute indépendance.

curl
# Public endpoints — no API key required
curl https://api.sealtrust.io/certificate/{identifier}

# The passport as JSON-LD (Schema.org / GS1 vocabulary)
curl "https://api.sealtrust.io/passport/{identifier}?format=jsonld"

# The public Merkle proof — verify our anchoring yourself on Base L2
curl https://api.sealtrust.io/verify/merkle/{identifier}

Endpoints publics

Tout ce qui suit est en production, sans authentification (limites de débit applicables). L'identifiant peut être le numéro de série imprimé, un uid_hash (0x + 64 hex) ou un token_id ; /certificate, /resolve et /verify/merkle acceptent en plus un numéro de certificat.

EndpointCe qu'il fait
GET/sdm/verify-urlVérifie un scan NTAG 424 DNA (SDM) : déchiffre et valide le code à usage unique de la puce.
GET/certificate/{identifier}Certificat d'authenticité public (par numéro de série imprimé, uid_hash, token_id ou numéro de certificat).
GET/certificate/{identifier}/downloadLe même certificat au format PDF.
GET/passport/{identifier}Passeport Numérique de Produit, filtré par le profil d'accès demandé. Ajoutez ?format=jsonld pour du JSON-LD (Schema.org/GS1).
GET/passport/{identifier}/vcLe passeport sous forme de credential vérifiable SD-JWT-VC, filtré par niveau d'accès.
GET/passport/{identifier}/vc/verifyVérifie le SD-JWT-VC stocké contre la clé de signature de la marque.
GET/brand/{brand_id}/did.jsonDID Document de la marque (did:web) : clés publiques de signature en JsonWebKey2020.
GET/p/{serial}L'identifiant unique de produit (EN 18219). C'est ce que porte le QR imprimé sur un produit, et le seul identifiant qu'une personne peut lire sur un objet. Redirige vers la page produit ; ajoutez ?linkType=dpp pour le passeport lui-même.
GET/01/{gtin}/21/{serial}Résolveur GS1 Digital Link : la même unité que /p/{serial}, sous la forme porteuse GS1.
GET/resolve/{identifier}Résolveur universel : produit + certificat + passeport + événements de cycle de vie + médias en une réponse.
GET/passport/{identifier}/proofFaisceau de preuves du passeport : hash SHA-256 des données, copie IPFS, ancrage Base L2 et statut SD-JWT-VC.
GET/timeline/{identifier}Historique combiné : vérifications et transferts de propriété. Limité à 30 requêtes par 60 secondes et par IP.
GET/verify/merkle/{identifier}Preuve publique d'ancrage Merkle d'un produit, recalculable par vous-même contre Base L2.
GET/qr/product/{identifier}QR code (PNG) pointant vers la page de vérification du produit.

API partenaire : clés & scopes

Les opérations d'écriture utilisent des clés API (préfixe st_live_) envoyées en Authorization: Bearer. Le secret complet n'est affiché qu'une seule fois à la création ; seul son hachage SHA-256 est stocké. Chaque clé est rattachée à une marque, soumise à un quota quotidien et à une limite de débit, et porte des scopes explicites :

mint:batchFrappe par lot via /partner/mint/batch
sellout:writeDéclarer une sortie de stock via /partner/sellout
webhooks:readLire vos abonnements aux webhooks
webhooks:writeCréer, modifier et supprimer un abonnement aux webhooks
mint:singleAccordable, mais aucun point d'entrée ne l'exige encore
products:readAccordable, mais aucun point d'entrée ne l'exige encore
products:statusAccordable, mais aucun point d'entrée ne l'exige encore
transfers:createAccordable, mais aucun point d'entrée ne l'exige encore

Mint en masse par l'API

POST /partner/mint/batch accepte du JSON (une liste d'objets) ou un fichier CSV, applique l'isolation par marque et les quotas, gère un en-tête Idempotency-Key pour des relances sûres, et renvoie un job interrogeable.

POST /partner/mint/batch
curl -X POST https://api.sealtrust.io/partner/mint/batch \
  -H "Authorization: Bearer st_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-2027-0042" \
  -d '[
    {
      "product_name": "Sneaker #001",
      "brand_id": 1,
      "category_id": 3,
      "metadata_uri": "https://metadata.sealtrust.io/001.json"
    }
  ]'

# → { "job_id": "abc123...", "status": "queued", "items_count": 1, "brand_id": 1 }
# Poll: GET /partner/mint/batch/status/{job_id}  (max 500 items per batch)

Des webhooks signés

Abonnez une URL par marque et recevez les événements en POST JSON. L'abonnement accepte aussi six noms d'événements que nous n'envoyons pas aujourd'hui ; vous abonner à l'un d'eux ne renvoie aucune erreur et ne produit aucune livraison. Chaque livraison est signée avec votre secret de webhook : l'en-tête X-Webhook-Signature porte t=<horodatage Unix>,v1=<hexadécimal>, où v1 est le HMAC-SHA256 de "{horodatage}.{corps brut}" calculé sur les octets exacts que nous envoyons. Vérifiez sur le corps brut, jamais sur une copie re-sérialisée, et contrôlez l'horodatage avec une tolérance que vous choisissez. Chaque livraison porte aussi X-Webhook-Timestamp et X-Webhook-Id, le SHA-256 du corps, identique à chaque nouvelle tentative d'un même événement pour vous permettre de dédupliquer :

verify_webhook.py
import hashlib
import hmac
import time

def verify_webhook(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
    """Verify X-Webhook-Signature: t=<unix_seconds>,v1=<hmac_sha256_hex>."""
    parts = {}
    for item in header.split(","):
        key, _, value = item.strip().partition("=")
        if value:
            parts[key] = value

    ts, sig = parts.get("t"), parts.get("v1")
    if not ts or not sig or not ts.isdigit():
        return False
    if abs(time.time() - int(ts)) > tolerance:   # tolerance is yours to choose
        return False

    signed = ts.encode() + b"." + raw_body       # the signed message, not the body alone
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

# FastAPI example
# raw = await request.body()   # the exact bytes, never a re-serialised dict
# sig = request.headers["X-Webhook-Signature"]
# assert verify_webhook(raw, sig, WEBHOOK_SECRET)

Les événements que nous envoyons

product.mintedUn produit est enregistré depuis la console, un par un. Une frappe en lot par l'API partenaire ne l'envoie pas : interrogez plutôt le statut du job.
product.transferredUn transfert de propriété effectué par nos soins aboutit sur la chaîne. Un transfert que le détenteur signe depuis son propre portefeuille ne l'envoie pas.
transfer.acceptedLe destinataire d'un transfert sous séquestre l'accepte.
product.scannedUn scan aboutit sur un de vos produits.
product.gray_marketUn scan a lieu hors de la zone que vous avez autorisée.
clone.alertNous détectons une duplication sur un identifiant de puce.
return.requestedUn retour est demandé.
return.receivedLe produit retourné vous est parvenu.
return.completedLe retour est soldé.
return.rejectedLe retour est refusé.
return.expiredLa demande de retour a expiré sans suite.
warranty.claimedUne garantie est actionnée.
buyback.offeredVous proposez de racheter un produit.
buyback.acceptedLe détenteur accepte la proposition.
buyback.declinedLe détenteur refuse la proposition.
buyback.completedLe rachat est soldé.
buyback.expiredLa proposition a expiré sans réponse.

SDK TypeScript

@sealtrust-io/sdk est un client typé, en fetch natif et sans dépendance (Node.js ≥ 18). Les requêtes POST et PUT portent automatiquement un en-tête Idempotency-Key ; vous pouvez fournir le vôtre pour des relances sûres.

@sealtrust-io/sdk
import { SealTrustClient } from "@sealtrust-io/sdk";

const sealtrust = new SealTrustClient({
  apiKey: "st_live_...",
  baseUrl: "https://api.sealtrust.io", // optional, this is the default
});

// Read a product's history. The printed serial is the identifier you actually
// have: it is what the QR code on the product carries, and the only one a
// human can read off an object. A token id or a 0x uid hash work too.
const history = await sealtrust.verify.timeline("2MH5NK5F37AE");
console.log(history.product_name);
console.log(history.timeline.length); // verifications + ownership transfers

// Mint a batch, then poll the job
const job = await sealtrust.products.mint([
  { product_name: "Sneaker #001", brand_id: 1, category_id: 3, metadata_uri: "https://metadata.sealtrust.io/001.json" },
]);
const status = await sealtrust.products.getBatchStatus(job.job_id);
console.log(status.status); // "queued" | "started" | "finished" | "failed"

// Subscribe to webhooks
await sealtrust.webhooks.create({
  url: "https://example.com/webhooks/sealtrust",
  events: ["product.minted", "product.transferred"],
  secret: "whsec_...",
});

GS1 Digital Link

Chaque identité produit est adressable via la syntaxe GS1 Digital Link vers laquelle converge l'écosystème ESPR : /01/{gtin}/21/{serial} résout un GTIN + numéro de série vers la page produit de l'article, et vers son Passeport Numérique de Produit sous ?linkType=dpp. Le même support fonctionne pour les distributeurs, les douanes et les recycleurs, sans intégration sur mesure.

GS1 Digital Link
# One GS1 Digital Link per item: GTIN + serial resolves to the product page
curl https://api.sealtrust.io/01/{gtin}/21/{serial}

# Add ?linkType=dpp to land on the passport itself
curl "https://api.sealtrust.io/01/{gtin}/21/{serial}?linkType=dpp"

# The same identity also resolves certificates and events
curl https://api.sealtrust.io/resolve/{identifier}

Vos produits, lisibles par les agents IA

@sealtrust-io/mcp-server expose la surface publique de vérification sous forme de serveur Model Context Protocol (MCP) : sept outils en lecture seule que tout client MCP (Claude Desktop, Claude Code et les autres) peut appeler pour vérifier un produit, lire son Passeport Numérique de Produit et contrôler les preuves qui le soutiennent. Il tourne en local sur stdio, n'exige ni compte ni clé API, et n'atteint que des endpoints publics en lecture seule, sans authentification.

Claude Desktop : claude_desktop_config.json
{
  "mcpServers": {
    "sealtrust": {
      "command": "npx",
      "args": ["-y", "@sealtrust-io/mcp-server"]
    }
  }
}
claude mcp add
# Claude Code
claude mcp add sealtrust -- npx -y @sealtrust-io/mcp-server

# Optional: point it at another environment (default: https://api.sealtrust.io)
claude mcp add sealtrust --env SEALTRUST_API_URL=https://api.sealtrust.io -- npx -y @sealtrust-io/mcp-server

Les sept outils

verify_productStatut d'authenticité d'un produit (authentique, révoqué, expiré, trouvé sans certificat actif, ou inconnu) avec les infos produit publiques.
get_passportLe Passeport Numérique de Produit publié, niveau public uniquement (JSON ou JSON-LD).
get_passport_proofFaisceau de preuves : hash SHA-256 des données, copie IPFS, ancrage Base L2, statut SD-JWT-VC, nombre de vérifications physiques.
get_certificateLe certificat d'authenticité public (statut, dates, émetteur).
resolve_gs1Résout un GS1 Digital Link vers un passeport : celui de l'article avec un numéro de série, celui du modèle sans.
verify_credentialVérifie le SD-JWT-VC du passeport contre la clé de signature did:web de la marque.
get_product_historyLa chronologie de l'article : vérifications et transferts de propriété, du plus ancien au plus récent.

Lecture seule par construction : le serveur ne peut que consulter des données publiques. Rien de ce qu'il fait ne peut minter, transférer ou modifier un produit.

Aller plus loin

Référence API complèteGuides d'intégration & documentation

Une question sur votre intégration ? Parlons-en avec notre équipe.

Parlez-nous→