Skip to content

Privacy and Tracking#

The eventTrackingOptions parameter customizes Storyteller's analytics and tracking behavior. It allows certain features to be disabled based on user privacy choices. It is an object of type EventTrackingOptions and by default, all of its properties are enabled.

Important: eventTrackingOptions can only be set during SDK initialization. To configure tracking options, pass an EventTrackingOptions object to the initialize method:

// Using custom tracking options
final trackingOptions = EventTrackingOptions(
  enablePersonalization: false,
  enableStorytellerTracking: false,
  enableUserActivityTracking: false,
  enableAdTracking: false,
  enableFullVideoAnalytics: false,
  enableRemoteViewingStore: false,
  disabledFeatures: [], // empty list means no features disabled
);

final result = await Storyteller.initialize(
  'your-api-key',
  externalId: 'user-id',
  eventTrackingOptions: trackingOptions,
);

// Or use the defaults (all tracking enabled)
final result = await Storyteller.initialize(
  'your-api-key',
  externalId: 'user-id',
);

The options remain publicly readable via Storyteller.eventTrackingOptions(), but cannot be modified at runtime. To change tracking options after initialization, you must reinitialize the SDK with new options.

Example: Reading Current Tracking Options

final options = await Storyteller.eventTrackingOptions();
print('Personalization enabled: ${options.enablePersonalization}');
print('Ad tracking enabled: ${options.enableAdTracking}');
print('Disabled features: ${options.disabledFeatures}');

User Personalization#

When enablePersonalization is enabled, user attributes and the user's ID are included on requests to Storyteller's servers to allow us to personalize the content returned.

Example:

final trackingOptions = EventTrackingOptions(
  enablePersonalization: true, // Enable personalized content
);

await Storyteller.initialize(
  'your-api-key',
  externalId: 'user-123',
  eventTrackingOptions: trackingOptions,
);

Storyteller Tracking#

When enableStorytellerTracking is enabled, we will record analytics events on our servers. Note that some events are necessary for user functionality and will still be transmitted (but not stored) even when this setting is off.

Example:

final trackingOptions = EventTrackingOptions(
  enableStorytellerTracking: false, // Disable server-side analytics
);

User Activity Tracking#

When enableUserActivityTracking is enabled, the SDK will emit events through the onUserActivityOccurred stream, which allows integrating apps to record our analytics events on their own systems.

Example:

final trackingOptions = EventTrackingOptions(
  enableUserActivityTracking: true, // Enable client-side analytics events
);

await Storyteller.initialize(
  'your-api-key',
  eventTrackingOptions: trackingOptions,
);

// Listen to analytics events
Storyteller.onUserActivityOccurred.listen((event) {
  print('Event: ${event.type}');
  // Forward to your analytics system
});

Ads Tracking#

When enableAdTracking is disabled, ad-related events will not be tracked through the onUserActivityOccurred stream and on our servers. Additionally, only necessary fields like Ad Unit Id and Custom Template Id's will be included in GAM requests.

Example:

final trackingOptions = EventTrackingOptions(
  enableAdTracking: false, // Disable ad tracking
);

Videos Tracking#

When enableFullVideoAnalytics is disabled, sensitive video event data for Story ID, Page ID, Story Title, Page Title, Clip ID, Clip Title, Story Display Title, Item Title, Container Title, Card Id, Card Title and Card Subtitle will not be included in the onUserActivityOccurred stream events.

Example:

final trackingOptions = EventTrackingOptions(
  enableFullVideoAnalytics: false, // Exclude sensitive video metadata
);

Remote Viewing Store#

When enableRemoteViewingStore is disabled, user IDs are never stored or sent to backend services, and all user viewing activity is only kept locally on the device. This mode ensures the SDK operates in a privacy-enhanced mode designed to address VPPA (Video Privacy Protection Act) compliance concerns.

Example:

final trackingOptions = EventTrackingOptions(
  enableRemoteViewingStore: false, // Keep viewing data local only
);

Independent Functional Behavior Toggles#

The disabledFeatures property allows you to conditionally disable functional features of the SDK for privacy compliance. When a feature is disabled, the SDK will behave as if that functionality is disabled from the server.

Available features to disable:

  • 'pageReadStatus'
  • 'clipViewedStatus'
  • 'pollVotes'
  • 'triviaQuizAnswers'
  • 'clipLikes'
  • 'clipShares'

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['clipLikes', 'clipShares', 'pollVotes'],
);

pageReadStatus#

Summary: Controls whether read/unread status is enabled for Story pages.

When disabled, the SDK will not store read/unread behavior for pages. All Lists and Players will act as if read/unread tracking is disabled from the server, meaning users will not see visual indicators of which Stories they have previously viewed.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['pageReadStatus'],
);

clipViewedStatus#

Summary: Controls whether viewed/not viewed status is enabled for individual Clips.

When disabled, the SDK will not store viewed/not viewed information for Clips. All Lists and Players will act as if viewed/not viewed tracking is disabled from the server, removing visual indicators of previously watched content.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['clipViewedStatus'],
);

pollVotes#

Summary: Controls whether Poll voting responses are persistently stored.

When disabled, users can still interact with Polls and see immediate UI updates when they vote, but their votes are not persistently stored. If they navigate away and return to the same Poll, they can vote again. Since this is coupled with disabled Storyteller Analytics, their votes will not contribute to overall Poll statistics.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['pollVotes'],
);

triviaQuizAnswers#

Summary: Controls whether Trivia Quiz responses and progress are persistently stored.

When disabled, users can still answer trivia questions and see immediate UI feedback, but their answers are not persistently stored. If they navigate away and return to the same Quiz, they can answer questions again. The results page will be hidden since the SDK is not allowed to display persistent Quiz results.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['triviaQuizAnswers'],
);

clipLikes#

Summary: Controls whether Clip like/unlike interactions are persistently stored.

When disabled, users can still tap to like/unlike Clips and see immediate UI updates, but these interactions are not persistently stored. If they swipe away and return to the same Clip, it will appear in its original unliked state.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['clipLikes'],
);

clipShares#

Summary: Disables Clip Share tracking and storage (but not the sharing action itself).

When disabled, users can still tap on Share Clip button and see immediate UI updates, but this interaction is not persistently stored. If they swipe away and returns to the same Clip, the original share count will be displayed.

Example:

final trackingOptions = EventTrackingOptions(
  disabledFeatures: ['clipShares'],
);