- CLI Reference
- Commands
- ironflow event
ironflow event
Manage event schemas and test upcasters.
ironflow event <subcommand> [flags]ironflow event schema register
Section titled “ironflow event schema register”Register a JSON schema for an event type at a specific version.
ironflow event schema register <event-name> [flags]Arguments:
| Argument | Required | Description |
|---|---|---|
event-name | Yes | The event name (e.g., order.created) |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--version | int | Schema version (required) | ||
--file | string | Path to JSON schema file | ||
--schema | string | Inline JSON schema string | ||
--description | string | Schema description | ||
--server | -s | string | Server URL override |
One of --file or --schema is required. Cannot use both.
Examples:
ironflow event schema register order.created --version 1 --file schema.jsonironflow event schema register order.created --version 1 --schema '{"type":"object"}'ironflow event schema register order.created --version 2 --file schema-v2.json --description "Added address field"The schema must be a JSON Schema the server can compile (draft 2020-12); a
malformed document is rejected. Re-registering an existing (event name, version) overwrites it and reports updated rather than created.
The created/updated distinction is advisory. It is read before the upsert
rather than derived from it, so two registrations racing on the same
(event name, version) can both report created. The write itself is still
correct — last one wins — and this is a display label on a command a human
runs, not a value to branch on.
Registering a schema does not by itself enforce it. See
IRONFLOW_EVENT_SCHEMA_ENFORCEMENT,
which is off by default.
ironflow event schema list
Section titled “ironflow event schema list”List registered event schemas.
ironflow event schema list [flags]Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--event | string | Filter by event name | ||
--limit | int | 100 | Maximum number of schemas to return | |
--json | bool | false | Output as JSON | |
--server | -s | string | Server URL override |
Output:
EVENT VERSION DESCRIPTION REGISTEREDorder.created 1 Order created event 2025-01-15 12:00:05order.created 2 Added address field 2025-01-20 09:30:00Examples:
ironflow event schema listironflow event schema list --event order.createdironflow event schema list --jsonironflow event schema get
Section titled “ironflow event schema get”Get detailed information about a registered event schema.
ironflow event schema get <event-name> [flags]Arguments:
| Argument | Required | Description |
|---|---|---|
event-name | Yes | The event name to look up |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--version | int | 0 | Schema version (0 = latest) | |
--json | bool | false | Output as JSON | |
--server | -s | string | Server URL override |
Output:
Event: order.createdVersion: 2Description: Added address fieldRegistered: 2025-01-20 09:30:00Schema:{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"object"}}}Examples:
ironflow event schema get order.createdironflow event schema get order.created --version 2ironflow event schema get order.created --jsonironflow event schema delete
Section titled “ironflow event schema delete”Delete a registered event schema.
ironflow event schema delete <event-name> [flags]Arguments:
| Argument | Required | Description |
|---|---|---|
event-name | Yes | The event name to delete |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--version | int | Schema version (required) | ||
--server | -s | string | Server URL override |
Output:
Deleted schema order.created (v1)ironflow event schema check
Section titled “ironflow event schema check”Report whether event-schema enforcement is actually enforcing anything.
Enforcement is opt-in and off by default, and it has several ways to accept
every payload without validating it. From outside, all of them look exactly
like “every payload was clean”: an operator sets
IRONFLOW_EVENT_SCHEMA_ENFORCEMENT=reject, sees zero rejections, and cannot
tell which they are in. This command tells them apart (#1958).
ironflow event schema check [event-name] [flags]Arguments:
| Argument | Required | Description |
|---|---|---|
event-name | No | Report on one event name only (default: every schema) |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--window | int | 0 | Traffic sample window in hours (0 = default, 24) | |
--json | bool | false | Output as JSON | |
--server | -s | string | Server URL override |
Verdicts:
| Verdict | Meaning |
|---|---|
enforcing | Events at this version, all validated against this schema |
partial | Some events at this version validated against this schema |
unvalidated | Events at this version, none validated against this schema |
unused | Events of this name arrive, but at a different version |
no-traffic | No events of this name in the window |
permissive | The schema compiles but accepts every payload |
broken | The stored schema does not compile; enforcement fails open |
permissive is the one to read twice. A JSON Schema that compiles is not
necessarily one that constrains: Draft 2020-12 treats an unrecognized keyword
as an annotation, so {"foo":"bar"} is a valid schema that accepts every
payload, exactly as {} does. Registering a sample payload by mistake succeeds
and enforces nothing. Registration cannot reject these — {} is a legitimate
permissive schema — so this report is where they surface. The check is a
heuristic (it asks whether the schema rejects any of six probe documents), and
it errs toward reporting permissive only when a schema really does accept
every JSON type.
unvalidated means the events reached the store without being checked —
because the mode was off, or the name was ungoverned at the time, or the stored
schema would not compile. It is not a claim that the payloads were bad.
Output:
Enforcement mode: rejectTraffic window: last 24h
EVENT VER HASH VERDICT DETAILorder.created 1 3f2a91c04b7e5d18 enforcing 340 events at v1 in the last 24h, all validated against this schemaorder.created 2 9b1e77c2aa04f6d3 unused 340 events in the last 24h, none at v2 — they arrive at v1 (340). Version matching is exact, so this schema governs none of them.user.signup 1 c40de9f1b2a83057 permissive schema compiles but rejects nothing — every payload satisfies it. Registering a sample payload instead of a schema looks exactly like this.With the mode off, the table still renders and a banner says so — the verdicts then describe what would happen.
Counts are a sample of the newest matching events, not lifetime totals. When
the sample hits its scan cap the header says (sampled).
Examples:
ironflow event schema checkironflow event schema check order.createdironflow event schema check --window 168ironflow event schema check --jsonironflow event upcast
Section titled “ironflow event upcast”Test how an event would be transformed between schema versions.
ironflow event upcast <event-name> [flags]Arguments:
| Argument | Required | Description |
|---|---|---|
event-name | Yes | The event name to upcast |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--from | int | Source version (required) | ||
--to | int | Target version (required) | ||
--data | string | Event data as JSON | ||
--data-file | string | Path to JSON file with data | ||
--json | bool | false | Output as JSON | |
--server | -s | string | Server URL override |
Data input follows the same rules as emit (flag vs file vs stdin).
Output:
Steps applied:FROM TO DESCRIPTION1 2 added priority field
Result data:{ "orderId": "123", "customerId": "456", "priority": "normal"}Examples:
ironflow event upcast order.created --from 1 --to 2 --data '{"orderId":"123"}'ironflow event upcast order.created --from 1 --to 2 --data-file event.jsonironflow event upcast order.created --from 1 --to 3 --data '{}' --json