Documentation Index
Fetch the complete documentation index at: https://docs.getimmutable.dev/llms.txt
Use this file to discover all available pages before exploring further.
How It Works
Every event in Immutable is linked to the previous event in a per-workspace SHA-256 hash chain. This creates a tamper-evident seal across your entire audit trail — if any event is modified, inserted, or deleted at the database level, the chain breaks and the tampering is detectable.previous_event_hash set to null.
Hash Computation
Each event hash is a SHA-256 digest computed from all event fields:| Field Group | Fields |
|---|---|
| Identity | workspace_id |
| Actor | actor_id, actor_name, actor_type |
| Action | action, action_category |
| Resource | resource_id, resource_name, resource |
| Context | metadata, targets, occurred_at |
| Network | ip_address, ip_country, ip_city, user_agent |
| Tracking | tenant_id, session_id, idempotency_key, version |
| Chain | previous_event_hash |
Metadata keys are recursively sorted and targets are sorted by
type then id before hashing. This ensures deterministic hashes regardless of JSON key order or array ordering in the database.Chain Ordering
Events are chained bycreated_at (server-side timestamp with microsecond precision), not occurred_at (client-provided time). This guarantees a consistent, linear chain even when clients report out-of-order timestamps.
Concurrency Safety
Immutable uses PostgreSQL advisory locks (pg_advisory_xact_lock scoped by workspace ID via crc32) to ensure concurrent event ingestion does not produce conflicting hash chains. Only one event per workspace is hashed at a time.
Integrity Block
Every event returned by the API includes anintegrity block:
Verifying the Chain
Use the verify endpoint to validate the entire chain or a date range:Break Types
If tampering is detected, thebreaks array describes each issue:
| Type | Description |
|---|---|
hash_mismatch | The stored hash does not match the recomputed hash. The event data was modified. |
chain_break | The previous_event_hash does not match the prior event’s hash. An event was inserted or deleted. |
Batch Event Ordering
When events are ingested via the batch endpoint, each event’screated_at is offset by 1 microsecond to preserve insertion order. Without this offset, batch events would share the same created_at value and UUID-based ordering would not match insertion order, causing false chain_break errors during verification.