Skip to main content
CanaryVaultsCanaryVaults home
ProductsPricingBlogDocs
Start Free

GET STARTED

OverviewQuickstart

SURFACES

CanaryVaultsCanaryRAGCanaryShieldCanaryHoneypotCanaryAuditCanaryAgent

REFERENCE

API referenceAlerts & webhooksEnterprise & teams

Surface 05 · CanaryAudit

Verify an audit record

Every logged action is sealed with a SHA-256 content hash at write time. Verification recomputes the hash from the stored payload and compares. There are two ways to run that check and they are not interchangeable. POST /canaryaudit/verify/{log_id} is the owner path: it requires authentication and ownership of the record, and anybody else gets a 401 or a 403 and no verification data. The public path is GET /api/verify/{content_hash} — no auth, 30 requests per minute per IP, and it takes the content hash, not the record id.

bash
curl -X POST https://api.canaryvaults.com/canaryaudit/log \
  -H "X-API-Key: $CV_KEY" -H "Content-Type: application/json" \
  -d '{
    "user_id": "<your-user-uuid>",
    "agent_id": "billing-agent",
    "action_type": "invoice_export",
    "input_trigger": "cron:invoice-run",
    "action_detail": "Exported invoice batch 2026-08 to S3",
    "outcome": "success"
  }'
# → record id + content hash, returned for independent verification
bash
curl -X POST https://api.canaryvaults.com/canaryaudit/verify/<log-id> \
  -H "X-API-Key: $CV_KEY"

# → { "verified": true, "tampered": false, "match": true,
#     "stored_hash": "…", "recomputed_hash": "…", "sealed": true, … }
bash
# the public check — no auth, no key, takes the 64-char content hash
curl https://api.canaryvaults.com/api/verify/<content-hash>

# → { found, verified, tampered, hash, recordType, sealedAt,
#     sealed, anchored, note, basescanUrl }  — no user ids, no payload

So the thing you hand a customer or an auditor is the 64-character content_hash returned by POST /canaryaudit/log, never the record id. The same check has a web page at https://www.canaryvaults.com/verify, which accepts a 64-character hex hash and nothing else — paste a UUID record id and it answers "unrecognized format" without ever reaching the backend.

A record edited after sealing returns "tampered": true with both hashes so you can see the mismatch. The hash covers user_id|agent_id|action_type|input_trigger|action_detail|outcome|logged_at — metadata is deliberately outside it, so editing metadata does not break verification. The extra HMAC seal is opt-in on a server-side key, which is why an untampered record can legitimately report "sealed": false. Exports are JSON on every plan and legal PDF on Pro — tamper-evident, not court-admissible.

Next

Connect an agent →Evidence & verification →
CanaryVaults

Deception-based AI security. Decoys, trap facts, honeypots, prompt defense, and tamper-evident audit trails — one workspace.

Plant your first canary

PRODUCT

ProductsCanaryAgentDashboardPricingReferralGet started

RESOURCES

DocumentationQuickstartShieldEvidence formatAPIBlog

COMPANY

AboutSecurityReport a vulnerabilityContact

TRUST

Trust centerVerify evidenceStatusChangelogIncidentsDPA

COMPARE

vs Thinkst Canaryvs CanaryTokensFor SaaS teams

LEGAL

TermsPrivacyCookiesSubprocessorsSupport
deception-based AI security© CanaryVaults · canaryvaults.comsha-256 sealed · tamper-evident

CANARYVAULTS