Skip to main content
Every event in a POST /beacon batch is validated against a schema chosen by its event_type field. Events that don’t match their schema are dropped from the batch.

Common fields

These fields are accepted on every event. Server-enriched fields (geo, device, browser, OS) are added automatically. Don’t send them.
string
required
Unique identifier for the event. Use a ULID or UUID generated client-side. Required for deduplication.
string
required
The event discriminator. Must be one of the values listed in Supported event types.
string
required
ISO 8601 timestamp of when the event occurred (e.g., "2026-06-01T14:30:00Z"). Accepted as either an ISO string or a Date-parseable value; stored in UTC.
string
required
Anonymized session identifier for the shopper’s visit. Should be stable for the duration of a session and rotate at session expiry.
string
Logged-in customer identifier. null or omitted for guests.
string
The token returned by Search, Browse, or Blocks. Required to attribute downstream product_click, product_view, add_to_cart, block_view, and content_* events back to the originating request.
string
"web" or "app". Optional. If omitted, the worker infers it from User-Agent and the X-Requested-With header.
number
Shopify product ID. Required for product-scoped events (see below).
number
Shopify variant ID.
string
Collection handle. Required for collection_view.
string
Type of content: "article" or "page". Required for content_view, content_click, and content_impression.
number
Shopify article or page ID. Required for content_view, content_click, and content_impression.
string
Handle of the article or page. Optional on content events.
string
Banner ULID. Required for banner_impression and banner_click.
string
ID of the merchandising rule that produced the banner. Read it from the banner’s rule_id field in the Browse response. Optional on banner events.
string
Banner type slug: "link" for the built-in type, otherwise a custom banner type slug. Optional on banner events.
string
"inject" or "overtake". Optional on banner events.
number
Grid position from the banner’s web_layout. Optional on banner events.
number
Grid position from the banner’s mobile_layout. Optional on banner events.
number
1-indexed position in the result set. Required for product_click, product_impression, product_hover, product_touch.
string
UTM source.
string
UTM medium.
string
UTM campaign.
object
Free-form additional context (e.g., A/B test bucket, page template, locale). Defaults to {}.

Server-enriched fields

Don’t set these. The worker fills them in:

Supported event types

Engagement events (fired from the storefront): Request events (typically sent server-side by the platform, not the storefront; included here for completeness):
Storefront integrations should generally only send the engagement events in the first table. The request events are emitted by the Layers platform itself.
The content_* events track engagement with articles and pages returned by blocks that use the related content strategy. Include the block’s attribution_token so clicks and views attribute back to the originating block request. The banner_* events track engagement with merchandising banners returned on Browse responses. Include the banner’s rule_id (present on each banner in the response) so impressions and clicks attribute back to the merchandising rule that placed it. banner_type, banner_mode, web_position, and mobile_position are optional and enable slicing engagement by banner type, mode, and grid position. Platform-emitted request events carry a derived device_type (mobile, tablet, desktop, or bot) rather than a raw User-Agent string. Their contextual_data contains only the validated fields from the request’s context parameter (see the context data structure). Layers drops unrecognized keys.

Validation rules

  • event_id, event_type, timestamp, session_id are required on every event.
  • event_type must be one of the values above. Unknown types are dropped.
  • Type-specific required fields above must be present; missing them causes the individual event to be dropped (the batch still ingests).
  • The batch must contain between 1 and 100 events. Outside that range, the entire request fails with 422.

Next steps