Verifying a Consent Evidence Certificate

A Consent Evidence certificate (cert_v: 1, or the record-only cert_v: 2) is built to be checked without trusting AdPriva, and without AdPriva existing. Everything a checker needs is inside the certificate, in the Legal Bundle export the controller keeps, in a public key registry, and on a public blockchain.

What a certificate proves: this consent wording, these checkbox states, were captured at this time and have not been altered since. It does not prove who the person was, or that consent was freely given; that stays with the controller.

What you need

  • the certificate: EV-….json, downloaded from the console or from GET https://api.adpriva.com/public/evidence/<evidence_id>;
  • the Legal Bundle export it names: LB-….json, downloaded from the console or from GET https://api.adpriva.com/public/legal-bundles/<LB-id>;
  • Node.js 20 or newer, and network access to the Horizen public RPC. AdPriva is never contacted.

Run the verifier

AdPriva’s reference verifier, adpriva-verify, is a small MIT-licensed Node.js tool with no dependencies. Its repository, AdPriva/consent-verifier, is in review before its public release; until then it is available to customers on request. The checks below are the complete procedure, so an independent implementation can follow them too.

adpriva-verify EV-….json --bundle LB-….json --claimed-at 2026-08-03T14:12:09.412Z

--claimed-at is the time the controller says the consent was given (for example, from its CRM). Add --json for a machine-readable report.

The seven checks

#CheckWhat is verified
1SchemaThe file is a cert_v: 1 or cert_v: 2 certificate: exact fields and formats, the interaction assessment allowed for its version, no duplicate keys.
2SignatureAn Ed25519 signature over the certificate’s canonical content, by a key listed in AdPriva’s published key registry (GET https://api.adpriva.com/public/consent-keys) and valid at the certificate time. Keys are never removed from the registry.
3LeafThe Merkle leaf is recomputed from the content. Change one byte and it no longer matches.
4Merkle pathThe path folds the leaf up to the batch’s Merkle root.
5AnchorOn the Horizen chain (chain id 26514), the transaction succeeded and emitted Anchored(root) from AdPriva’s published contract, sent by AdPriva’s published address, in the stated block at the stated time.
6BundleThe Legal Bundle export hashes to the bundle_hash the certificate binds. Its consent text decides whether the text shown on the page matched (MATCH) or not (TEXT_MISMATCH), and that must equal what the certificate says.
7TimingThe anchor came within the published window (60 minutes) after the event. With --claimed-at, the certification time must also be within 10 minutes of the claimed consent time. A certificate made later for an older consent is flagged as a possible re-certification.

Each check reports PASS, FAIL, FLAG (worth a human look, for example a truthful TEXT_MISMATCH or a late anchor), SKIP or ERROR. The verdict is PASS, FLAGGED, INCOMPLETE (anchor still pending or no bundle supplied) or FAIL.

Record-only certificates (cert_v: 2)

A cert_v: 2 certificate records a consent form submitted without consent through the site’s consent banner, on a form the controller opted in. No interaction signals were collected, so its interaction assessment is always NOT_AVAILABLE: it says nothing about whether a person or a bot submitted the form. Every other field and all seven checks are the same as for cert_v: 1.

Use verifier v0.2.0 or newer. An older verifier refuses a cert_v: 2 certificate at step 1 with “cert_v must be 1”, rather than misreading it.

The exact rules

Canonicalization (how text and JSON are normalized before hashing) is specified in the canonicalization annex that ships with the verifier, and pinned by a fixture suite that the JavaScript, Go and Python implementations and three browser engines all pass.

The registry also lists the anchor contract (0x7b6a7eb310d30c338c9ecb575f439c1a93fcb217 on Horizen, chain id 26514) and the one address allowed to anchor (0xc0bd23fbde06d43ff699aa23cbf69f1b3de18663), so step 5 can be checked against any Horizen RPC or block explorer.

Known limits

  • A certificate attests what the AdPriva tag observed in the page. A site that deliberately feeds the tag a doctored page is outside what any client-side witness can rule out (spec T8).
  • A consent event fabricated on day one is still a consent event to the tag. The interaction assessment raises the bar, but the claim is strictly “unaltered since T” (spec T7). A record-only cert_v: 2 certificate has no interaction assessment at all.
  • Anchoring currently uses a single chain (Horizen). A second, independent anchor is planned.