> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Understanding walkerOS Events

## Overview[​](#overview "Direct link to Overview")

walkerOS events are self-describing, stateless, vendor-agnostic data structures. They capture user interactions in a standardized format that can be transformed for any destination.

**Core principle:** Events describe WHAT happened, not WHERE it goes. Stateless. Self-describing. Industry-agnostic.

## Entity-Action Naming (Critical)[​](#entity-action-naming-critical "Direct link to Entity-Action Naming (Critical)")

**STRICT REQUIREMENT:** All events use "entity action" format with space separation.

```
// Correct

'page view';

'product add';

'order complete';

'button click';



// Wrong

'page_view'; // underscore

'pageview'; // no separator

'purchase'; // no entity

'add_to_cart'; // wrong format
```

**Parsing:** `const [entity, action] = event.split(' ')`

* **Entity:** Noun (page, product, user, order, button)
* **Action:** Verb (view, add, complete, click, login)

## Event Properties[​](#event-properties "Direct link to Event Properties")

See [packages/core/src/types/walkeros.ts](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/types/walkeros.ts) for canonical types (Event interface, plus event helpers in `event.ts`).

| Property          | Type   | Purpose                                                      | Example                                |
| ----------------- | ------ | ------------------------------------------------------------ | -------------------------------------- |
| `name`            | string | "entity action" format                                       | `"product view"`                       |
| `data`            | object | Entity-specific properties                                   | `{ id: "P123", price: 99 }`            |
| `context`         | object | State/environment info (optional)                            | `{ stage: ["checkout", 1] }`           |
| `globals`         | object | Global properties                                            | `{ language: "en" }`                   |
| `user`            | object | User identification                                          | `{ id: "user123" }`                    |
| `nested`          | array  | Related entities (optional)                                  | `[{ entity: "product", data: {...} }]` |
| `consent`         | object | Consent states                                               | `{ marketing: true }`                  |
| `id`              | string | W3C span\_id, 16 lowercase hex chars, generated by collector | `"0123456789abcdef"`                   |
| `timestamp`       | number | Auto-generated Unix ms                                       | `1647261462000`                        |
| `entity`          | string | Parsed from name                                             | `"product"`                            |
| `action`          | string | Parsed from name                                             | `"view"`                               |
| `source.type`     | string | Source kind (`browser`, `dataLayer`, `cookiefirst`, ...)     | `"browser"`                            |
| `source.platform` | string | Runtime platform (`web`, `server`)                           | `"web"`                                |
| `source.schema`   | string | Source-emitted schema/version (optional)                     | `"datalayer-v2"`                       |
| `source.trace`    | string | Run-scoped W3C trace\_id, shared by every event of a run     | `"0123...cdef"` (32 hex)               |
| `source.count`    | number | Per-run emission sequence (1, 2, 3, ...)                     | `1`                                    |
| `source.release`  | object | Per-flow config release map, accumulates across crossings    | `{ web: "3", server: "5" }`            |

### data Property[​](#data-property "Direct link to data Property")

Entity-specific properties. Schema-free but consistent within entity type.

```
// product entity

data: { id: "P123", name: "Laptop", price: 999, currency: "USD" }



// page entity

data: { title: "Home", path: "/", referrer: "https://..." }
```

### context Property[​](#context-property "Direct link to context Property")

Hierarchical state information. Format: `{ name: [value, order] }`. Optional.

```
context: {

  stage: ["checkout", 1],    // checkout stage, first step

  test: ["variant-A", 0],    // A/B test variant

  group: ["premium", 2]      // user segment

}
```

### globals Property[​](#globals-property "Direct link to globals Property")

Properties that apply to ALL events in the session.

```
globals: {

  language: "en",

  currency: "USD",

  environment: "production"

}
```

### nested Property[​](#nested-property "Direct link to nested Property")

Related entities captured together. Optional.

```
// Order with line items

nested: [

  { entity: 'product', data: { id: 'P1', quantity: 2 } },

  { entity: 'product', data: { id: 'P2', quantity: 1 } },

];
```

### user Property[​](#user-property "Direct link to user Property")

User identification across sessions.

```
user: {

  id: "user123",        // Your user ID

  device: "device456",  // Device fingerprint

  session: "sess789"    // Session ID

}
```

### source Property[​](#source-property "Direct link to source Property")

Where the event came from. The collector enriches the event with `source` data based on which source emitted it.

```
source: {

  type: 'browser',         // source kind (browser, dataLayer, cookiefirst, ...)

  platform: 'web',         // runtime: 'web' or 'server'

  version: '4.0.0',        // external source-emitter version (collector no longer sets this)

  schema: 'datalayer-v2',  // optional schema/version emitted by the source

  trace: '0123...cdef',    // run-scoped W3C trace_id, groups all events of a run

  count: 1,                // per-run emission sequence (1, 2, 3, ...)

  release: { web: '3' },   // per-flow config release map, accumulates web to server

  url: 'https://...',      // page URL (web only, set by web-context transformer)

  referrer: '...',         // page referrer (web only)

  tool: 'cli',             // tool that produced the event (optional)

  command: 'simulate',     // command name (optional)

}
```

CMP and other non-page sources do NOT set `source.url`/`source.referrer` - that's the responsibility of a web-context transformer.

`source.trace` is the run grouping key: the collector mints a fresh run-scoped trace\_id on each run and stamps it (plus a per-run `source.count`) on every event when absent. It is preserved unchanged when an event is forwarded from web to server, so the whole pipeline shares one trace.

`source.release` records which config handled the event, keyed by flow name. Each flow the event passes through adds its own entry (that flow's config release), so an event captured on the web and processed on the server carries both flow releases, and a warehouse row shows exactly which config version touched it. This is distinct from `source.version`, the source package version set only by external source emitters (the collector no longer stamps it).

## Migration from v3[​](#migration-from-v3 "Direct link to Migration from v3")

If you have existing v3 events or configs, here is the v4 mapping:

| v3                                | v4                                                                  |
| --------------------------------- | ------------------------------------------------------------------- |
| `event.id` = `"<ts>-<rnd>-<seq>"` | `event.id` = W3C span\_id (16 lowercase hex chars)                  |
| `event.version`                   | removed - see `source.version` and `source.schema`                  |
| `event.group`                     | removed - use `source.trace` (run-scoped trace\_id) for correlation |
| `event.count`                     | removed - use `source.count` (per-run emission sequence)            |
| `event.source.id`                 | `event.source.url` (when it meant page URL)                         |
| `nested: [{ type, data }]`        | `nested: [{ entity, data }]` (`Entity.entity` replaces `.type`)     |

## Design Principles[​](#design-principles "Direct link to Design Principles")

### Statelessness[​](#statelessness "Direct link to Statelessness")

Events are immutable snapshots. They don't reference previous events or maintain state.

### Self-Describing[​](#self-describing "Direct link to Self-Describing")

Events contain all context needed to understand them. No external lookups required.

### Vendor-Agnostic[​](#vendor-agnostic "Direct link to Vendor-Agnostic")

Events use generic concepts (product, order) not vendor-specific (GA4 item, FB content).

Transformation to vendor formats happens in **mapping**, not in event creation.

## Creating Events[​](#creating-events "Direct link to Creating Events")

```
import { elb } from '@walkeros/collector';



// Basic event

await elb('page view', { title: 'Home', path: '/' });



// With all properties

await elb(

  'product add',

  { id: 'P123', price: 99 }, // data

  { stage: ['cart', 1] }, // context (optional)

  { currency: 'USD' }, // globals (optional)

);
```

## Related Skills[​](#related-skills "Direct link to Related Skills")

* [walkeros-understanding-mapping](https://www.walkeros.io/skills/walkeros-understanding-mapping.md) - Transform events for destinations
* [walkeros-understanding-flow](https://www.walkeros.io/skills/walkeros-understanding-flow.md) - Data flow architecture

**Source Files:**

* [packages/core/src/types/walkeros.ts](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/types/walkeros.ts) - Event types
* [packages/core/src/schemas/](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/schemas) - Event schemas

**Documentation:**

* [Website: Event Model](https://www.walkeros.io/docs/getting-started/event-model.md) - User-facing docs
* [walkeros.io/docs](https://www.walkeros.io/docs/) - Public documentation
