Skip to main content

Quickstart

Get up and running with Trailproof in 5 minutes. You’ll install the library, emit events, query them, and verify the chain is intact.

Installation

Python
pip install trailproof
# or
uv add trailproof
TypeScript / Node.js
npm install @kyberonai/trailproof

1. Create a Trailproof Instance

By default, Trailproof uses an in-memory store — perfect for getting started.
from trailproof import Trailproof

tp = Trailproof()

2. Emit Events

Every event needs an event_type, actor_id, tenant_id, and payload. Trailproof auto-generates event_id, timestamp, and the hash chain fields.
event = tp.emit(
    event_type="myapp.user.login",
    actor_id="user-42",
    tenant_id="acme-corp",
    payload={"ip": "1.2.3.4", "method": "oauth"},
)

print(event.event_id)    # UUID v4
print(event.hash)        # SHA-256 hash
print(event.prev_hash)   # "0" * 64 (genesis)
The first event in the chain uses a genesis hash of 64 zeros as its prev_hash. Every subsequent event links to the hash of the previous event.

3. Query Events

Filter events by type, actor, tenant, time range, or any combination. Results are paginated with cursor-based navigation.
result = tp.query(actor_id="user-42", limit=50)

for event in result.events:
    print(f"{event.event_type} at {event.timestamp}")

# Paginate
if result.next_cursor:
    next_page = tp.query(actor_id="user-42", cursor=result.next_cursor)

4. Verify Chain Integrity

Walk the entire hash chain to confirm no events have been tampered with.
verification = tp.verify()

print(verification.intact)  # True
print(verification.total)   # number of events
print(verification.broken)  # [] (empty = no tampering)
If a tampered event is detected, broken contains the indices of all affected events. Because each event depends on the previous hash, tampering event N causes events N through the end to appear broken.

5. Persist to Disk

Switch to the JSONL file store for events that survive restarts.
tp = Trailproof(store="jsonl", path="events.jsonl")

# Events are appended to the file as JSON lines
event = tp.emit(
    event_type="myapp.user.login",
    actor_id="user-42",
    tenant_id="acme-corp",
    payload={"ip": "1.2.3.4"},
)

# Ensure all data is flushed to disk
tp.flush()
The JSONL file is human-readable. Inspect it with cat events.jsonl | jq . or grep "user-42" events.jsonl.

Next Steps

Event Envelope

Learn about the 10-field event structure.

HMAC Signing

Add cryptographic provenance to your events.

JSONL Store

Configure persistent file-based storage.

Verification

Deep dive into chain integrity verification.