React Native / Expo
Install the Expo / React Native SDK, register installs, track events, and read attribution. Setup takes about 5 minutes.
Requirements
- React Native 0.71+
- React 18+
- iOS 14.0+ and Android 7.0+ (API 24+)
Install
npm
npm install appsprint-react-native@^1.1.9# iOS onlycd ios && pod install
For Expo prebuild, add the config plugin to app.json and run npx expo prebuild. The plugin injects NSUserTrackingUsageDescription on iOS and INTERNET / ACCESS_NETWORK_STATE / AD_ID on Android.
Published on npm. Always use the latest version.
Configure
import { AppSprint } from 'appsprint-react-native';// Call as early as possible. App.tsx, root layout, or _layout.tsx.await AppSprint.configure({apiKey: 'as_live_xxxxx',});
Non-blocking. configure() resolves after local state is restored; install registration runs in the background on the native side. Lifecycle observers register automatically.
Track events
// Standard eventawait AppSprint.sendEvent('login');
// Revenue event. Currency must be a 3-letter ISO code.await AppSprint.sendEvent('purchase', null, {revenue: 9.99,currency: 'USD',});
// Custom event with parametersawait AppSprint.sendEvent('custom', 'level_complete', {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.
const attr = await AppSprint.getAttribution();console.log(attr?.source); // "apple_ads", "tracking_link", or "organic"console.log(attr?.isAttributed); // booleanconsole.log(attr?.campaignName); // Campaign name when availableconsole.log(attr?.appleAds?.campaignId);console.log(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.
const result = await AppSprint.sendTestEvent();console.log(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 | boolean | true | iOS only. Fetches Apple AdServices at install time. |
| customerUserId | string | null | null | Your internal user ID. Persists across launches and replays automatically if the first send fails. |
| autoTrackSessions | boolean | true | Fires session_start on configure() and on foreground, debounced to one event per 30 minutes. |
| autoRefreshAttribution | boolean | true | Refetches /v1/sdk/attribution on configure() and foreground transitions. |
| googleAdsConsent | GoogleAdsConsent | null | null | Reserved for upcoming Google Ads uploads; not used while Google Ads is coming soon. |
| isDebug | boolean | false | Forces debug-level logging on the native side. |
| logLevel | 0 | 1 | 2 | 3 | 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)
→ Promise<boolean>Initializes the SDK. Resolves true after local state is restored; install registration runs in the background.
await AppSprint.configure({ apiKey: '…' })
sendEvent(type, name?, params?)
→ Promise<boolean>Enqueues an event locally and schedules a flush. Resolves true once the native bridge accepts it.
await AppSprint.sendEvent('purchase', null, { revenue: 9.99, currency: 'USD' })
type is a string literal — see event types below.
flush()
→ Promise<void>Drains the queue immediately. Safe to call repeatedly.
await AppSprint.flush()
refreshAttribution()
→ Promise<AttributionResult | null>Fetches the latest attribution from the backend. Self-heals a 404 install_not_found by re-running install.
const attr = await AppSprint.refreshAttribution()
setCustomerUserId(id)
→ Promise<void>Updates the customer user ID. Sent immediately if install is registered; otherwise queued and retried automatically.
await AppSprint.setCustomerUserId('user-123')
getAppSprintId()
→ Promise<string | null>Returns the install ID, or null before install registration completes.
const id = await AppSprint.getAppSprintId()
getAttribution()
→ Promise<AttributionResult | null>Returns the cached AttributionResult.
const attr = await AppSprint.getAttribution()
getAttributionParams()
→ Promise<Record<string, string>>Partner-ready flat payload for forwarding to RevenueCat, Superwall, etc.
const params = await AppSprint.getAttributionParams()
enableAppleAdsAttribution()
→ Promise<boolean>Re-enables Apple Ads at runtime on iOS. Returns false on Android.
await AppSprint.enableAppleAdsAttribution()
isInitialized()
→ Promise<boolean>True once configure() resolved.
await AppSprint.isInitialized()
isSdkDisabled()
→ Promise<boolean>True if a 401 or 403 permanently disabled the SDK.
await AppSprint.isSdkDisabled()
sendTestEvent()
→ Promise<{ success, message }>Posts a diagnostic event and resolves to (success, message).
const result = await AppSprint.sendTestEvent()
clearData()
→ Promise<void>Wipes local state and the event queue. Removes lifecycle observers.
await AppSprint.clearData()
destroy()
Removes native lifecycle observers without wiping data.
AppSprint.destroy()
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 JS layer is a thin bridge. Behavior matches the standalone native iOS and Android SDKs.
- On iOS, ATT must be requested while the app is foreground-active. NativeAppSprint.requestTrackingAuthorization() waits for that state internally.
- On iOS, AdServices runs on iOS 14.3+. Older OS versions skip Apple Ads attribution silently.
- On Android, GAID is read off the main thread, honoring Limit Ad Tracking and dropping the all-zero advertising ID.
- 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.
- On Expo, the bundled config plugin injects NSUserTrackingUsageDescription, INTERNET, ACCESS_NETWORK_STATE, and AD_ID during prebuild.
Next steps
Troubleshooting
| Problem | What to try |
|---|---|
| getAppSprintId() returns null | configure() resolves before install registration finishes on the native side. 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 returned message. |
| SDK disabled (isSdkDisabled returns true) | The API returned 401 or 403. Call clearData(), then configure() with a valid key. |
| Apple Ads attribution not detected | AdServices requires a real device (not the simulator). Confirm enableAppleAdsAttribution is true and that the test build is signed with a real provisioning profile. |
| pod install fails after adding the package | Delete ios/Podfile.lock and ios/Pods, then run pod install --repo-update. |
| Android build cannot find AD_ID | The package's manifest declares com.google.android.gms.permission.AD_ID and is merged at build time. If you target an app that cannot use it, remove with tools:node="remove". |