Event SpecsOverview

Event Specs

Datafly Signal uses a consistent set of snake_case event IDs across all verticals. These IDs are:

  • The value sent in the event field by Datafly.js (e.g. datafly.track('add_to_cart', {...}))
  • The key used in your pipeline’s Per-Event Parameters configuration
  • The stable identifier used for vendor event name mapping

Using the standard event IDs from these specs means your pipelines stay compatible with pre-built blueprints and vendor mapping tables — you won’t need to manually configure the event name for each destination.

How event IDs work

Every event flowing through Signal has an event field:

{
  "type": "track",
  "event": "add_to_cart",
  "properties": {
    "currency": "GBP",
    "value": 79.99,
    "items": [
      { "item_id": "SKU-001", "item_name": "Running Shoes", "price": 79.99, "quantity": 1 }
    ]
  }
}

The pipeline engine looks up the event value against your Per-Event Parameters configuration. If a matching section exists, those field mappings are applied on top of the global parameters before delivery to the vendor.

Built-in events

These events are sent automatically by Datafly.js without any track() call:

Event IDSent byDescription
pagedatafly.page()Page view. Fired automatically on each page load. Pass page_type to classify it (see below).
identifydatafly.identify(userId, traits)Links anonymous visitor to a known user.
groupdatafly.group(groupId, traits)Associates user with a company or account.

Classifying page views with page_type

page is vertical-neutral and fires on every page load, so on its own it says nothing about what kind of page was viewed. Several destinations model page views by type rather than as one undifferentiated event, and can only report properly when they know which.

Pass an optional page_type to classify it:

datafly.page({ page_type: 'content' })
ValueUse for
homepageThe site homepage
categoryA listing, category, or index page
productA product detail page
searchA search results page
contentAn article, post, guide, or other content item
thematicA themed or SEO landing page
otherAnything that doesn’t fit the above

Destinations that don’t model page types ignore it. Destinations that do fall back to their generic page type when it’s absent or unrecognised, so adding it can only improve fidelity, never break a working integration.

⚠️

Don’t send both a typed page and a separate page-view event for the same page load. On destinations whose page-view events are their page-type taxonomy, that counts the view twice with two conflicting types. Retail sites firing view_item and view_item_list should generally leave page unmapped for those destinations; non-retail sites should use typed page as their single page-view event.

Common events

These optional events apply across any vertical. They’re documented here so they map consistently across destinations.

Event IDDescriptionGA4Meta CAPI
generate_leadA lead / enquiry was submitted (form, demo, quote). Hash PII via identify().generate_leadLead
donation_madeA donation was completed (treated as a conversion).purchasePurchase
cta_clickedA call-to-action button was clicked.select_content(custom)
element_clickedA tracked UI element was clicked.select_content(custom)
error_occurredA client or checkout error occurred (diagnostic).(custom)(custom)
user_updatedA user updated their profile or account details.(custom)(custom)
consentA communications consent was granted or withdrawn (see below).(custom)(custom)

Fired when a user grants or withdraws consent for a communications channel or purpose: a newsletter opt-in, an SMS marketing checkbox, a preference-centre change, an unsubscribe.

datafly.track('consent', {
  consent_category: 'weekly_newsletter',        // your own category identifier
  consent_action: 'granted',                    // 'granted' | 'denied'
  consent_message: 'Send me weekly offers',     // what the user actually saw
  consent_valid_until: 'unlimited'              // optional; 'unlimited' or a timestamp
})
PropertyTypeRequiredDescription
consent_categorystringRequiredYour identifier for the thing being consented to. Must match the category defined in the destination.
consent_actionstringRequiredgranted or denied. Destination blueprints value-map this to vendor wording.
consent_messagestringOptionalVerbatim text the user reacted to. This is what makes the record defensible to a regulator.
consent_valid_untilstringOptionalunlimited, or when the consent expires.

The event timestamp is the moment consent was given, and destinations treat it as the consent’s valid_from. Fire this event on change only, never on every page load: repeating a grant floods the profile and destroys the audit trail’s meaning.

⚠️

This is not cookie consent, and the two must never be wired together. Cookie and tracking consent lives in context.consent.*, is collected by your CMP, and is what Signal uses to gate whether a destination receives data at all. This event is about permission to communicate with someone.

They are different permissions with different legal bases. Mapping a cookie-banner category onto a communications category means a visitor declining analytics cookies gets unsubscribed from your email programme. Some destinations treat a withdrawal as immediate and irreversible, so that mistake is not recoverable by resending.

Because this event carries a permission decision rather than behavioural data, destinations that accept it may receive it even where the cookie-consent gate would otherwise close, but only where an operator has explicitly configured that destination to accept consent from Signal. It is off by default everywhere.

Vertical specs

Choose the spec that matches your business model. You can mix events from multiple verticals — a subscription news site might use both Publishing and SaaS events.

Property conventions

All event properties use snake_case:

// Correct
datafly.track('purchase', {
  transaction_id: 'ORD-1234',
  value: 129.99,
  currency: 'GBP',
  items: [{ item_id: 'SKU-001', item_name: 'Trainers', price: 79.99, quantity: 1 }],
});
 
// Avoid
datafly.track('purchase', {
  transactionId: 'ORD-1234',   // camelCase — avoid
  Value: 129.99,               // PascalCase — avoid
});

Standard monetary properties:

PropertyTypeDescription
revenuenumberTotal revenue including tax and shipping
valuenumberConversion value (use when revenue doesn’t apply)
currencystringISO 4217 currency code (GBP, USD, EUR)
pricenumberUnit price
⚠️

Never include raw PII (email addresses, phone numbers, full names) in track() properties. Use datafly.identify() to attach user traits — Signal hashes PII server-side before delivering to vendors.