Cookbook
Verify a certificate
Independently confirm a certificate is genuine, with no involvement from the platform and no need to trust the firm.
The fast path: use the verify page
For one-off checks, drop the certificate (PDF or JSON) onto verify.bedrockgovernance.com. The page does the cryptographic work in the browser and shows you the result.
The programmatic path
For continuous verification, say, a nightly job that checks every certificate your firm has issued, use the public verification endpoint or do the verification yourself.
Option A: public endpoint
The verify endpoint is unauthenticated, anyone with the certificate ID can confirm it. No X-Bedrock-Key required.
curl https://api.bedrockgovernance.com/v1/verify/cert_01HX5...Returns:
{
"valid": true,
"certificate": {
"id": "cert_01HX5...",
"firmName": "Apex Wealth Management",
"firmFrnNumber": "123456",
"issuedAt": "2026-04-07T17:59:42.000Z",
"metadata": {
"eventLabel": "Review approved",
"statusPill": { "label": "Approved", "palette": "success" },
"sections": [
{
"heading": "Document",
"fields": [
{ "label": "Reference", "value": "SR-2026-0142", "mono": true },
{ "label": "Type", "value": "Suitability report" }
]
},
{
"heading": "Reviewer",
"fields": [
{ "label": "Name", "value": "James Hargreaves" },
{ "label": "FCA reference", "value": "JHA00123", "mono": true }
]
}
]
}
},
"record": {
"documentHash": "...",
"previousHash": "...",
"recordHash": "...",
"chainHash": "...",
"signature": "...",
"publicKey": "..."
},
"verifiedAt": "2026-04-08T09:12:00.000Z"
}The certificate is a thin envelope. The cryptographic proof (hashes, signature, public key) lives on the linked ledger record and is returned alongside under record. Event-specific content lives in the certificate.metadata blob, its shape depends on the underlying event type.
Option B: verify it yourself with the Notary
If you do not want to trust the platform's verification endpoint, you can do the same cryptographic check locally with the open-source notary package. The platform itself imports from this package, so you are running the same code that ran when the certificate was issued.
npm install @bedrockgovernance/notaryimport { verifyCertificate } from '@bedrockgovernance/notary';
const response = await fetch(
`https://api.bedrockgovernance.com/v1/verify/${certificateId}`,
);
const { certificate, record } = await response.json();
const result = verifyCertificate({ certificate, record });
if (!result.valid) {
throw new Error(`Certificate invalid: ${result.reason}`);
}
}What "valid" means
- The signature was produced by the firm's signing key.
- The payload has not been altered since it was signed.
- The chain entry referenced still exists at the same position with the same content hash.
- No subsequent entry contradicts the certificate's claim.