The GET /api/v1/verify endpoint recomputes the SHA-256 hash for every event in your workspace and checks that each event’s previous_event_hash matches the hash of the preceding event. If any field has been modified or any event has been inserted or deleted, the verification will report the exact break.
The stored hash does not match the recomputed hash. This means the event data was modified after ingestion. The expected_hash is what the hash should be based on the current field values, and actual_hash is what was stored at ingestion time.
The previous_event_hash on an event does not match the hash of the preceding event. This means an event was inserted into or deleted from the chain. The expected_hash is the hash of the preceding event, and actual_hash is the previous_event_hash stored on the broken event.
Run the verify endpoint on a schedule and alert your team if the chain is broken. This is the recommended approach for production workspaces.
// cron-verify.ts — run daily via cron or your schedulerimport { ImmutableClient } from "getimmutable";async function verifyAuditLogIntegrity() { const client = new ImmutableClient({ apiKey: process.env.IMMUTABLE_API_KEY!, baseUrl: "https://getimmutable.dev", }); // Verify the last 24 hours const now = new Date(); const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000); const result = await client.verify( yesterday.toISOString(), now.toISOString() ); if (!result.data.valid) { await fetch(process.env.SLACK_WEBHOOK_URL!, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: `:rotating_light: Audit log chain integrity violation detected!\n${result.data.breaks.length} break(s) found. Check immediately.`, }), }); } console.log( `[${now.toISOString()}] Verified ${result.data.events_checked} events. Valid: ${result.data.valid}` );}verifyAuditLogIntegrity();
For maximum coverage, run verification on the last 24 hours daily, and verify the full chain weekly or monthly. The limit parameter can be increased for full-chain verification.
Legacy events ingested before hash chain activation have nullable hash fields. These events are skipped during verification and do not produce breaks.