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 the Ingestion Gateway 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
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Event type. One of: track, page, identify, group |
event | string | Track only | Name of the event (e.g., "Order Completed", "Button Clicked") |
name | string | Page only | Name of the page (e.g., "Product Detail", "Checkout") |
properties | object | No | Event-specific data. Free-form key-value pairs |
traits | object | No | User or group attributes (used with identify and group events) |
userId | string | No | Known user ID. Set after an identify call |
anonymousId | string | Yes | Anonymous visitor ID. Generated by Datafly.js and stored in the _dfid cookie |
groupId | string | Group only | Group identifier (e.g., company or account ID) |
context | object | No | Contextual data about the event (page, device, campaign, consent, etc.) |
timestamp | string | No | ISO 8601 timestamp. Defaults to server receipt time if not provided |
messageId | string | No | Client-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.
| Field | Type | Description |
|---|---|---|
url | string | Full URL of the page |
path | string | URL path (e.g., /products/headphones) |
referrer | string | URL of the referring page |
title | string | Document title |
search | string | Query string (e.g., ?color=black&size=m) |
context.device
Device information, derived from the user agent string.
| Field | Type | Description |
|---|---|---|
type | string | Device type: desktop, mobile, tablet |
manufacturer | string | Device manufacturer (e.g., Apple, Samsung). Null for desktops |
model | string | Device model (e.g., iPhone 15, Galaxy S24). Null for desktops |
context.campaign
Campaign attribution, extracted from UTM parameters in the page URL.
| Field | Type | Description |
|---|---|---|
source | string | Campaign source (utm_source). E.g., google, facebook, newsletter |
medium | string | Campaign medium (utm_medium). E.g., cpc, email, organic |
name | string | Campaign name (utm_campaign). E.g., summer_sale |
term | string | Campaign term (utm_term). E.g., wireless headphones |
content | string | Campaign content (utm_content). E.g., ad_v2 |
context.consent
User consent state, populated from the consent management platform.
| Field | Type | Description |
|---|---|---|
analytics | boolean | Consent for analytics tracking |
marketing | boolean | Consent for marketing communications |
functional | boolean | Consent for functional/personalisation features |
advertising | boolean | Consent for advertising and retargeting |
Other Context Fields
| Field | Type | Description |
|---|---|---|
context.locale | string | Browser locale (e.g., en-US, de-DE) |
context.ip | string | Client IP address (set by the Ingestion Gateway from the request) |
context.userAgent | string | Full user agent string |
context.timezone | string | IANA 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.
| Convention | Example | Recommended |
|---|---|---|
| snake_case | product_id, order_total | Yes |
| camelCase | productId, orderTotal | Avoid |
| PascalCase | ProductId, OrderTotal | Avoid |
| kebab-case | product-id, order-total | Avoid |
Deduplication
The messageId field is used for event deduplication. The Ingestion Gateway checks incoming events against recently received message IDs (stored in Redis with a 24-hour TTL). If a duplicate messageId is detected, the event is 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
| Limit | Value |
|---|---|
| Maximum event payload size | 32 KB |
Maximum properties object depth | 10 levels |
| Maximum array length in properties | 200 items |
| Maximum batch size (batch endpoint) | 500 events or 500 KB |
Events exceeding these limits are rejected with a 422 Unprocessable Entity response and error code BATCH_TOO_LARGE or PAYLOAD_TOO_LARGE.