Event SpecsPublishing

Publishing & Editorial Event Spec

This page defines standard events for news sites, blogs, magazines, and content publishers. These events cover content consumption, search, newsletter subscriptions, paywall interactions, and reader engagement.

All events are sent via _df.track(). Properties listed here are sent inside the properties object.


Content Browsing Events

article_viewed

Fired when a user loads an article or content page. Send this as soon as the page renders, regardless of scroll depth.

_df.track('article_viewed', {
  article_id: 'art-20260311-001',
  title: 'The Future of Server-Side Tracking',
  author: 'Jane Holloway',
  category: 'Technology',
  tags: ['tracking', 'privacy', 'adtech'],
  published_at: '2026-03-11T09:00:00Z',
  word_count: 1840,
  paywall: false
})
PropertyTypeRequiredDescription
article_idstringRequiredUnique identifier for the article
titlestringOptionalArticle headline
authorstringOptionalAuthor name or byline
categorystringOptionalPrimary section or category (e.g. Technology, Sport)
tagsstring[]OptionalArray of topic tags associated with the article
published_atstringOptionalISO 8601 publication date (e.g. 2026-03-11T09:00:00Z)
word_countnumberOptionalTotal word count of the article body
paywallbooleanOptionalWhether the article is behind a paywall or content gate

article_read

Fired once when a user has scrolled to at least 80% of the article. Fire this event a maximum of once per article per session.

_df.track('article_read', {
  article_id: 'art-20260311-001',
  title: 'The Future of Server-Side Tracking',
  read_time_seconds: 312,
  scroll_depth: 87
})
PropertyTypeRequiredDescription
article_idstringRequiredUnique identifier for the article
titlestringOptionalArticle headline
read_time_secondsnumberOptionalTime in seconds from article_viewed to reaching the read threshold
scroll_depthnumberOptionalMaximum scroll depth reached, expressed as a percentage (0–100)
💡

Use article_read (not article_viewed) as the signal for engaged reads when optimising campaigns. A user who scrolls to 80% is a meaningfully different signal from a page bounce.


article_shared

Fired when a user shares an article via a share button or copy-link action.

_df.track('article_shared', {
  article_id: 'art-20260311-001',
  share_method: 'twitter'
})
PropertyTypeRequiredDescription
article_idstringRequiredUnique identifier for the article being shared
share_methodstringOptionalShare channel. One of: twitter, facebook, email, copy_link

article_bookmarked

Fired when a user saves an article to their bookmarks or reading list.

_df.track('article_bookmarked', {
  article_id: 'art-20260311-001',
  title: 'The Future of Server-Side Tracking'
})
PropertyTypeRequiredDescription
article_idstringRequiredUnique identifier for the bookmarked article
titlestringOptionalArticle headline

category_viewed

Fired when a user browses a section, topic, or category listing page.

_df.track('category_viewed', {
  category: 'Technology',
  page: 2
})
PropertyTypeRequiredDescription
categorystringRequiredSection or category name
pagenumberOptionalPagination page number (1-indexed). Omit or set to 1 for the first page.

Search Events

search_performed

Fired when a user submits a search query on the site.

_df.track('search_performed', {
  query: 'climate policy',
  results_count: 47,
  filters: {
    date_range: 'last_30_days',
    category: 'Environment'
  }
})
PropertyTypeRequiredDescription
querystringRequiredThe search term entered by the user
results_countnumberOptionalNumber of results returned for the query
filtersobjectOptionalKey-value map of any filters applied to the search

Newsletter Events

newsletter_subscribed

Fired when a user successfully subscribes to a newsletter or mailing list.

_df.track('newsletter_subscribed', {
  list_id: 'daily-briefing',
  email_hash: 'b4c9a...f1e2',
  source: 'article'
})
PropertyTypeRequiredDescription
list_idstringOptionalIdentifier of the newsletter or list subscribed to
email_hashstringOptionalSHA-256 hash of the subscriber’s email address. Never send raw email addresses in event properties.
sourcestringOptionalWhere the subscription was triggered. One of: inline, popup, footer, article
⚠️

Never pass a raw email address in event properties. Always hash with SHA-256 (lowercase, trimmed) before sending. This hashed value can be used by Meta CAPI and other platforms for identity matching.


newsletter_unsubscribed

Fired when a user unsubscribes from a newsletter or mailing list.

_df.track('newsletter_unsubscribed', {
  list_id: 'daily-briefing',
  reason: 'too_frequent'
})
PropertyTypeRequiredDescription
list_idstringOptionalIdentifier of the newsletter or list unsubscribed from
reasonstringOptionalReason provided by the user for unsubscribing

Paywall & Subscription Events

paywall_viewed

Fired when a user encounters a content gate or paywall prompt, whether inline (content cut-off) or as a modal overlay.

_df.track('paywall_viewed', {
  article_id: 'art-20260311-044',
  subscription_type: 'digital',
  position: 'modal'
})
PropertyTypeRequiredDescription
article_idstringRequiredArticle that triggered the paywall
subscription_typestringOptionalSubscription tier or product required to access the content
positionstringOptionalHow the gate was presented. One of: inline, modal

subscription_started

Fired when a user successfully starts a subscription (paid or trial).

_df.track('subscription_started', {
  plan_id: 'digital-monthly',
  plan_name: 'Digital Monthly',
  revenue: 9.99,
  currency: 'GBP',
  trial: false
})
PropertyTypeRequiredDescription
plan_idstringOptionalMachine-readable plan identifier
plan_namestringOptionalHuman-readable plan name
revenuenumberOptionalSubscription price charged at start
currencystringOptionalISO 4217 currency code
trialbooleanOptionalWhether this is the start of a free trial

subscription_cancelled

Fired when a user cancels their subscription.

_df.track('subscription_cancelled', {
  plan_id: 'digital-monthly',
  reason: 'too_expensive'
})
PropertyTypeRequiredDescription
plan_idstringOptionalIdentifier of the cancelled plan
reasonstringOptionalCancellation reason provided by the user

Engagement Events

comment_posted

Fired when a user successfully submits a comment on an article.

_df.track('comment_posted', {
  article_id: 'art-20260311-001',
  comment_id: 'cmt-77241',
  reply_to: 'cmt-77190'
})
PropertyTypeRequiredDescription
article_idstringRequiredArticle the comment was posted on
comment_idstringOptionalUnique identifier for the new comment
reply_tostringOptionalcomment_id of the parent comment, if this is a reply

author_followed

Fired when a user follows or subscribes to updates from an author.

_df.track('author_followed', {
  author_id: 'author-jane-holloway',
  author_name: 'Jane Holloway'
})
PropertyTypeRequiredDescription
author_idstringRequiredUnique identifier for the author
author_namestringOptionalDisplay name of the author