Flutter
Install the Flutter SDK, register installs, track events, and read attribution. Setup takes about 5 minutes.
Requirements
- Flutter 3.22+
- Dart 3.3+
- iOS 14.0+ and Android 7.0+ (API 24+)
Install
pub.dev
# pubspec.yamldependencies:appsprint_flutter: ^1.1.7# Then run:flutter pub get
The Flutter plugin manages the iOS pod and the Android AAR for you. No extra repository setup needed.
Published on pub.dev. Always use the latest version.
Configure
import 'package:flutter/material.dart';import 'package:appsprint_flutter/appsprint_flutter.dart';Future<void> main() async {WidgetsFlutterBinding.ensureInitialized();await AppSprint.instance.configure(const AppSprintConfig(apiKey: 'as_live_xxxxx'),);runApp(const MyApp());}
Non-blocking. configure() resolves after local state is restored; install registration runs in the background on the native side. Platform-specific code (AdServices on iOS, Play Install Referrer on Android) runs through method channels.
Track events
// Standard eventawait AppSprint.instance.sendEvent(AppSprintEventType.login);
// Revenue event. Currency must be a 3-letter ISO code.await AppSprint.instance.sendEvent(AppSprintEventType.purchase,params: {'revenue': 9.99, 'currency': 'USD'},);
// Custom event with parametersawait AppSprint.instance.sendEvent(AppSprintEventType.custom,name: 'level_complete',params: {'level': 5, 'score': 1200},);
Read attribution
Once install registration completes, the SDK caches the attribution result from the install response. Native iOS and Android expose synchronous getters; React Native and Flutter bridge calls are asynchronous.
final attr = await AppSprint.instance.getAttribution();print(attr?.source); // "apple_ads", "tracking_link", or "organic"print(attr?.isAttributed); // boolprint(attr?.campaignName); // Campaign name when availableprint(attr?.appleAds?.campaignId);print(attr?.link?.name);
Verify the connection
Send a test event to confirm end-to-end delivery. You should see it in the AppSprint dashboard within seconds.
final result = await AppSprint.instance.sendTestEvent();print('${result.success} — ${result.message}');
Reference
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | String | — | Your live API key (starts with as_live_). |
| apiUrl | String | https://api.appsprint.app | Override for staging or self-hosted environments. |
| enableAppleAdsAttribution | bool | true | iOS only. Fetches Apple AdServices at install time. |
| customerUserId | String? | null | Your internal user ID. Persists across launches and replays automatically if the first send fails. |
| autoTrackSessions | bool | true | Fires session_start on configure() and on foreground, debounced to one event per 30 minutes. |
| autoRefreshAttribution | bool | true | Refetches /v1/sdk/attribution on configure() and foreground transitions. |
| googleAdsConsent | GoogleAdsConsent? | null | Reserved for upcoming Google Ads uploads; not used while Google Ads is coming soon. |
| isDebug | bool | false | Forces debug-level logging on the native side. |
| logLevel | int | 2 (WARN) | 0 = DEBUG, 1 = INFO, 2 = WARN, 3 = ERROR. |
Supported event types
session_startloginsign_upregisterpurchasesubscribestart_trialadd_payment_infoadd_to_cartadd_to_wishlistinitiate_checkoutview_contentview_itemsearchsharetutorial_completeachieve_levellevel_startlevel_completecustomUse custom with a name parameter for any event not in this list.
Attribution fields
| Field | Description |
|---|---|
| source | "apple_ads", "tracking_link", or "organic" |
| isAttributed | false for organic installs, true otherwise |
| matchType | Backend match method: apple_ads, idfa, idfv, gaid, ttclid, gclid, gbraid, wbraid, ip_user_agent, or organic |
| campaignName | Signal Campaign name when available |
| link | Signal link object: id, name |
| appleAds | Apple AdServices payload: campaignId, adGroupId, keywordId, countryOrRegion, conversionType |
| utmSource | UTM source from the signal link |
| utmMedium | UTM medium from the signal link |
| utmCampaign | UTM campaign value from the signal link |
API reference
configure(config)
→ Future<bool>Initializes the SDK. Resolves true after local state is restored; install registration runs in the background.
await AppSprint.instance.configure(const AppSprintConfig(apiKey: '…'));
sendEvent(type, {name, params})
→ Future<bool>Enqueues an event locally and schedules a flush. Resolves true once the native bridge accepts it.
await AppSprint.instance.sendEvent(AppSprintEventType.purchase, params: {'revenue': 9.99, 'currency': 'USD'});
flush()
→ Future<void>Drains the queue immediately.
await AppSprint.instance.flush()
refreshAttribution()
→ Future<AttributionResult?>Fetches the latest attribution from the backend. Self-heals a 404 install_not_found by re-running install.
final attr = await AppSprint.instance.refreshAttribution();
setCustomerUserId(id)
→ Future<void>Updates the customer user ID. Sent immediately if install is registered; otherwise queued and retried automatically.
await AppSprint.instance.setCustomerUserId('user-123');
getAppSprintId()
→ Future<String?>Returns the install ID, or null before install registration completes.
final id = await AppSprint.instance.getAppSprintId();
getAttribution()
→ Future<AttributionResult?>Returns the cached AttributionResult.
final attr = await AppSprint.instance.getAttribution();
getAttributionParams()
→ Future<Map<String, String>>Partner-ready flat payload for forwarding to RevenueCat, Superwall, etc.
final params = await AppSprint.instance.getAttributionParams();
enableAppleAdsAttribution()
→ Future<bool>Re-enables Apple Ads at runtime on iOS. Returns false on Android.
await AppSprint.instance.enableAppleAdsAttribution()
isInitialized()
→ Future<bool>True once configure() resolved.
await AppSprint.instance.isInitialized()
isSdkDisabled()
→ Future<bool>True if a 401 or 403 permanently disabled the SDK.
await AppSprint.instance.isSdkDisabled()
sendTestEvent()
→ Future<TestEventResult>Posts a diagnostic event and resolves to (success, message).
final result = await AppSprint.instance.sendTestEvent();
clearData()
→ Future<void>Wipes local state and the event queue.
await AppSprint.instance.clearData()
Offline behavior
- Events that fail to send are queued in native storage (up to 100 events).
- The queue persists across app restarts.
- Queued events are retried when
configure()completes, when another event is sent, when lifecycle flushes run, or when you callflush(). - If a queued event receives a 401/403, the SDK disables itself and clears the queue.
Platform notes
- The Flutter plugin wraps the native iOS and Android SDKs through method channels. Behavior matches the native SDKs exactly; the Dart layer is a thin pass-through.
- configure() is non-blocking. The future resolves once local state is restored; install registration runs in the background on the native side.
- On iOS, ATT must be requested while the app is foreground-active. AppSprintNative.requestTrackingAuthorization() waits for that state internally, so calling it from main() or initState() is safe.
- On Android, GAID is read off the main thread, honoring Limit Ad Tracking and dropping the all-zero advertising ID. The plugin declares INTERNET, ACCESS_NETWORK_STATE, and AD_ID for you.
- Events persist to native storage (UserDefaults on iOS, SharedPreferences on Android) and survive app restarts. Maximum queue size is 100 events.
- iOS uses URLSession with waitsForConnectivity = true. Transient offline windows queue inside the OS rather than failing fast.
Next steps
Troubleshooting
| Problem | What to try |
|---|---|
| getAppSprintId() returns null | configure() resolves before install registration finishes on the native side. Check isInitialized() and retry briefly, or read the value after the first event has been sent. |
| Events do not appear in dashboard | Confirm the API key starts with as_live_. Call sendTestEvent() and inspect the message. iOS logs flow into Console.app; Android logs flow into logcat under the AppSprint tag. |
| SDK disabled after 401/403 | Call clearData(), then configure() with a valid key. |
| pod install fails after adding the package | Run flutter clean, flutter pub get, then cd ios && pod install --repo-update. |
| Attribution returns organic on iOS when Apple Ads is expected | Backend resolution can take up to 75 seconds. The SDK refetches automatically by default; if disabled, call refreshAttribution() manually. |