Skip to main contentCertyo Developer Portal

Verification

Cryptographically prove that a record existed at a point in time and has not been tampered with. Certyo provides three verification modes depending on what you have on hand.

The three modes

1. Verify by record (most common)

You have the original payload and record identifier. Use this when you want to check a record you just read from your own database.

POST /api/v1/verify/record
Requestjson
{
  "tenantId": "acme-corp",
  "database": "production",
  "collection": "orders",
  "recordId": "order-12345",
  "payload": { "amount": 299.99, "currency": "USD" }
}

2. Verify by payload hash

You have a hash (computed by you or previously returned by Certyo) and want to confirm it was anchored. Use this when you don't have the payload but want to prove a hash exists on-chain.

POST /api/v1/verify/payload

3. Verify by snapshot ID

You have the internal snapshot ID (returned by the ingestion response or query endpoints) and want to verify its on-chain status.

GET /api/v1/verify/snapshot/{snapshotId}

What a successful verification proves

A response with verified: true and verificationStatus: "pass" mathematically proves three things:

  1. Integrity — the hash you recomputed matches the hash stored at ingestion time. The payload hasn't been modified.
  2. Inclusion — the Merkle proof path connects your record's hash to the batch Merkle root. The record was part of the batch at the time of anchoring.
  3. Anchoring — the batch Merkle root is committed on the Polygon blockchain, with a specific timestamp and block number.

Together, these three checks mean the record existed at or before the block timestamp, and has not been tampered with. The proof can be independently verified — you don't have to trust Certyo.

Verification response

Successful verificationjson
{
  "verified": true,
  "verificationStatus": "pass",
  "reasonCategory": "verified_anchored",
  "snapshotHash": "5f3c7d2e...",
  "computedPayloadHash": "5f3c7d2e...",
  "merkleRoot": "0x7e2d9a1b...",
  "merkleProof": [
    "0xa1b2c3d4...",
    "0x2c3d4e5f..."
  ],
  "anchoredOnChain": true,
  "chainId": 137,
  "contractAddress": "0xeeCD2FAD7841E113BCeEB39c704c78B91E35D6f2",
  "onChainMerkleRoot": "0x7e2d9a1b...",
  "anchorTimestamp": "2026-04-12T15:32:30Z",
  "onChainProof": {
    "polygonScanEventUrl": "https://polygonscan.com/tx/0x9a8f7e6d...",
    "polygonScanContractUrl": "https://polygonscan.com/address/0xeeCD2FAD...",
    "howToVerify": "1. Go to PolygonScan contract page. 2. Find getBatch() function. ..."
  },
  "ipfsEvidence": {
    "ipfsCid": "QmAbc123XyZ789...",
    "ipfsGatewayUrl": "https://gateway.pinata.cloud/ipfs/QmAbc123XyZ789.../manifest.json"
  }
}

Failure modes

verified: false can mean different things. The reasonCategory field tells you which:

  • hash_mismatch — the payload you sent hashes to a different value than what was ingested. The record was modified or you sent the wrong payload.
  • record_not_found — Certyo has no record matching that tenantId + database + collection + recordId. Either it was never ingested or you're querying the wrong identifiers.
  • pending_anchor — the record is in the pipeline but hasn't been anchored to Polygon yet. Retry in 30–60 seconds.
  • anchor_failed — the batch failed to anchor (blockchain transaction error). Certyo will retry automatically; check the GET /api/v1/snapshots/{id}/lifecycle endpoint for details.

Independent verification

You don't have to trust Certyo's verification response. Using the data in onChainProof and ipfsEvidence, you can verify independently:

  1. Fetch the batch Merkle root from the Polygon smart contract using the polygonScanContractUrl.
  2. Fetch the IPFS manifest at ipfsGatewayUrl. It contains all record hashes and the Merkle tree structure.
  3. Recompute the Merkle root from the manifest and compare it to the on-chain root — they must match.
  4. Recompute your record's hash and walk the Merkle proof — it must reach the same root.

This is the entire point of Certyo. Your audit trail is independently verifiable, even if Certyo shuts down.