Method GET/passport/01/{gtin}/10/{lot}/proof

Fetch the public proofs of a batch's passport: content hash, seal, anchoring of the document on Base without any minting, state of the signed credential. Public endpoint.

On this page

You fetch the public proofs of a production batch's passport. When you leave this page, you will know how to request these proofs, how to check by yourself that the batch's version is written on chain, and why no minting was needed.

Full address:

HTTP
GET https://api.sealtrust.io/v1/passport/01/{gtin}/10/{lot}/proof

#Authorization

None, public endpoint. The response is the same for everyone.

#Rate limit

600 calls per window of 60 seconds, counted per calling IP address, shared by every read (GET) whose address starts with /passport.

#Path and query parameters

NameTypeRequiredDescription
gtinstringyesThe GTIN of the batch's model. Its check digit is verified.
lotstringyesThe lot number, compared exactly, case included.

This endpoint has no query parameter.

#Request body

None. This request has no body.

#Example request

curl -i "https://api.sealtrust.io/v1/passport/01/03701234567891/10/LOT-26A/proof"

#Example response

HTTP code 200, for a version already anchored.

JSON
{
  "passport_version": 2,
  "data_hash": "9f2c1e7d4b8a6f0e3d5c2b1a9e8f7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e",
  "passport_anchor": {
    "type": "passport_anchor",
    "chain": "base",
    "chain_id": 8453,
    "tx_hash": "0x5e1f0c2d3b4a59687766554433221100ffeeddccbbaa99887766554433221100",
    "merkle_root": "0x0d1c2b3a49586776655443322110ffeeddccbbaa998877665544332211000f1e",
    "leaf": "0x7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b",
    "leaf_index": 3,
    "proof": ["0x1122334455667788990011223344556677889900112233445566778899001122"],
    "block_timestamp": "2026-09-26T09:00:02+00:00",
    "passport_version": 2,
    "data_hash_matches": true,
    "anchored": true,
    "proves": "content_existed_at_or_before_tx"
  },
  "seal": {"sealed": true, "linked": true, "chain_link_match": true},
  "vc": {"issued": false},
  "level": "batch",
  "gtin": "03701234567891",
  "batch_code": "LOT-26A"
}

Every value in this example is fictitious, and the real response carries other fields in passport_anchor and seal, described on GET /passport/01/{gtin}/proof.

Two blocks are absent, and their absence is the right answer: anchor, which dates an item, and verifications, which counts the reads of a physical label. A batch is neither. As long as the version has not been taken by the sweep, passport_anchor is absent too, and seal is enough to make any rewrite visible in the meantime.

#Verifying the proof yourself

The leaf is keccak256(abi.encode(uint256 passportId, uint256 passportVersion, bytes32 dataHash)), where passportId is the id field of GET /passport/01/{gtin}/10/{lot}. Walking up from the leaf with each node of proof, two by two and in ascending byte order, you get back merkle_root. The detail is on Trust and proofs.

#Errors

CodeConditionWhat to do
400The GTIN check digit does not match.Copy the GTIN again from the barcode.
404No published passport for this batch, a batch of another brand than the one of the called domain, or a batch of another brand than the one that publishes the model passport of this GTIN.Check the lot number, case included, and the publication in the console.
429More than 600 calls in 60 seconds from the same IP address.Wait the number of seconds given by Retry-After.

#See also

Your answer opens a pre-filled email in your mail app, addressed to contact@sealtrust.io. You read it over before sending it.

Suggest a correctionReport a problem