Skip to content

Flutter SDK

Capture events from Flutter apps with azfive_capture — identity, sessions, feature flags, surveys and opt-in session replay.

azfive_capture brings AZ-Five product analytics to Flutter: events, identity, sessions, persistence, feature flags & experiments, surveys, and opt-in session replay. Dart 3; a single dependency (shared_preferences, plus image for replay JPEG encoding), under the shared behavioral spec.

Install

flutter pub add azfive_capture

Create a public ingest token with “Mobile app token” enabled (Settings → API Keys) — native requests carry no browser Origin, and tokens without that flag fail closed.

Initialize

final azfive = await AzFive.init('azfive_pub_…',
    const AzFiveConfig(host: 'https://app.az-five.com'));

AzFive.init is async: it hydrates shared_preferences persistence before returning, so identity and cached flags survive restarts. After init, the static facade (AzFive.capture(…), AzFive.getFlag(…)) mirrors the instance API.

Capture events

azfive.capture('signed_up', {'plan': 'pro'});
azfive.screen('Checkout');   // az.screen_view + survey eligibility re-check

// Super properties — merged into every event
azfive.register({'deployment': 'eu-1'});
azfive.registerOnce({'first_touch': 'ad-campaign'});
azfive.unregister('deployment');

Automatic screen tracking (which also drives survey eligibility) comes from the bundled navigator observer:

MaterialApp(navigatorObservers: [AzFiveNavigatorObserver(azfive)], …)

Identify & person properties

azfive.identify('ava@example.com', set: {'plan': 'pro'});
azfive.alias('legacy-77');
azfive.peopleSet({'favorite_color': 'teal'});
azfive.peopleSetOnce({'signup_date': '2026-08-01'});

// on logout:
azfive.reset();   // new anonymous id; reset(resetDeviceId: true) also rotates the device id

identify merges the anonymous session into the person (az.identify with $anonymous_id) and refetches flags; calling it again with the same id only updates properties. Opt-out controls — optInCapturing() / optOutCapturing() — drop events at capture time, persist, and survive reset().

Feature flags

Flags load from /v1/decide on init, persist for stale-while-revalidate startup, and refetch on identify / reset:

final unsubscribe = azfive.onFlags((flags) {
  final variant = azfive.getFlag('exp-checkout');   // true | false | 'variant' | null
  if (azfive.isFlagEnabled('new-billing')) {
    final payload = azfive.getFlagPayload('new-billing');  // no exposure event
  }
});
await azfive.reloadFlags();   // force a refetch

getFlag and isFlagEnabled capture an az.flag_called exposure automatically, deduped per session:flag:value. getFlagPayload never does.

Surveys

Mount the survey host once, above your app:

AzFiveSurveyHost(coordinator: azfive.surveys, child: const MyApp())

Survey selection reacts to screen() changes; responses ship as az.survey_shown / az.survey_dismissed / az.survey_sent events, and suppression persists per survey.

Session replay (opt-in, default off)

Set enableSessionRecording: true, enable recording server-side, and mount an AzFiveReplayBoundary at your root. Capture is ~1 fps masked JPEG frames plus touches; masking is best-effort — review your screens before enabling in production.

Flush & shutdown

Delivery is automatic (10 events / 5 s), and the queue flushes when the app backgrounds. flush() forces delivery and returns a Future; dispose() tears the client down:

await azfive.flush();

Reference

AzFiveConfig

ParameterDefaultNotes
hostrequiredAZ-Five deployment base URL
project'default'Target project slug
batchSize10Queue length that triggers a flush
flushIntervalDuration(seconds: 5)Background flush period
maxQueueSize1000Queue bound; oldest events dropped on overflow
gzipfalseContent-Encoding: gzip on event POSTs
optOutfalseStart opted out (persisted opt-out wins)
disableDecidefalseSkip flags/surveys/recording bootstrap
enableSessionRecordingfalseSession replay opt-in; recording still requires the server to enable it
sessionIdleTimeoutDuration(minutes: 30)Session rotation on inactivity
storageSharedPreferencesStoreCustom Store persistence backend
platformPropsauto-detectedOverride the computed static platform properties

API

capture · screen · identify · alias · reset · getDistinctId · getSessionId · register / registerOnce / unregister · peopleSet / peopleSetOnce · optInCapturing / optOutCapturing · getFlag / isFlagEnabled / getFlagPayload / onFlags / reloadFlags · flush · dispose.

Behavior notes

  • Sessions rotate after 30 minutes idle or 24 hours total; $session_id is stamped on every event.
  • Failed batches — 429 included — re-queue at the front and retry next flush; the public API never throws for delivery or flag problems.
  • Custom event names: anything except the reserved az. prefix, ≤ 200 characters; properties ≤ 64 KiB serialized.