@certnode/verify
v2.0.0
Published
Verify-only SDK for CertNode AI Provenance receipts. No API key required — verification is public. Lightweight alternative to @certnode/sdk for browser extensions, audit tooling, and verification pipelines. Complete rewrite from v1.x (unrelated to previou
Maintainers
Readme
@certnode/verify
Verify-only SDK for CertNode AI Provenance receipts.
Verification is public — no API key required. This package is the lightweight alternative to @certnode/sdk for callers that only need to verify, not sign.
When to use this package
- Browser extensions verifying signatures on web pages (Chrome/Firefox/Safari/Edge)
- Audit tooling pulling receipts from logs without holding signing keys
- Verification pipelines on third-party content
- Server-side verify-before-serve gates where you can't ship a signing key
For signing, use @certnode/sdk which includes the full signing + verifying + searching surface.
Install
npm install @certnode/verifyQuickstart
import { CertNodeVerify } from '@certnode/verify'
const verifier = new CertNodeVerify()
// Mode 1: by receipt ID
const result = await verifier.verify({ receiptId: 'uuid-here' })
console.log(result.valid) // true / false
console.log(result.receipt?.signedAt) // ISO timestamp
console.log(result.receipt?.timestamps.bitcoin?.status) // 'anchored' / 'pending'
// Mode 2: by raw signature + content (no DB lookup)
const recheck = await verifier.verify({
signature: '...',
content: 'original content',
})
console.log(recheck.signatureValid)
console.log(recheck.contentMatches)API
new CertNodeVerify(options?)
interface CertNodeVerifyOptions {
baseUrl?: string // default: https://certnode.io/api/v1/provenance
timeoutMs?: number // default: 15000
}No API key needed — verification is public.
verifier.verify(input)
interface VerifyInput {
// Mode 1: by receipt ID
receiptId?: string
// Mode 2: by raw signature + content
signature?: string
content?: string
}Returns VerifyResult with valid, signatureValid, contentMatches, and the full receipt object when mode 1.
verifier.getReceipt(receiptId)
Convenience wrapper around verify({ receiptId }). Returns just the receipt object if valid; throws CertNodeVerifyError with code 'not_found' otherwise.
const receipt = await verifier.getReceipt('uuid-here')
console.log(receipt.signedAt)
console.log(receipt.model, receipt.provider)
console.log(receipt.timestamps.certnode.id)
console.log(receipt.timestamps.rfc3161) // base64 DER token (optional)
console.log(receipt.timestamps.bitcoin?.status) // 'anchored' / 'pending' / 'skipped'verifier.getTrustScore(receiptId)
Compute a developer-facing trust score (0-100) from a receipt's verification signals.
const trust = await verifier.getTrustScore('uuid-here')
console.log(trust.score) // 95
console.log(trust.signals.bitcoinAnchored) // true
console.log(trust.signals.ageHours) // 26.4Weighting: signature 40 + RFC 3161 anchored 20 + Bitcoin anchored 30 + age bonuses (5 at 1h, 5 at 24h).
Not a regulatory or legal metric — a developer-facing convenience number. For legal admissibility, cite the underlying receipt's three-layer chain directly.
What gets verified
When you call verify({ receiptId }), CertNode confirms:
- JWS signature is cryptographically intact — ES256 over the receipt payload, using CertNode's published EC P-256 public key.
- Content hash matches — if you pass
content, CertNode re-hashes it and compares to the signed hash. Mismatch means the content has been modified since signing. - Three-layer timestamp chain — receipt includes (a) CertNode signing timestamp, (b) RFC 3161 token from an independent Time Stamp Authority, (c) Bitcoin OpenTimestamps anchor status.
A fully-verified receipt is designed for FRE 902(13)/(14) self-authenticating digital evidence admissibility. The verification is reproducible — opposing counsel / regulators / auditors can run the same check independently.
Errors
import { CertNodeVerifyError } from '@certnode/verify'
try {
await verifier.verify({ receiptId })
} catch (err) {
if (err instanceof CertNodeVerifyError) {
console.log(err.code) // e.g. 'not_found'
console.log(err.status) // HTTP status
}
}Common error codes:
invalid_request— neither receiptId nor signature+content passedreceipt_not_found— no receipt with this IDreceiptId_required— empty receiptId togetReceipt()timeout— request exceeded timeoutMsnetwork_error— fetch failed
Links
- Homepage: https://certnode.io/ai-provenance
- Docs: https://certnode.io/docs/provenance
- Full SDK (sign + verify + search): https://www.npmjs.com/package/@certnode/sdk
- Public verify page: https://certnode.io/verify/[receiptId]
- Source: https://github.com/srbryant86/certnode/tree/main/packages/verify
- License: MIT
