Skip to main content

Event Contract

The event contract is the central primitive in event-spec. It is a YAML file that describes exactly one analytics event: its name, version, status, type, and every property it carries.

Anatomy of a spec file

specs/ecommerce/product_viewed/1-0-0.yaml
$schema: "https://event-spec.io/schemas/event/v1"
name: product_viewed
display_name: "Product Viewed"
version: "1-0-0"
status: active
namespace: ecommerce
type: track
event_name: "Product Viewed"
description: "Fired when a user views a product detail page."

properties:
product_id:
type: string
required: true
description: "SKU or internal product identifier"
category:
type: string
required: true
enum: [clothing, electronics, other]
price:
type: number
required: false
minimum: 0
currency:
type: string
required: false
default: "USD"
tags:
type: array
required: false

hooks:
sampling:
strategy: user_id_hash
rate: 0.5
validation:
mode: strict

Versioning: SchemaVer

event-spec uses SchemaVer (MAJOR-MINOR-PATCH) for event versions — borrowed from Snowplow Iglu. Hyphens visually distinguish event versions from SemVer (which governs CLI and SDK releases).

ChangeBump
Add required propertyMAJOR
Remove any propertyMAJOR
Rename propertyMAJOR
Rename event (name or event_name changed)MAJOR
Change property typeMAJOR
Change event type (trackpage etc.)MAJOR
Make optional → requiredMAJOR
Remove enum valueMAJOR
Status changed to deletedMAJOR
Make required → optionalMINOR
Add optional propertyMINOR
Add enum valueMINOR
Status changed (non-deleted)MINOR
Sampling config added / changed / removedMINOR
Context properties changedMINOR
Provider overrides changedMINOR
Property description-only changePATCH
Metadata changed (display_name, description, owner, tags)PATCH
Destinations changedPATCH
Property priority changedPATCH

The CLI enforces these rules with event-spec diff:

event-spec diff specs/ecommerce/product_viewed/1-0-0.yaml \
specs/ecommerce/product_viewed/2-0-0.yaml
# BREAKING: removed property "currency"
# BREAKING: "category" changed type string → integer

See CLI — diff for the full command reference.

Status lifecycle

StatusMeaning
draftWork in progress. Not validated in CI by default.
activeIn production use. Validated strictly.
deprecatedBeing phased out. validate --strict emits a warning.
deletedNo longer used. Retained for historical audit purposes.

The validation hook uses status to decide behavior: active events are fully validated; deprecated events emit warnings; deleted events are skipped.

Event type

TypeAnalytics call
trackclient.Track()
identifyclient.Identify()
groupclient.Group()
pageclient.Page()
aliasclient.Alias()

Property types

TypeGenerated Go typeGenerated TypeScript type
stringstringstring
numberfloat64number
integerint64number
booleanboolboolean
objectmap[string]anyRecord<string, unknown>
array[]anyunknown[]

Constraints

ConstraintApplies toExample
enumstring, integerenum: [clothing, electronics]
patternstringpattern: "^[A-Z]{2}$"
minimumnumber, integerminimum: 0
maximumnumber, integermaximum: 100
defaultanydefault: "USD"
aliasesanyaliases: [productId, product-id]
requiredanyrequired: true

Directory layout

Specs are organized as:

specs/
└── <namespace>/
└── <event_name>/
├── 1-0-0.yaml
└── 2-0-0.yaml # newer version

Multiple versions of the same event can coexist. The registry keeps all versions; codegen defaults to the latest active version.

Full field reference

See Spec Reference — Event for the complete field documentation.