> ## Documentation Index
> Fetch the complete documentation index at: https://trailproof.kyberon.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Envelope

> The 10-field TrailEvent structure that wraps every audit event

# Event Envelope

Every event in Trailproof uses the same 10-field envelope. Your domain-specific data goes in `payload` -- Trailproof handles the rest.

<Note>
  Trailproof doesn't validate or inspect payload contents. It stores them opaquely. Your application is responsible for payload structure.
</Note>

## TrailEvent Fields

| Field        | Type   | Required | Description                                  |
| ------------ | ------ | -------- | -------------------------------------------- |
| `event_id`   | string | yes      | UUID v4, auto-generated by Trailproof        |
| `event_type` | string | yes      | Namespaced type (e.g., `myapp.user.login`)   |
| `timestamp`  | string | yes      | ISO-8601 UTC, auto-generated by Trailproof   |
| `actor_id`   | string | yes      | Who performed the action                     |
| `tenant_id`  | string | yes      | Tenant/org isolation key                     |
| `trace_id`   | string | no       | Cross-system correlation ID                  |
| `session_id` | string | no       | Session grouping ID                          |
| `payload`    | object | yes      | Domain-specific data (opaque to Trailproof)  |
| `prev_hash`  | string | yes      | Hash of the previous event                   |
| `hash`       | string | yes      | SHA-256 hash of this event                   |
| `signature`  | string | no       | HMAC-SHA256 signature (if signer configured) |

## Auto-Generated vs. Caller-Provided

**You provide** (required):

* `event_type` -- what happened
* `actor_id` -- who did it
* `tenant_id` -- which tenant (use `"default"` for single-tenant)
* `payload` -- domain-specific data

**You can optionally provide:**

* `trace_id` -- correlate events across systems
* `session_id` -- group events within a session

**Trailproof auto-generates:**

* `event_id` -- UUID v4
* `timestamp` -- ISO-8601 UTC
* `prev_hash` -- from the hash chain
* `hash` -- SHA-256 of the event
* `signature` -- if a signing key is configured

## Event Type Convention

Event types follow a namespaced pattern: `{project}.{domain}.{action}`

```
myapp.user.login
myapp.user.logout
memproof.memory.write
memproof.memory.redact
attesta.approval.requested
attesta.approval.decision
```

Trailproof doesn't enforce this convention -- event types are just strings. The naming pattern is a recommendation for consistency.

## Example

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  from trailproof import Trailproof

  tp = Trailproof()

  event = tp.emit(
      event_type="myapp.user.login",
      actor_id="user-42",
      tenant_id="acme-corp",
      payload={"ip": "1.2.3.4", "method": "oauth"},
      trace_id="trace-abc",
      session_id="session-xyz",
  )

  # Access all fields
  print(event.event_id)     # "f47ac10b-..."
  print(event.event_type)   # "myapp.user.login"
  print(event.timestamp)    # "2025-01-15T10:30:00Z"
  print(event.actor_id)     # "user-42"
  print(event.tenant_id)    # "acme-corp"
  print(event.trace_id)     # "trace-abc"
  print(event.session_id)   # "session-xyz"
  print(event.payload)      # {"ip": "1.2.3.4", "method": "oauth"}
  print(event.prev_hash)    # "0000...0000" (genesis)
  print(event.hash)         # "a1b2c3..."
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import { Trailproof } from "@kyberonai/trailproof";

  const tp = new Trailproof();

  const event = tp.emit({
    eventType: "myapp.user.login",
    actorId: "user-42",
    tenantId: "acme-corp",
    payload: { ip: "1.2.3.4", method: "oauth" },
    traceId: "trace-abc",
    sessionId: "session-xyz",
  });

  console.log(event.eventId);    // "f47ac10b-..."
  console.log(event.eventType);  // "myapp.user.login"
  console.log(event.timestamp);  // "2025-01-15T10:30:00Z"
  console.log(event.actorId);    // "user-42"
  console.log(event.tenantId);   // "acme-corp"
  console.log(event.hash);       // "a1b2c3..."
  ```
</CodeGroup>

## Validation

Trailproof validates required fields on `emit()`. Missing or empty required fields throw a `ValidationError`:

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
# These all throw ValidationError:
tp.emit(event_type="", actor_id="user-42", tenant_id="acme", payload={})
tp.emit(event_type="app.action", actor_id="", tenant_id="acme", payload={})
tp.emit(event_type="app.action", actor_id="user-42", tenant_id="", payload={})
```

<Warning>
  All four required caller fields -- `event_type`, `actor_id`, `tenant_id`, and `payload` -- must be non-empty. Trailproof raises `ValidationError` immediately on empty or missing values.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Hash Chain" icon="link" color="#0EA5E9" href="/concepts/hash-chain">
    How events are cryptographically linked.
  </Card>

  <Card title="API Reference" icon="code" color="#0284C7" href="/api-reference/overview">
    Full API documentation for both SDKs.
  </Card>
</CardGroup>
