Flutter SDK
Log product telemetry from Flutter
Queue structured customer events with automatic runtime context, lifecycle flushes, and durable retry behavior.
Log a product event
Btx.log(...) queues a structured event for the active customer. It waits for
pending configure work, persists the entry, and flushes automatically without
blocking the app on network delivery.
await Btx.log(
'checkout_started',
level: BtxLogLevel.info,
message: 'Customer started checkout.',
properties: <String, Object?>{
'cartId': 'cart_123',
'itemCount': 3,
'subtotalUsd': 149.97,
'couponApplied': true,
},
);Keep events structured
Use a stable eventType, one of the info, warning, or error levels, a
concise message, and bounded properties. Pass occurredAt when the event time
differs from the enqueue time.
- Keep event names and property shapes stable between releases.
- Prefer product IDs and bounded values over free-form state dumps.
- Do not include passwords, access tokens, server credentials, or sensitive payloads.
- Use
Btx.flush(...)only for rare lifecycle or diagnostic waits; normal delivery is automatic.
Configure telemetry only
Apps that do not need customer-facing surfaces can enable only logs. Feature flag state still loads through the telemetry session for an identified customer.
await Btx.configure(
BtxConfiguration(
publishableClientKey: 'cfk_...',
features: const <BtxFeature>{BtxFeature.logs},
),
);Telemetry survives runtime recreation in a durable queue. Permanent key or app
context errors pause delivery and appear through Btx.status; temporary network,
rate-limit, and server failures retry with bounded backoff.
Use automatic runtime context
BTX automatically captures privacy-safe app, platform, operating-system, device-family or model, physical-device, and SDK version context. Android also captures API level and security patch when available.
The SDK intentionally excludes advertising identifiers, persistent phone IDs, serial numbers, user-assigned device names, storage readings, and memory readings. Metadata collection is best effort and never blocks configuration.
Use worker mode for telemetry only
Select worker mode when telemetry collection and delivery should run on a worker isolate. Customer messages, knowledge base UI, and push integration stay on the main isolate.
await Btx.configure(
BtxConfiguration(
publishableClientKey: 'cfk_...',
features: const <BtxFeature>{BtxFeature.logs},
telemetry: const BtxTelemetryConfiguration(
bindAppLifecycle: true,
runtimeMode: BtxTelemetryRuntimeMode.worker,
),
),
);