Event SpecsMedia & Streaming

Media & Streaming Event Spec

This page defines all standard events for media and streaming businesses on Datafly Signal — publishers, news sites, video-on-demand and live streaming platforms, and podcast players. It covers the full lifecycle: content discovery, engagement, video and audio playback, advertising, conversion (subscriptions and leads), and retention. Implement these events to enable accurate server-side delivery to advertising and analytics platforms.

💡

Where a media event overlaps with a standard GA4 recommended event (search, view_item, sign_up, login, purchase, generate_lead), this spec reuses the GA4 name so existing Google Tag Manager implementations work as-is. Media-specific events follow Segment’s video and content tracking specs, using snake_case throughout.

All events are sent via datafly.track(). Properties are passed as a flat object in the second argument.

⚠️

Never pass raw PII (email address, phone number, or full name) in track() properties. Identity is resolved server-side by Signal from first-party cookies. Pass opaque IDs such as content_id, author_id, or subscription_id only.


Content Discovery Events

These events describe how users find content — browsing feeds, searching, and filtering.

view_item_list

Fired when a user views a feed, category page, channel, or list of content items (articles, videos, podcasts).

datafly.track('view_item_list', {
  item_list_id: 'channel-technology',
  item_list_name: 'Technology',
  items: [
    { item_id: 'art-90213', item_name: 'The State of Server-Side Tracking', index: 0, content_type: 'article', author_id: 'auth-12' },
    { item_id: 'art-90218', item_name: 'Why First-Party Data Wins', index: 1, content_type: 'article', author_id: 'auth-07' }
  ]
})
PropertyTypeRequiredDescription
item_list_idstringOptionalMachine-readable identifier for the feed, channel, or category
item_list_namestringOptionalHuman-readable name of the list being browsed
itemsarrayOptionalArray of content items displayed in the list (see Items Array Schema)

select_item

Fired when a user clicks a content item within a feed, list, or search results to open it.

datafly.track('select_item', {
  item_list_id: 'channel-technology',
  item_list_name: 'Technology',
  items: [
    { item_id: 'art-90213', item_name: 'The State of Server-Side Tracking', index: 0, content_type: 'article' }
  ]
})
PropertyTypeRequiredDescription
item_list_idstringOptionalIdentifier of the list the item was selected from
item_list_namestringOptionalName of the list the item was selected from
itemsarrayOptionalArray containing the selected content item (see Items Array Schema)

Fired when a user submits a search query for content.

datafly.track('search', {
  search_term: 'first-party tracking',
  results_count: 42
})
PropertyTypeRequiredDescription
search_termstringRequiredThe search term entered by the user
results_countnumberOptionalNumber of results returned for the query

view_promotion

Fired when a promotional unit, content recommendation rail, or hero placement becomes visible to the user.

datafly.track('view_promotion', {
  promotion_id: 'rail-trending-now',
  promotion_name: 'Trending Now',
  creative_name: 'homepage-trending-rail',
  creative_slot: 'homepage-hero'
})
PropertyTypeRequiredDescription
promotion_idstringOptionalIdentifier for the promotion or recommendation rail
promotion_namestringOptionalHuman-readable name of the promotion
creative_namestringOptionalName or URL of the creative asset shown
creative_slotstringOptionalSlot or placement where the promotion appeared

select_promotion

Fired when a user clicks a promotional unit or recommendation.

datafly.track('select_promotion', {
  promotion_id: 'rail-trending-now',
  promotion_name: 'Trending Now',
  creative_name: 'homepage-trending-rail',
  creative_slot: 'homepage-hero'
})
PropertyTypeRequiredDescription
promotion_idstringOptionalIdentifier for the promotion or recommendation rail
promotion_namestringOptionalHuman-readable name of the promotion
creative_namestringOptionalName or URL of the creative asset shown
creative_slotstringOptionalSlot or placement where the promotion appeared

Content Engagement Events

These events describe how users engage with an individual piece of content — articles, videos, podcasts, galleries.

content_viewed

Fired when a user opens a piece of content (article page, video detail page, podcast episode page). This is the primary content-consumption signal. Also accepted as view_item.

datafly.track('content_viewed', {
  content_id: 'art-90213',
  content_type: 'article',
  content_title: 'The State of Server-Side Tracking',
  content_category: 'Technology',
  author_id: 'auth-12',
  publish_date: '2026-06-20',
  paywalled: false,
  word_count: 1840
})
PropertyTypeRequiredDescription
content_idstringRequiredUnique identifier for the content item
content_typestringOptionalType of content (e.g. article, video, podcast, gallery)
content_titlestringOptionalDisplay title of the content
content_categorystringOptionalSection, channel, or category the content belongs to
author_idstringOptionalIdentifier of the author or creator
publish_datestringOptionalPublication date (ISO 8601)
paywalledbooleanOptionalWhether the content sits behind a paywall
word_countnumberOptionalWord count (for text content)

content_scrolled

Fired when a user reaches a scroll-depth milestone within an article or page. Fire once each at 25%, 50%, 75%, and 100%.

datafly.track('content_scrolled', {
  content_id: 'art-90213',
  content_type: 'article',
  percent_scrolled: 50
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the content being read
content_typestringOptionalType of content
percent_scrollednumberOptionalScroll-depth milestone reached. One of: 25, 50, 75, 100

content_completed

Fired when a user finishes consuming a piece of content — reaching the end of an article or finishing a gallery.

datafly.track('content_completed', {
  content_id: 'art-90213',
  content_type: 'article',
  time_spent: 312
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the completed content
content_typestringOptionalType of content
time_spentnumberOptionalActive time spent on the content in seconds

content_shared

Fired when a user shares a content item to a social network, messaging app, or via a copied link.

datafly.track('content_shared', {
  content_id: 'art-90213',
  content_type: 'article',
  content_title: 'The State of Server-Side Tracking',
  share_method: 'twitter'
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the shared content
content_typestringOptionalType of content
content_titlestringOptionalDisplay title of the content
share_methodstringOptionalDestination of the share (e.g. twitter, facebook, whatsapp, email, copy_link)

content_liked

Fired when a user likes, upvotes, or reacts positively to a content item.

datafly.track('content_liked', {
  content_id: 'art-90213',
  content_type: 'article',
  content_title: 'The State of Server-Side Tracking'
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the liked content
content_typestringOptionalType of content
content_titlestringOptionalDisplay title of the content

content_saved

Fired when a user saves or bookmarks a content item to read or watch later.

datafly.track('content_saved', {
  content_id: 'art-90213',
  content_type: 'article',
  content_title: 'The State of Server-Side Tracking',
  list_name: 'Read Later'
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the saved content
content_typestringOptionalType of content
content_titlestringOptionalDisplay title of the content
list_namestringOptionalName of the list or collection the content was saved to

content_downloaded

Fired when a user downloads a content item for offline access — a PDF, an offline video, or a podcast episode.

datafly.track('content_downloaded', {
  content_id: 'pod-signal-ep-041',
  content_type: 'podcast',
  content_title: 'Server-Side Tracking in 2026',
  file_format: 'mp3'
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the downloaded content
content_typestringOptionalType of content
content_titlestringOptionalDisplay title of the content
file_formatstringOptionalFile format downloaded (e.g. mp3, mp4, pdf)

comment_posted

Fired when a user posts a comment on a content item.

datafly.track('comment_posted', {
  content_id: 'art-90213',
  content_type: 'article',
  comment_id: 'cmt-558210'
})
PropertyTypeRequiredDescription
content_idstringRequiredIdentifier of the content commented on
content_typestringOptionalType of content
comment_idstringOptionalIdentifier of the posted comment

Video Playback Events

These events describe the state of the media player. They are fired regardless of what content is loaded.

💡

This spec distinguishes between two categories of video event:

Playback events (video_playback_*) describe the state of the media player — play, pause, buffer, seek. They are fired regardless of what content is loaded.

Content events (video_content_*) describe the specific piece of content being watched — the show, film, or clip. A single playback session may contain multiple content items (e.g. a playlist or episode queue).

Use session_id to correlate all events within the same viewing session. Generate a new session_id each time the player loads, not each time a new video starts.

video_played

Fired when a user starts a video — a lightweight, high-level “play” signal suitable for advertising platforms that expect a single video-start event. For full session telemetry, also emit video_playback_started.

datafly.track('video_played', {
  session_id: 'vps-f3a9c2b1',
  content_id: 'ep-s2e4-breaking-ground',
  content_title: 'Breaking Ground — Season 2, Episode 4',
  content_type: 'video',
  total_length: 2740,
  livestream: false
})
PropertyTypeRequiredDescription
session_idstringRequiredUnique identifier for this playback session
content_idstringOptionalID of the content being played
content_titlestringOptionalDisplay title of the content
content_typestringOptionalType of content (e.g. video, clip, trailer)
total_lengthnumberOptionalTotal duration of the content in seconds
livestreambooleanOptionalWhether this is a live stream

video_playback_started

Fired when a user presses play and playback begins (or auto-play initiates). This is the first event in any detailed playback session.

datafly.track('video_playback_started', {
  session_id: 'vps-f3a9c2b1',
  content_asset_id: 'ep-s2e4-breaking-ground',
  position: 0,
  total_length: 2740,
  bitrate: 4500,
  quality: '1080p',
  fullscreen: false,
  sound: 80,
  livestream: false
})
PropertyTypeRequiredDescription
session_idstringRequiredUnique identifier for this playback session
content_asset_idstringOptionalID of the content item currently loaded
content_pod_idstringOptionalID of the content playlist or pod
ad_asset_idstringOptionalID of an ad playing at session start (pre-roll)
positionnumberOptionalPlayback position in seconds at start
total_lengthnumberOptionalTotal duration of the content in seconds
bitratenumberOptionalCurrent stream bitrate in kbps
qualitystringOptionalVideo quality label (e.g. 1080p, 720p, 480p, auto)
fullscreenbooleanOptionalWhether the player is in fullscreen mode
soundnumberOptionalVolume level at start, expressed as 0–100
livestreambooleanOptionalWhether this is a live stream

video_playback_paused

Fired when playback is paused by the user.

datafly.track('video_playback_paused', {
  session_id: 'vps-f3a9c2b1',
  position: 483,
  total_length: 2740
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
positionnumberOptionalPlayback position in seconds when paused
total_lengthnumberOptionalTotal duration of the content in seconds

video_playback_resumed

Fired when playback resumes after a pause.

datafly.track('video_playback_resumed', {
  session_id: 'vps-f3a9c2b1',
  position: 483,
  total_length: 2740
})

Accepts the same properties as video_playback_paused.


video_playback_completed

Fired when the player reaches the end of the content and playback stops naturally.

datafly.track('video_playback_completed', {
  session_id: 'vps-f3a9c2b1',
  total_length: 2740
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
total_lengthnumberOptionalTotal duration of the content in seconds

video_playback_buffer_started

Fired when playback stalls and the player enters a buffering state.

datafly.track('video_playback_buffer_started', {
  session_id: 'vps-f3a9c2b1',
  position: 721
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
positionnumberOptionalPlayback position in seconds when buffering began

video_playback_buffer_completed

Fired when buffering ends and playback resumes.

datafly.track('video_playback_buffer_completed', {
  session_id: 'vps-f3a9c2b1',
  position: 721
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
positionnumberOptionalPlayback position in seconds when buffering ended

video_playback_seek_started

Fired when the user begins scrubbing or seeking to a new position in the timeline.

datafly.track('video_playback_seek_started', {
  session_id: 'vps-f3a9c2b1',
  seek_position: 1200
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
seek_positionnumberRequiredTarget position in seconds the user is seeking to

video_playback_seek_completed

Fired when the seek operation completes and playback resumes at the new position.

datafly.track('video_playback_seek_completed', {
  session_id: 'vps-f3a9c2b1',
  seek_position: 1200
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
seek_positionnumberOptionalPosition in seconds where playback resumed

Video Content Events

These events describe the specific content item being played within a session.

video_content_started

Fired when a content item begins playing. In a playlist, fire this for each new item as it starts.

datafly.track('video_content_started', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ep-s2e4-breaking-ground',
  title: 'Breaking Ground — Season 2, Episode 4',
  description: 'The team discovers an unexpected obstacle beneath the foundation.',
  keywords: ['construction', 'documentary', 'engineering'],
  season: '2',
  episode: '4',
  genre: 'Documentary',
  programme: 'Breaking Ground',
  publisher: 'Northfield Studios',
  channel: 'Documentary',
  livestream: false,
  airdate: '2026-01-14',
  total_length: 2740,
  position: 0
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalUnique identifier for this content item
titlestringOptionalDisplay title of the content
descriptionstringOptionalShort description or synopsis
keywordsstring[]OptionalTopic or genre keywords
seasonstringOptionalSeason number (for episodic content)
episodestringOptionalEpisode number (for episodic content)
genrestringOptionalGenre classification
programmestringOptionalParent show or series name
publisherstringOptionalProduction company or content owner
channelstringOptionalChannel or category within the platform
livestreambooleanOptionalWhether this is live content
airdatestringOptionalOriginal broadcast or release date (ISO 8601)
total_lengthnumberOptionalTotal duration of the content in seconds
positionnumberOptionalPosition in seconds where the content started playing

video_content_completed

Fired when a content item finishes playing. For playlists, this fires before video_content_started fires for the next item.

datafly.track('video_content_completed', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ep-s2e4-breaking-ground',
  total_length: 2740
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalUnique identifier for the completed content item
total_lengthnumberOptionalTotal duration of the content in seconds

video_content_milestone

Fired when a user reaches a watch percentage milestone. Fire once each at 25%, 50%, and 75% completion. Do not fire at 100% — use video_content_completed instead.

datafly.track('video_content_milestone', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ep-s2e4-breaking-ground',
  position: 685,
  milestone: 25
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalIdentifier of the content item
positionnumberOptionalPlayback position in seconds at the milestone
milestonenumberOptionalMilestone reached. One of: 25, 50, 75
💡

Milestone events are useful for measuring engaged viewing. Use them in pipeline transformations to send custom audience signals — for example, sending users who reach the 75% milestone to a retargeting list.


Advertising Events

These events track ad impressions and interactions within the player and across the page.

ad_impression

Fired when an ad becomes viewable to the user — whether a video ad in the player or a display unit on the page. This is the canonical monetisation signal for publishers.

datafly.track('ad_impression', {
  ad_unit_id: 'homepage-leaderboard',
  ad_format: 'display',
  placement: 'above-the-fold',
  campaign_id: 'cmp-northedge-summer',
  value: 0.012,
  currency: 'GBP'
})
PropertyTypeRequiredDescription
ad_unit_idstringRequiredIdentifier of the ad unit or placement
ad_formatstringOptionalAd format (e.g. display, video, native, audio)
placementstringOptionalPlacement description (e.g. above-the-fold, in-feed, pre-roll)
campaign_idstringOptionalIdentifier of the advertising campaign
valuenumberOptionalEstimated revenue for the impression
currencystringOptionalISO 4217 currency code

ad_clicked

Fired when a user clicks an ad.

datafly.track('ad_clicked', {
  ad_unit_id: 'homepage-leaderboard',
  ad_format: 'display',
  campaign_id: 'cmp-northedge-summer'
})
PropertyTypeRequiredDescription
ad_unit_idstringRequiredIdentifier of the ad unit clicked
ad_formatstringOptionalAd format (e.g. display, video, native, audio)
campaign_idstringOptionalIdentifier of the advertising campaign

video_ad_started

Fired when an ad begins playing within the player.

datafly.track('video_ad_started', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ad-northedge-brand-001',
  pod_id: 'pod-preroll-01',
  type: 'pre-roll',
  title: 'NorthEdge — Summer Collection',
  publisher: 'NorthEdge',
  total_length: 30,
  position: 0,
  load_type: 'linear'
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalUnique identifier for the ad creative
pod_idstringOptionalIdentifier for the ad break (pod) this ad belongs to
typestringOptionalAd placement type. One of: pre-roll, mid-roll, post-roll
titlestringOptionalAd title or campaign name
publisherstringOptionalAdvertiser or publisher serving the ad
total_lengthnumberOptionalDuration of the ad in seconds
positionnumberOptionalPlayback position within the content when the ad started
load_typestringOptionalAd serving method. One of: linear (standard), dynamic (DAI)

video_ad_completed

Fired when an ad plays through to completion without being skipped.

datafly.track('video_ad_completed', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ad-northedge-brand-001',
  pod_id: 'pod-preroll-01'
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalIdentifier for the completed ad
pod_idstringOptionalIdentifier for the ad break

video_ad_skipped

Fired when a user skips a skippable ad before it completes.

datafly.track('video_ad_skipped', {
  session_id: 'vps-f3a9c2b1',
  asset_id: 'ad-northedge-brand-001',
  position: 6
})
PropertyTypeRequiredDescription
session_idstringRequiredPlayback session identifier
asset_idstringOptionalIdentifier for the skipped ad
positionnumberOptionalPosition in seconds within the ad at the point of skip

Audio Events

audio_playback_started

Fired when audio playback begins — for music tracks, podcast episodes, or audio articles.

datafly.track('audio_playback_started', {
  session_id: 'aps-9b3f21a0',
  asset_id: 'pod-signal-ep-041',
  title: 'Server-Side Tracking in 2026',
  artist: 'The Datafly Podcast',
  album: 'Season 3',
  genre: 'Technology',
  duration: 3180,
  position: 0
})
PropertyTypeRequiredDescription
session_idstringRequiredUnique identifier for this audio playback session
asset_idstringOptionalUnique identifier for the audio asset
titlestringOptionalTrack or episode title
artiststringOptionalArtist, host, or creator name
albumstringOptionalAlbum, show, or series name
genrestringOptionalGenre classification
durationnumberOptionalTotal duration of the audio asset in seconds
positionnumberOptionalPlayback position in seconds at start

audio_playback_paused

Fired when audio playback is paused.

datafly.track('audio_playback_paused', {
  session_id: 'aps-9b3f21a0',
  position: 940
})
PropertyTypeRequiredDescription
session_idstringRequiredAudio playback session identifier
positionnumberOptionalPlayback position in seconds when paused

audio_playback_completed

Fired when an audio asset plays through to the end.

datafly.track('audio_playback_completed', {
  session_id: 'aps-9b3f21a0',
  asset_id: 'pod-signal-ep-041',
  duration: 3180
})
PropertyTypeRequiredDescription
session_idstringRequiredAudio playback session identifier
asset_idstringOptionalIdentifier for the completed audio asset
durationnumberOptionalTotal duration of the audio asset in seconds

podcast_subscribed

Fired when a user subscribes to a podcast show within the platform.

datafly.track('podcast_subscribed', {
  show_id: 'show-datafly-podcast',
  show_title: 'The Datafly Podcast'
})
PropertyTypeRequiredDescription
show_idstringRequiredUnique identifier for the podcast show
show_titlestringOptionalDisplay title of the podcast show

Conversion Events

These events capture the actions that turn an anonymous reader or viewer into a registered, subscribed, or monetised user. They are the highest-value signals to deliver server-side to advertising platforms.

sign_up

Fired when a user completes account registration.

datafly.track('sign_up', {
  method: 'email'
})
PropertyTypeRequiredDescription
methodstringOptionalRegistration method (e.g. email, google, apple)

login

Fired when a user signs in to their account.

datafly.track('login', {
  method: 'email'
})
PropertyTypeRequiredDescription
methodstringOptionalLogin method (e.g. email, google, apple)

generate_lead

Fired when a user submits a lead-generating form — a newsletter signup, gated content request, or content-download form.

datafly.track('generate_lead', {
  lead_type: 'newsletter',
  newsletter_id: 'weekly-briefing',
  value: 2.50,
  currency: 'GBP'
})
PropertyTypeRequiredDescription
lead_typestringOptionalType of lead captured (e.g. newsletter, gated_content, webinar)
newsletter_idstringOptionalIdentifier of the newsletter or list subscribed to
valuenumberOptionalEstimated value of the lead
currencystringOptionalISO 4217 currency code

view_item

Fired when a user views a subscription, membership, or paywall offer page. Reuses the GA4 view_item name so paywall offers map cleanly to vendor ViewContent events.

datafly.track('view_item', {
  currency: 'GBP',
  value: 9.99,
  items: [
    { item_id: 'plan-premium-monthly', item_name: 'Premium Monthly', item_category: 'subscription', price: 9.99 }
  ]
})
PropertyTypeRequiredDescription
currencystringOptionalISO 4217 currency code
valuenumberOptionalPrice of the offer viewed
itemsarrayOptionalArray containing the subscription or membership offer (see Items Array Schema)

begin_checkout

Fired when a user starts the subscription or membership purchase flow.

datafly.track('begin_checkout', {
  currency: 'GBP',
  value: 9.99,
  coupon: 'FIRST3FREE',
  items: [
    { item_id: 'plan-premium-monthly', item_name: 'Premium Monthly', item_category: 'subscription', price: 9.99 }
  ]
})
PropertyTypeRequiredDescription
currencystringOptionalISO 4217 currency code
valuenumberOptionalValue of the subscription being purchased
couponstringOptionalPromotion or coupon code applied
itemsarrayOptionalSubscription or membership offer in the checkout (see Items Array Schema)

purchase

Fired when a user completes a subscription purchase, membership upgrade, or one-off content payment. This is the most important conversion event — ensure it fires reliably.

datafly.track('purchase', {
  transaction_id: 'SUB-10042',
  value: 9.99,
  currency: 'GBP',
  coupon: 'FIRST3FREE',
  items: [
    { item_id: 'plan-premium-monthly', item_name: 'Premium Monthly', item_category: 'subscription', price: 9.99, quantity: 1 }
  ]
})
PropertyTypeRequiredDescription
transaction_idstringRequiredUnique transaction identifier — used for deduplication
valuenumberOptionalTotal amount charged
currencystringOptionalISO 4217 currency code
couponstringOptionalPromotion or coupon code applied
itemsarrayOptionalSubscription or content items purchased (see Items Array Schema)
⚠️

Always send transaction_id on purchase events for deduplication. Platforms like Meta CAPI and GA4 use the transaction ID to prevent double-counting alongside browser-side events.


Retention Events

These events describe subscription lifecycle changes after the initial purchase — the core retention signals for a subscription media business.

subscription_renewed

Fired when a subscription successfully renews for another billing period.

datafly.track('subscription_renewed', {
  subscription_id: 'sub-10042',
  plan_id: 'plan-premium-monthly',
  value: 9.99,
  currency: 'GBP',
  renewal_count: 4
})
PropertyTypeRequiredDescription
subscription_idstringRequiredIdentifier of the subscription
plan_idstringOptionalIdentifier of the plan or tier
valuenumberOptionalAmount charged for the renewal
currencystringOptionalISO 4217 currency code
renewal_countnumberOptionalNumber of renewals to date

subscription_cancelled

Fired when a user cancels their subscription.

datafly.track('subscription_cancelled', {
  subscription_id: 'sub-10042',
  plan_id: 'plan-premium-monthly',
  reason: 'too_expensive'
})
PropertyTypeRequiredDescription
subscription_idstringRequiredIdentifier of the cancelled subscription
plan_idstringOptionalIdentifier of the plan or tier
reasonstringOptionalCancellation reason code (e.g. too_expensive, not_using, switching)

Items Array Schema

💡

Several events accept an items array — used for content lists and subscription offers. Each object in the array can include the following properties. The items[] array uses GA4-style field names. Signal’s server-side blueprints automatically transform these to vendor-specific formats (e.g., Meta’s contents[] with id/title fields).

PropertyTypeDescription
item_idstringContent ID, SKU, or subscription plan ID
item_namestringDisplay name of the content item or offer
item_categorystringSection, channel, or offer category (e.g. article, subscription)
content_typestringType of content (e.g. article, video, podcast)
author_idstringIdentifier of the author or creator
pricenumberPrice of the offer (for subscription/membership items)
quantitynumberNumber of units (relevant for subscription quantity)
indexnumberPosition in list (0-indexed, relevant in list/search contexts)
currencystringISO 4217 currency code
couponstringItem-level coupon or promotion code if applicable
item_list_idstringIdentifier of the list the item was shown in
item_list_namestringName of the list the item was shown in

Vendor Mapping

The table below shows how Datafly Signal maps media events to the native event names expected by each vendor’s server-side API. Signal uses the GA4-style event names as its canonical format, and blueprints handle the transformation to vendor-specific payloads. (custom) indicates the vendor has no native equivalent, so Signal delivers a custom event of the same name.

Signal EventGA4Meta CAPITikTok Events API
view_item_listview_item_listViewContentViewContent
select_itemselect_itemViewContentClickButton
searchsearchSearchSearch
view_promotionview_promotion(custom)(custom)
select_promotionselect_promotion(custom)(custom)
content_viewedview_itemViewContentViewContent
content_scrolledscroll(custom)(custom)
content_completed(custom)ViewContent(custom)
content_sharedshare(custom)Share
content_liked(custom)(custom)(custom)
content_savedadd_to_wishlistAddToWishlistAddToWishlist
content_downloaded(custom)(custom)Download
comment_posted(custom)(custom)(custom)
video_playedvideo_startViewContentViewContent
video_playback_startedvideo_startViewContentViewContent
video_playback_paused(custom)(custom)(custom)
video_playback_resumed(custom)(custom)(custom)
video_playback_completedvideo_complete(custom)(custom)
video_playback_buffer_started(custom)(custom)(custom)
video_playback_buffer_completed(custom)(custom)(custom)
video_playback_seek_started(custom)(custom)(custom)
video_playback_seek_completed(custom)(custom)(custom)
video_content_startedvideo_startViewContentViewContent
video_content_completedvideo_complete(custom)(custom)
video_content_milestonevideo_progress(custom)(custom)
ad_impressionad_impression(custom)(custom)
ad_clickedselect_content(custom)ClickButton
video_ad_startedad_impression(custom)(custom)
video_ad_completed(custom)(custom)(custom)
video_ad_skipped(custom)(custom)(custom)
audio_playback_startedvideo_startViewContentViewContent
audio_playback_paused(custom)(custom)(custom)
audio_playback_completedvideo_complete(custom)(custom)
podcast_subscribedsign_upSubscribeSubscribe
sign_upsign_upCompleteRegistrationCompleteRegistration
loginlogin(custom)(custom)
generate_leadgenerate_leadLeadSubmitForm
view_itemview_itemViewContentViewContent
begin_checkoutbegin_checkoutInitiateCheckoutInitiateCheckout
purchasepurchaseSubscribeSubscribe
subscription_renewed(custom)SubscribeSubscribe
subscription_cancelled(custom)(custom)(custom)