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

# Step examples

Add `examples` to any step in your flow config to document what it expects and produces. On a GA4 destination (`@walkeros/web-destination-gtag` with measurement ID `G-DEMO123456`):

```
"examples": {

  "purchase": {

    "in": { "name": "order complete", "data": { "id": "ORD-123", "total": 149.97 } },

    "mapping": { "name": "purchase", "data": { "map": { "transaction_id": "data.id", "value": "data.total" } } },

    "out": [["gtag", "event", "purchase", { "transaction_id": "ORD-123", "value": 149.97, "send_to": "G-DEMO123456" }]]

  }

}
```

Examples are test fixtures, documentation, and simulation data in one place. They live in your flow config, get stripped at build time, and have zero runtime impact.

Examples are mainly internal: packages use them for tests, docs and demos. In your own flow, use them sparingly, where one shows something the package examples cannot, for example a client flow's source with an example of its default behaviour. Mark such a fixture `"public": false` to keep it out of docs, UI and MCP default output while tests and `--simulate` still use it.

## What are step examples[​](#what-are-step-examples "Direct link to What are step examples")

Every source, transformer, and destination in a walkerOS flow is a **step**. Each step receives input and produces output. Step examples are named `{ in, out }` pairs that capture concrete data for each step: what goes in, what comes out.

They serve multiple purposes simultaneously:

* **Documentation**: developers see real data shapes, not just type signatures
* **Testing**: your tests use examples as fixtures, and `walkeros validate` checks that connected steps have compatible examples
* **Simulation**: debug your pipeline before deployment
* **LLM context**: AI tools use examples to suggest correct mappings

## The `{ in, out }` format[​](#the--in-out--format "Direct link to the--in-out--format")

Each example has a human-readable name and two fields:

```json
{
  "examples": {
    "page view": {
      "in": {
        "name": "page view",
        "data": { "title": "Home", "path": "/" }
      },
      "out": [["gtag", "event", "page_view", { "send_to": "G-DEMO123456" }]]
    },
    "purchase": {
      "in": {
        "name": "order complete",
        "data": { "id": "ORD-123", "total": 149.97, "currency": "EUR" }
      },
      "mapping": {
        "name": "purchase",
        "data": {
          "map": {
            "transaction_id": "data.id",
            "value": "data.total",
            "currency": "data.currency"
          }
        }
      },
      "out": [["gtag", "event", "purchase", {
        "transaction_id": "ORD-123",
        "value": 149.97,
        "currency": "EUR",
        "send_to": "G-DEMO123456"
      }]]
    }
  }
}
```

| Field                      | Type    | Description                                                                                                                                                                                                                                          |
| -------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `in`                       | any     | The data the step receives                                                                                                                                                                                                                           |
| `mapping`                  | object  | The mapping rule applied to this event (destinations only)                                                                                                                                                                                           |
| `out`                      | array   | The effects the step produces, in order. Each entry is a tuple `[callable, ...args]`: a vendor call such as `["gtag", ...]` for a destination, `["elb", event]` for a source, `["return", value]` for a transformer. `[]` means no observable effect |
| `out: [["return", false]]` | array   | The transformer rejects or filters this event                                                                                                                                                                                                        |
| `trigger`                  | object  | Sources only: how the example fires the source (`type`, such as `load`, `click` or `POST`, and `options`). This is simulation and test input, not the event's `trigger` field, which is a string                                                     |
| `command`                  | string  | Route `in` through a walker command instead of pushing it as an event (`config`, `consent`, `user`, `run`)                                                                                                                                           |
| `title`, `description`     | string  | Labels shown in docs and MCP output                                                                                                                                                                                                                  |
| `public`                   | boolean | `false` hides a test-only example from docs, UI and default MCP output (default `true`)                                                                                                                                                              |

For destinations, the optional `mapping` field captures the mapping rule that transforms the walkerOS event into the vendor-specific output. This ties the example to a specific mapping configuration, so tests and simulations can register it dynamically as `{ [entity]: { [action]: example.mapping } }`.

### Command examples[​](#command-examples "Direct link to Command examples")

Some destinations need to react to walker commands (consent updates, user identification, run state) rather than events. Set the `command` field on a step example so the test runner invokes `elb('walker <command>', in)` instead of pushing `in` as a regular event:

```json
{
  "command": "consent",
  "in": { "marketing": true, "functional": true },
  "out": [
    ["gtag", "consent", "default", { "ad_storage": "denied", "ad_user_data": "denied", "ad_personalization": "denied", "analytics_storage": "denied" }],
    ["gtag", "consent", "update", { "ad_storage": "granted", "ad_user_data": "granted", "ad_personalization": "granted", "analytics_storage": "granted" }]
  ]
}
```

Supported commands: `config`, `consent`, `user`, `run`. When `command` is set, `mapping` is ignored, because commands don't flow through event mapping. See the [walkeros-using-step-examples skill](https://github.com/elbwalker/walkerOS/blob/main/skills/walkeros-using-step-examples/SKILL.md#command-step-example) for the full test-runner pattern.

You can add as many named examples as you need. Tests refer to each example by its name, and the MCP `flow_examples` tool lists them by name for each step.

## Three type zones[​](#three-type-zones "Direct link to Three type zones")

A walkerOS flow has three distinct type zones. The shape of `in` and `out` depends on where the step sits:

```
  ARBITRARY          walkerOS.Event              ARBITRARY

 ┌─────────┐    ┌──────────────────────┐    ┌──────────────┐

 │ Source   │ →  │ Collector → Transform │ →  │ Destination  │

 │ ingest   │    │ → ... → Transform    │    │ output       │

 └─────────┘    └──────────────────────┘    └──────────────┘

  package-        known structure,            package-

  specific        varying properties          specific
```

* **Source `in`**: raw HTTP request body, DOM event, dataLayer push (package-specific)
* **Source `out`**: the `elb` call that pushes the `walkerOS.Event`, as `[["elb", event]]`
* **Transformer `in` and destination `in`**: `walkerOS.Event` (known structure, varying properties)
* **Transformer `out`**: `[["return", { "event": event }]]`, or `[["return", false]]` when the transformer drops the event
* **Destination `out`**: the vendor calls, such as `gtag()` or `fbq()` arguments or an HTTP request (vendor-specific)

## Adding examples to a flow[​](#adding-examples-to-a-flow "Direct link to Adding examples to a flow")

Here is a complete flow config with examples on a source, transformer, and destination:

```json
{
  "version": 4,
  "flows": {
    "default": {
      "config": { "platform": "web" },
      "sources": {
        "browser": {
          "package": "@walkeros/web-source-browser",
          "examples": {
            "page view": {
              "trigger": { "type": "load", "options": { "url": "https://example.com/", "title": "Home" } },
              "in": "",
              "out": [["elb", {
                "name": "page view",
                "data": { "domain": "example.com", "title": "Home", "referrer": "", "id": "/" },
                "context": {},
                "globals": {},
                "trigger": "load",
                "source": { "type": "browser", "platform": "web", "url": "https://example.com/", "referrer": "" }
              }]]
            }
          }
        }
      },
      "transformers": {
        "validate": {
          "package": "@walkeros/transformer-validate",
          "config": {
            "settings": { "contract": [{ "type": "object", "properties": { "data": { "required": ["title"] } } }] }
          },
          "examples": {
            "page view": {
              "in": { "name": "page view", "entity": "page", "action": "view", "data": { "title": "Home" } },
              "out": [["return", { "event": {
                "name": "page view", "entity": "page", "action": "view",
                "data": { "title": "Home" },
                "source": { "valid": true }
              } }]]
            }
          }
        }
      },
      "destinations": {
        "ga4": {
          "package": "@walkeros/web-destination-gtag",
          "config": {
            "settings": { "ga4": { "measurementId": "G-DEMO123456" } }
          },
          "before": "validate",
          "examples": {
            "page view": {
              "in": { "name": "page view", "data": { "title": "Home" } },
              "mapping": {
                "name": "page_view",
                "data": { "map": { "page_title": "data.title" } }
              },
              "out": [["gtag", "event", "page_view", { "page_title": "Home", "send_to": "G-DEMO123456" }]]
            }
          }
        }
      }
    }
  }
}
```

The `ga4` destination runs `validate` in its `before` chain, so [cross-step validation](#validate-examples) checks the transformer's `out` against the destination's `in`.

Examples are stripped by the bundler at build time. They never appear in your production bundle.

## Using examples with the CLI[​](#using-examples-with-the-cli "Direct link to Using examples with the CLI")

### Simulate a step with an example's input[​](#simulate-a-step-with-an-examples-input "Direct link to Simulate a step with an example's input")

Push an event through one step with its external calls mocked. `--event` takes the input itself, so pass an example's `in` value:

```bash
# Push the "page view" example's in value through the ga4 destination
walkeros push flow.json --simulate destination.ga4 --event '{"name":"page view","data":{"title":"Home"}}'
```

The CLI runs the event through the flow with the step mocked and prints what the step did: for a destination, the matched mapping rule and every recorded vendor call. See [simulation output](/preview/pr-749/docs/apps/cli.md#simulation-output). It does not compare anything against the step's `out` and exits with code 1 only when the push fails with an error, so a mapping that produces the wrong output still exits 0. To assert on `out`, run the examples in your own tests (see [Using examples in tests](#using-examples-in-tests)).

### Validate examples[​](#validate-examples "Direct link to Validate examples")

`walkeros validate` checks examples statically. It does not run any step:

```bash
walkeros validate flow.json
```

For steps connected through `next` (source to transformer, transformer to transformer) or a destination's `before` chain, it checks that at least one `out` of the upstream step is structurally compatible with an `in` of the downstream step. Both values must have the same type. Two objects are compatible when they share at least half of the keys of the object with fewer keys; any two arrays are compatible regardless of their content. This is a shape check, not an equality check. An `out` written as effects is read for the events it passes on: `[["elb", event]]` and `[["return", { "event": ... }]]` pass the event, `[["return", [...]]]` passes each item, and `["return", false]`, `message.ack`, `response` or vendor calls pass nothing.

* No compatible pair is an error.
* A connection is only checked when both steps declare `examples`. If either step has no `examples` key, nothing is checked and no warning is produced.
* When both steps declare `examples` but one side has no usable value, the connection produces a warning. An upstream `out` counts when it passes on at least one event; empty values such as `out: []` are skipped. A downstream `in` counts unless its example sets `command`.
* Other chains, such as a source's or transformer's `before`, a destination's `next` or `collector.next`, and steps without these fields are not checked.
* Each `@walkeros/transformer-validate` step's own examples agree with its linked contract and settings (see [Validate](/preview/pr-749/docs/getting-started/flow/validate.md#design-time-checks)); examples of other steps are not checked against contracts.

## Using examples in tests[​](#using-examples-in-tests "Direct link to Using examples in tests")

Extract examples from your flow config and use them as test fixtures:

```typescript
import { readFileSync } from 'fs';
import { startFlow } from '@walkeros/collector';
import { destinationGtag } from '@walkeros/web-destination-gtag';

const flow = JSON.parse(readFileSync('flow.json', 'utf-8'));
const ga4 = flow.flows.default.destinations.ga4;
const examples: Record<string, { in: { name: string }; mapping?: unknown; out: unknown[][] }> = ga4.examples;

it.each(Object.entries(examples))('ga4 destination: %s', async (name, example) => {
  // Record every gtag() call instead of loading the real gtag.js
  const calls: unknown[][] = [];
  const env = { window: { dataLayer: [], gtag: (...args: unknown[]) => calls.push(['gtag', ...args]) } };
  const [entity, action] = example.in.name.split(' ');

  const { elb } = await startFlow({
    destinations: { ga4: { code: destinationGtag, config: { ...ga4.config, mapping: { [entity]: { [action]: example.mapping } } }, env } },
  });
  await elb(example.in);

  // calls[0] is the gtag('config', ...) call the destination makes on init
  expect(calls.slice(1)).toEqual(example.out);
});
```

This pattern means your flow config is the single source of truth for both documentation and tests.

## Package-level vs flow-level examples[​](#package-level-vs-flow-level-examples "Direct link to Package-level vs flow-level examples")

Examples exist at two levels:

| Level       | Where                                             | Purpose                                             |
| ----------- | ------------------------------------------------- | --------------------------------------------------- |
| **Package** | `walkerOS.json` in the npm package (via `dev.ts`) | Generic examples showing what the package handles   |
| **Flow**    | Inline on step references in `flow.json`          | Specific examples for your actual data and mappings |

**Package examples** are generic and ship with the npm package. They show the package's capabilities with sample data. The MCP tools `package_get` and `flow_examples` read them from the package's `walkerOS.json` on the CDN.

**Flow examples** are specific to your setup. They use your real event names, your actual data properties, and your configured mappings. In the MCP `flow_examples` tool, a step's flow examples take precedence over its package's examples; a step without flow examples falls back to the package's examples.

How packages ship examples

Packages export examples through the `dev.ts` convention:

```typescript
// src/dev.ts
export * as schemas from './schemas';
export * as examples from './examples';
```

These are included in the package's `walkerOS.json` metadata and discoverable via CDN, following the same `{ in, out }` format used in flow configs.

A package with several exports (for example `destinationBigQuery` and `destinationPubSub` in `@walkeros/server-destination-gcp`) also exports `exportExamples`, a map from every export name, the default included, to that export's examples. The CLI, MCP and `walkerOS.json` pick the entry for the step's `import`:

```typescript
// src/dev.ts
export const exportExamples = {
  destinationBigQuery: bigqueryExamples,
  destinationPubSub: pubsubExamples,
};
```

Such a package also exports `exportSchemas`, the same map for schemas: every export name, the default included, to that export's `settings` (and `mapping` or `setup` where it has them). `walkeros validate` and MCP `package_get` use the entry for the step's `import`. The build fails when either map does not list exactly the exports in `package.json` `walkerOS.exports`, or an `exportSchemas` entry has no `settings`:

```typescript
// src/dev.ts
export const exportSchemas = {
  destinationBigQuery: { settings: bigquery.settings, mapping: bigquery.mapping },
  destinationPubSub: { settings: pubsub.settings, mapping: pubsub.mapping, setup: pubsub.setup },
};
```

## In the complete example[​](#in-the-complete-example "Direct link to In the complete example")

Every step of [`flow-complete.json`](https://github.com/elbwalker/walkerOS/blob/main/packages/cli/examples/flow-complete.json) carries examples. The web GA4 destination's set:

`/flows/web/destinations/ga4/examples`

```json
{
  "purchase": { … },
  "purchaseWithoutCoupon": { … },
  "productView": { … },
  "consentUpdate": { … }
}
```

examples are the contract of a step: this in gives this out, checked by simulation. [Guide chapter `step-envelope`](https://github.com/elbwalker/walkerOS/blob/main/packages/cli/examples/flow-complete.md#step-envelope-one-step-shape)

## Next steps[​](#next-steps "Direct link to Next steps")

* **[CLI](/preview/pr-749/docs/apps/cli.md)**: Bundle and simulate flows with examples
* **[Flow](/preview/pr-749/docs/getting-started/flow.md)**: Learn the full flow configuration format
* **[Mapping](/preview/pr-749/docs/mapping.md)**: Transform events between steps
* **[Event model](/preview/pr-749/docs/getting-started/event-model.md)**: Understand the walkerOS event structure
