ReferenceEvent Schema

Event Schema

Every event flowing through Datafly Signal conforms to a canonical format. Whether collected by Datafly.js in the browser or submitted via the server-side API, events are normalised into this schema at ingestion before entering the processing pipeline.

Canonical Event Format

{
  "type": "track",
  "event": "Order Completed",
  "properties": {
    "order_id": "ORD-1234",
    "total": 129.99,
    "currency": "USD",
    "products": [
      {
        "product_id": "SKU-001",
        "name": "Wireless Headphones",
        "price": 79.99,
        "quantity": 1
      }
    ]
  },
  "userId": "user_98765",
  "anonymousId": "anon_a1b2c3d4",
  "groupId": null,
  "context": {
    "page": {
      "url": "https://shop.example.com/checkout/complete",
      "path": "/checkout/complete",
      "referrer": "https://shop.example.com/checkout",
      "title": "Order Confirmation | Shop",
      "search": ""
    },
    "device": {
      "type": "desktop",
      "manufacturer": null,
      "model": null
    },
    "campaign": {
      "source": "google",
      "medium": "cpc",
      "name": "summer_sale",
      "term": "wireless headphones",
      "content": "ad_v2"
    },
    "locale": "en-US",
    "ip": "203.0.113.42",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "consent": {
      "analytics": true,
      "marketing": true,
      "functional": true,
      "advertising": true
    }
  },
  "timestamp": "2026-02-25T14:30:00.000Z",
  "messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Top-Level Fields

FieldTypeRequiredDescription
typestringYesEvent type. One of: track, page, identify, group
eventstringTrack onlyName of the event (e.g., "Order Completed", "Button Clicked")
namestringPage onlyName of the page (e.g., "Product Detail", "Checkout")
propertiesobjectNoEvent-specific data. Free-form key-value pairs
traitsobjectNoUser or group attributes (used with identify and group events)
userIdstringNoKnown user ID. Set after an identify call
anonymousIdstringYesAnonymous visitor ID. Generated by Datafly.js and persisted in a first-party cookie
groupIdstringGroup onlyGroup identifier (e.g., company or account ID)
contextobjectNoContextual data about the event (page, device, campaign, consent, etc.)
timestampstringNoISO 8601 timestamp. Defaults to server receipt time if not provided
messageIdstringNoClient-generated UUID for deduplication. Generated by Datafly.js automatically

Context Object

The context object carries metadata about the environment in which the event occurred.

context.page

Page information, automatically populated by Datafly.js.

FieldTypeDescription
urlstringFull URL of the page
pathstringURL path (e.g., /products/headphones)
referrerstringURL of the referring page
titlestringDocument title
searchstringQuery string (e.g., ?color=black&size=m)

context.device

Device information, derived from the user agent string.

FieldTypeDescription
typestringDevice type: desktop, mobile, tablet
manufacturerstringDevice manufacturer (e.g., Apple, Samsung). Null for desktops
modelstringDevice model (e.g., iPhone 15, Galaxy S24). Null for desktops

context.campaign

Campaign attribution, extracted from UTM parameters in the page URL.

FieldTypeDescription
sourcestringCampaign source (utm_source). E.g., google, facebook, newsletter
mediumstringCampaign medium (utm_medium). E.g., cpc, email, organic
namestringCampaign name (utm_campaign). E.g., summer_sale
termstringCampaign term (utm_term). E.g., wireless headphones
contentstringCampaign content (utm_content). E.g., ad_v2

context.consent

User consent state, populated from the consent management platform.

FieldTypeDescription
analyticsbooleanConsent for analytics tracking
marketingbooleanConsent for marketing communications
functionalbooleanConsent for functional/personalisation features
advertisingbooleanConsent for advertising and retargeting

Other Context Fields

FieldTypeDescription
context.localestringBrowser locale (e.g., en-US, de-DE)
context.ipstringClient IP address (set by Signal from the request)
context.userAgentstringFull user agent string
context.timezonestringIANA timezone (e.g., America/New_York)

Event Types

Track

A track event records a specific user action.

{
  "type": "track",
  "event": "Product Added",
  "properties": {
    "product_id": "SKU-001",
    "name": "Wireless Headphones",
    "price": 79.99,
    "quantity": 1,
    "category": "Audio"
  }
}

Page

A page event records a page view. Sent automatically by Datafly.js on each page load and client-side navigation.

{
  "type": "page",
  "name": "Product Detail",
  "properties": {
    "url": "https://shop.example.com/products/headphones",
    "title": "Wireless Headphones | Shop",
    "path": "/products/headphones"
  }
}

Identify

An identify event links an anonymous visitor to a known user.

{
  "type": "identify",
  "userId": "user_98765",
  "traits": {
    "email": "jane@example.com",
    "name": "Jane Smith",
    "plan": "premium"
  }
}

Group

A group event associates a user with a group (company, team, account).

{
  "type": "group",
  "groupId": "org_555",
  "traits": {
    "name": "Acme Corp",
    "industry": "Technology",
    "employees": 250
  }
}

Property Naming Conventions

Use snake_case for property names. This ensures consistency across the pipeline and compatibility with all vendor API formatters and data warehouse destinations.

ConventionExampleRecommended
snake_caseproduct_id, order_totalYes
camelCaseproductId, orderTotalAvoid
PascalCaseProductId, OrderTotalAvoid
kebab-caseproduct-id, order-totalAvoid

Deduplication

The messageId field is used for event deduplication. Signal suppresses duplicate messageIds within a rolling 24-hour window; duplicates are acknowledged but not reprocessed.

Datafly.js generates a UUID v4 for messageId automatically. For server-side events, you should generate and include a unique messageId to prevent duplicate processing during retries.

Size Limits

Defaults. Each limit is a deployment setting (the ingestion gateway’s INGESTION_MAX_* environment variables, or ingestionGateway.inputLimits in the Helm chart), so it can be raised for a deployment without a code change, within a fixed upper bound.

LimitDefaultUpper bound
Events per browser/app batch (/v1/batch)50010,000
Events per server-side request (/v1/events)2,00050,000
Nesting depth of properties / traits32 levels128
Keys across properties + traits per event2005,000
Length of a single string value16 KB1 MB
Browser/app request body1 MB16 MB
Server-side request body (/v1/events)10 MB100 MB

A request over an event-count limit is rejected with 413 Payload Too Large; an event over a structural limit (depth, key count, string length) is rejected with 400 Bad Request. Neither is retried by Datafly.js.