Méthode GET/qr/verify

Vérifier un article à partir des paramètres signés portés par une adresse de vérification de l'ancienne forme. Point d'entrée public, sans clef d'API.

Sur cette page

Vous obtenez un verdict d'authenticité pour un article, à partir des paramètres signés d'une adresse de vérification, sans aucune clef d'API.

L'adresse complète est https://api.sealtrust.io/v1/qr/verify. La même route existe sans le préfixe /v1, et c'est la forme /v1 qui est recommandée pour une nouvelle intégration.

Ce point d'entrée répond 200 même quand le verdict est négatif. Un QR falsifié, un QR trop ancien, un article pas encore frappé : dans les trois cas la réponse est un 200 dont le champ valid vaut false. Les codes 4xx et 5xx sont réservés aux cas où aucun verdict ne peut être rendu.

#Autorisation

Aucune, point d'entrée public. Il n'attend ni clef d'API, ni cookie de session, ni en-tête Authorization.

Appelez-le depuis votre serveur. Notre politique de partage entre origines n'autorise que le site public et la console SealTrust. Depuis une page web hébergée sur un autre domaine, le navigateur bloque la réponse, et l'en-tête X-RateLimit-Remaining n'est de toute façon jamais exposé à un script de page.

Ce qui fait foi ici, c'est la valeur s. C'est la signature que nous avons apposée en produisant l'adresse de vérification. Sans elle, ou avec une valeur modifiée, le verdict est négatif.

#Plafond d'appels

30 appels par fenêtre de 60 secondes, comptés par adresse IP appelante. Le plafond est partagé par toutes les adresses qui commencent par /qr, et il s'applique aussi bien à /qr/verify qu'à /v1/qr/verify.

Les réponses portent les en-têtes X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset, ce dernier donnant l'heure de remise à zéro en secondes depuis le 1er janvier 1970. Un dépassement renvoie 429 avec en plus Retry-After, en secondes.

Ne faites pas dépendre votre code de la présence de ces en-têtes : lisez-les s'ils sont là, et continuez s'ils manquent.

Ce point d'entrée ne consomme aucun quota de votre offre.

#Paramètres de chemin et de requête

Ce point d'entrée n'a aucun paramètre de chemin.

NomTypeObligatoireDescription
ustringouiL'empreinte de l'article : 0x suivi de 64 caractères hexadécimaux. Les espaces de bord sont retirés, la casse n'a pas d'importance, et le préfixe 0x est ajouté s'il manque.
tsintegerouiL'horodatage inscrit dans l'adresse au moment de sa production, en secondes depuis le 1er janvier 1970.
sstringouiLa signature, telle qu'elle figure dans l'adresse.
tstringnonL'identifiant du jeton. Les adresses anciennes l'omettent. Le serveur retrouve de toute façon l'identifiant réel à partir de u, et c'est celui-là qu'il renvoie.
cstringnonLa référence courte du contrat portée par l'adresse. Ce point d'entrée l'accepte et ne la lit jamais. La présence ou l'absence de c ne change rien à la réponse.
srcstringnonPrésent dans les adresses de l'ancienne forme, avec la valeur qr. Ce point d'entrée ne le déclare pas et n'en tient aucun compte.
latitudenumbernonLatitude transmise par l'appareil qui scanne, entre -90 et 90. Arrondie à deux décimales, soit des cellules d'environ 1,1 km, avant tout enregistrement. La position fine n'existe à aucun moment chez nous.
longitudenumbernonLongitude transmise par l'appareil qui scanne, entre -180 et 180. Arrondie de la même façon.

latitude et longitude vont par paire. Si vous n'en envoyez qu'une seule, elle est écartée et le scan est enregistré sans coordonnées.

La réponse ne renvoie jamais de coordonnées : au mieux un libellé de zone. Quand vous n'envoyez pas de coordonnées, la ville et le pays de ce libellé sont déduits de l'adresse IP appelante, par une base de correspondance lue chez nous. Votre adresse IP n'est envoyée à aucun service extérieur. Si la position du scan compte pour vous, envoyez latitude et longitude. Sinon, sachez que la zone enregistrée sera celle de la machine qui appelle.

#Corps de la requête

Aucun. C'est une requête GET, tout passe par les paramètres de requête.

#Requête d'exemple

curl -i -G https://api.sealtrust.io/v1/qr/verify \
  --data-urlencode "u=0x0000000000000000000000000000000000000000000000000000000000000000" \
  --data-urlencode "t=1024" \
  --data-urlencode "ts=1755000000" \
  --data-urlencode "c=0x00000000" \
  --data-urlencode "s=0000000000000000000000000000000000000000000000000000000000000000"

#Réponse d'exemple

Code HTTP 200OK

Code HTTP 200, verdict positif.

JSON
{
  "valid": true,
  "message": "Authentic product: QR code and blockchain verified.",
  "uid_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "token_id": "1024",
  "product_name": "Sac de voyage Exemple SAS",
  "brand_name": "Exemple SAS",
  "image_url": null,
  "contract_address": "0x0000000000000000000000000000000000000000",
  "scan_area": "Lyon, FR"
}

Ici l'article n'a pas d'image de couverture, donc image_url vaut null. Quand il en a une, le champ porte son adresse publique. Le champ scan_area est renseigné parce que l'appel a pu être situé. Il vaut null sinon.

Code HTTP 200 également quand le verdict est négatif, et la réponse n'a pas la même forme selon le verdict.

Trois verdicts négatifs sont rendus avant toute lecture sur la chaîne : signature refusée, adresse trop ancienne, article pas encore frappé. Ces trois réponses ne portent que uid_hash.

JSON
{
  "valid": false,
  "message": "Invalid QR code signature. This QR code may be tampered with.",
  "uid_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "token_id": null,
  "product_name": null,
  "brand_name": null,
  "image_url": null,
  "contract_address": null,
  "scan_area": null
}

Le quatrième verdict négatif est rendu après la lecture sur la chaîne, quand l'empreinte lue ne correspond pas. Cette réponse décrit l'article, comme le verdict positif. Seul scan_area reste null, parce que la zone n'est calculée que sur un verdict positif.

JSON
{
  "valid": false,
  "message": "Invalid product: blockchain verification failed.",
  "uid_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "token_id": "1024",
  "product_name": "Sac de voyage Exemple SAS",
  "brand_name": "Exemple SAS",
  "image_url": null,
  "contract_address": "0x0000000000000000000000000000000000000000",
  "scan_area": null
}

Les neuf champs de la réponse.

ChampTypeDescription
validbooleanLe verdict. C'est le seul champ sur lequel construire votre logique.
messagestringUne phrase en anglais qui explique le verdict. Fondez vos décisions sur valid, jamais sur ce texte.
uid_hashstring ou nullL'empreinte de l'article, normalisée : minuscules, préfixe 0x. Renseignée dès que l'article a été trouvé, y compris sur un verdict négatif.
token_idstring ou nullL'identifiant du jeton, en base 10, sous forme de chaîne. C'est celui enregistré chez nous, qui peut différer du t que vous avez envoyé. Renseigné sur un verdict positif et sur le verdict Invalid product: blockchain verification failed.
product_namestring ou nullLe nom de l'article. Même règle de présence que token_id.
brand_namestring ou nullLe nom de la marque propriétaire. Renvoyé dans les mêmes cas que token_id, et null quand l'article n'est rattaché à aucune marque.
image_urlstring ou nullL'adresse publique de l'image de couverture. null quand l'article et son modèle n'en ont aucune.
contract_addressstring ou nullL'adresse du contrat qui porte ce jeton, en minuscules. Même règle de présence que token_id.
scan_areastring ou nullLa zone du scan. Ville, PP quand la ville et le code pays à deux lettres sont connus tous les deux, par exemple Lyon, FR. Quand une seule partie est connue, le champ ne porte que celle-là, Lyon ou FR. null quand aucune des deux n'est connue. Renseigné seulement sur un verdict positif. Jamais de coordonnées, jamais d'adresse postale.

#Les six verdicts possibles

validmessageCe que cela veut dire
trueAuthentic product: QR code and blockchain verified.La signature est reconnue et l'empreinte enregistrée sur la chaîne correspond.
falseInvalid product: blockchain verification failed.La signature est reconnue, mais l'empreinte lue sur la chaîne ne correspond pas.
falseInvalid QR code signature. This QR code may be tampered with.La signature ne correspond pas à celle que nous attendons pour cet article.
falseQR code has expired. Please request a new QR code.L'horodatage ts s'écarte de plus de 30 jours de l'heure courante, en avance comme en retard. Produisez une nouvelle adresse de vérification depuis votre console.
falseThis product has not been minted yet.L'article existe chez nous, sa frappe n'a jamais été envoyée. Rappeler plus tard ne changera rien.
falseMint submitted, waiting for on-chain confirmation.La frappe a été envoyée et attend sa confirmation. Rappelez dans quelques minutes.

#Erreurs

CodeConditionQue faire
404Aucun article vivant ne porte cette empreinte. Message Product not found for this QR code. L'article a été détruit, ou retiré du catalogue.Vérifiez la valeur de u. Si l'article a été détruit ou retiré du catalogue, ce code est définitif.
404La chaîne ne connaît pas ce jeton. Message Unknown product: this token_id does not exist.Rien à corriger côté appel. Contactez la marque : l'article est enregistré chez nous avec un identifiant de jeton que le contrat ne porte pas.
422Un paramètre obligatoire manque (u, ts ou s), ts n'est pas un entier, ou latitude et longitude sortent de leurs bornes.Le corps de la réponse liste les paramètres fautifs et le motif de chaque refus. Corrigez et rappelez.
429Plus de 30 appels en 60 secondes depuis la même adresse IP. Message Rate limit exceeded: 30 requests per 60s.Attendez le nombre de secondes indiqué par Retry-After. Répartissez vos appels au lieu de les envoyer en rafale.
500Erreur inattendue du serveur. Corps figé {"detail": "Internal Server Error"}.Réessayez. L'en-tête X-Request-Id identifie l'appel ; transmettez-le-nous s'il se répète.
503La lecture sur la chaîne a échoué. Message Error during blockchain verification.Réessayez dans quelques instants. Aucun verdict n'a été rendu, et le scan n'a pas été enregistré.

#Voir aussi

Votre réponse ouvre un courriel pré-rempli dans votre messagerie, à destination de contact@sealtrust.io. Vous le relisez avant de l'envoyer.

Proposer une correctionSignaler un problème