Skip to main content

SDK Integration

Integrate LinkForty's mobile SDK to enable deferred deep linking, attribution tracking, and in-app event analytics.

Overview

The LinkForty SDK enables your mobile app to:

  • Deferred deep linking - Route new users to specific content after install
  • Attribution tracking - Know which links drive installs
  • Event tracking - Track in-app actions with attribution
  • Fingerprint matching - 70%+ attribution accuracy without device IDs
  • Cross-platform - iOS, Android, React Native, Flutter

Prerequisites

Before integrating the SDK:

  1. Create LinkForty account (Cloud or self-hosted)
  2. Get API key from Settings → API Keys
  3. Create at least one link to test with
  4. Have your app built and ready for SDK integration

Platform SDKs

Choose your platform:

React Native SDK

Best for: React Native apps

npm install @linkforty/react-native

Features:

  • Cross-platform (iOS + Android)
  • TypeScript support
  • Auto-linking (RN 0.60+)

Full React Native Guide →

iOS SDK

Best for: Native iOS apps (Swift/Objective-C)

pod 'LinkFortySDK'

Features:

  • Swift Package Manager support
  • iOS 12+ compatible
  • SwiftUI + UIKit examples

Full iOS Guide →

Android SDK

Best for: Native Android apps (Kotlin/Java)

implementation 'com.linkforty:sdk:2.0.0'

Features:

  • Kotlin-first API
  • Android 5.0+ (API 21+)
  • Jetpack Compose examples

Full Android Guide →

Flutter SDK

Best for: Flutter apps

dependencies:
linkforty_flutter: ^2.0.0

Features:

  • Pure Dart API
  • iOS + Android support
  • Null safety

Full Flutter Guide →

Quick Start (React Native)

1. Install SDK

npm install @linkforty/react-native

2. Initialize SDK

In your App.tsx:

import React, { useEffect } from 'react';
import { LinkFortySDK } from '@linkforty/react-native';

function App() {
useEffect(() => {
LinkFortySDK.initialize({
apiKey: 'your-api-key',
apiUrl: 'https://api.linkforty.com', // Optional for Cloud
enableLogging: __DEV__
});
}, []);

return (
// Your app
);
}
import { useEffect } from 'react';
import { LinkFortySDK } from '@linkforty/react-native';
import { useNavigation } from '@react-navigation/native';

function App() {
const navigation = useNavigation();

useEffect(() => {
checkDeepLink();
}, []);

const checkDeepLink = async () => {
const deepLinkData = await LinkFortySDK.getDeepLinkData();

if (deepLinkData) {
// User installed from a link - route to specific content
if (deepLinkData.productId) {
navigation.navigate('Product', { id: deepLinkData.productId });
}
}
};

return (
// Your app
);
}

4. Track Events

import { LinkFortySDK } from '@linkforty/react-native';

// Track purchase
await LinkFortySDK.trackEvent({
eventName: 'purchase',
value: 29.99,
currency: 'USD',
properties: {
productId: '123',
category: 'Electronics'
}
});

Core Concepts

Deferred Deep Linking

What it does: Routes new users to specific content after app install.

Flow:

  1. User clicks link (e.g., product page)
  2. User doesn't have app → Goes to App Store
  3. User installs and opens app
  4. SDK retrieves deep link data
  5. App navigates to original product page

Code:

const data = await LinkFortySDK.getDeepLinkData();
// { productId: "123", utm_source: "instagram" }

Attribution Tracking

What it does: Tracks which links drive app installs.

Flow:

  1. User clicks link → Fingerprint created
  2. User installs app
  3. SDK checks for matching fingerprint
  4. Install attributed to link (if within attribution window)

View in dashboard: Analytics → Links → Select link → View installs

Event Tracking

What it does: Tracks in-app actions with attribution.

Flow:

  1. User makes purchase in app
  2. SDK tracks event with attribution
  3. Event appears in analytics with original link/campaign

Code:

await LinkFortySDK.trackEvent({
eventName: 'purchase',
value: 49.99,
properties: { productId: '456' }
});

View in dashboard: Analytics → Events

Integration Steps

Step 1: Get API Key

  1. Log into LinkForty dashboard
  2. Go to SettingsAPI Keys
  3. Click "Create API Key"
  4. Name it "Mobile App SDK"
  5. Copy the API key (starts with lf_live_)

Step 2: Install SDK

See platform-specific guides:

Step 3: Initialize on App Launch

Call initialize() as early as possible:

React Native:

useEffect(() => {
LinkFortySDK.initialize({
apiKey: process.env.LINKFORTY_API_KEY
});
}, []);

iOS:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
LinkFortySDK.initialize(apiKey: "your-api-key")
return true
}

Android:

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
LinkFortySDK.initialize(this, "your-api-key")
}
}

Call getDeepLinkData() on first app launch:

React Native:

const data = await LinkFortySDK.getDeepLinkData();
if (data) {
// Route to specific content
navigation.navigate('Product', { id: data.productId });
}

iOS:

LinkFortySDK.getDeepLinkData { result in
if case .success(let data) = result {
// Route to specific content
navigateToProduct(id: data["productId"])
}
}

Android:

LinkFortySDK.getDeepLinkData { data ->
data?.let {
// Route to specific content
navigateToProduct(it["productId"])
}
}

Step 5: Track Key Events

Track important actions:

// User registration
await LinkFortySDK.trackEvent({
eventName: 'signup',
properties: { method: 'email' }
});

// Purchase
await LinkFortySDK.trackEvent({
eventName: 'purchase',
value: 29.99,
currency: 'USD',
properties: { productId: '123' }
});

// Custom events
await LinkFortySDK.trackEvent({
eventName: 'level_completed',
properties: { level: 5 }
});

Step 6: Test Integration

Create test link:

curl -X POST https://api.linkforty.com/api/links \
-H "Authorization: Bearer $LINKFORTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "template_123",
"originalUrl": "https://example.com/product/123?productId=123",
"iosUrl": "https://apps.apple.com/app/id123",
"androidUrl": "https://play.google.com/store/apps/details?id=com.app"
}'

Test flow:

  1. Uninstall app from test device
  2. Click test link on device
  3. Install app from App Store/Google Play
  4. Open app
  5. Check console logs for deep link data
  6. Verify navigation to product page

Expected result:

[LinkForty] Deep link data: {
productId: "123",
utm_source: undefined,
utm_campaign: undefined
}

Step 7: Deploy to Production

  1. Remove debug logging:

    LinkFortySDK.initialize({
    apiKey: PRODUCTION_API_KEY,
    enableLogging: false // Disable in production
    });
  2. Use environment-specific API keys:

    • Development: lf_test_... (when available)
    • Production: lf_live_...
  3. Test on real devices (not simulators/emulators)

  4. Monitor attribution in dashboard after launch

Best Practices

1. Initialize Early

Initialize SDK in app entry point, before any navigation:

✅ Good:

function App() {
useEffect(() => {
LinkFortySDK.initialize({ apiKey: API_KEY });
}, []);
}

❌ Bad:

function HomeScreen() {
useEffect(() => {
LinkFortySDK.initialize({ apiKey: API_KEY });
}, []);
}

Only check for deep link on first app launch, not every time:

const [hasCheckedDeepLink, setHasCheckedDeepLink] = useState(false);

useEffect(() => {
if (!hasCheckedDeepLink) {
checkDeepLink();
setHasCheckedDeepLink(true);
}
}, []);

3. Handle Navigation Carefully

Wait for navigation to be ready:

const checkDeepLink = async () => {
const data = await LinkFortySDK.getDeepLinkData();

if (data && navigationRef.isReady()) {
navigationRef.current?.navigate('Product', { id: data.productId });
}
};

4. Track Key Events Only

Don't track every single action. Focus on:

  • User registration
  • Purchases/conversions
  • Key feature usage
  • Level/milestone completions

❌ Don't track:

  • Button clicks
  • Screen views (unless key screens)
  • Every user interaction

5. Use Environment Variables

Never hardcode API keys:

// .env
LINKFORTY_API_KEY=lf_live_a1b2c3d4e5f6g7h8

// App.tsx
LinkFortySDK.initialize({
apiKey: process.env.LINKFORTY_API_KEY
});

6. Set User Identifiers

Associate events with user IDs:

// After login
LinkFortySDK.setUserIdentifier(user.id);

// Events now associated with this user
await LinkFortySDK.trackEvent({ eventName: 'purchase' });

// After logout
LinkFortySDK.clearUserIdentifier();

7. Test on Real Devices

Fingerprint matching doesn't work reliably in simulators. Always test on physical devices.

Troubleshooting

Symptoms:

  • getDeepLinkData() returns null
  • User definitely clicked link before installing

Possible causes:

  1. Attribution window expired

    • Check link's attribution window setting
    • User may have installed too long after clicking
  2. SDK not initialized before calling getDeepLinkData

    • Ensure initialize() completes before calling
  3. Different network/device

    • User clicked on WiFi, installed on cellular
    • Fingerprint won't match (expected)
  4. Testing in simulator

    • Fingerprint matching unreliable in simulators
    • Test on real device

Solution:

// Enable debug logging
LinkFortySDK.initialize({
apiKey: API_KEY,
enableLogging: true
});

// Check result
const data = await LinkFortySDK.getDeepLinkData();
console.log('Deep link result:', data);

Events Not Appearing in Dashboard

Symptoms:

  • trackEvent() succeeds but events don't show in analytics

Possible causes:

  1. Network connectivity

    • Events are queued and sent when online
  2. Invalid API key

    • Check API key is correct
  3. Events delayed (batched)

    • Events may take 1-2 minutes to appear

Solution:

try {
await LinkFortySDK.trackEvent({
eventName: 'test_event'
});
console.log('Event tracked successfully');
} catch (error) {
console.error('Error tracking event:', error);
}

Build Errors After Installation

iOS:

cd ios && pod install

Android:

cd android && ./gradlew clean

React Native:

npm install
npx react-native link @linkforty/react-native

Attribution Accuracy Lower Than Expected

Expected: 70-80% accuracy with fingerprint matching

If lower:

  1. Check attribution window

    • May be too short for your use case
    • Increase to 7-14 days
  2. Verify SDK integration

    • Ensure getDeepLinkData() called on first launch
    • Check logs for errors
  3. Network conditions

    • VPN/proxy usage reduces accuracy
    • Cellular vs WiFi switching
  4. Device factors

    • iOS 14+ privacy features
    • Different browsers (in-app vs Safari)

Security Best Practices

1. Protect API Keys

✅ Good:

  • Store in environment variables
  • Use different keys for dev/prod
  • Rotate keys quarterly

❌ Bad:

  • Hardcode in source code
  • Commit to Git
  • Share publicly

Don't trust deep link data blindly:

const data = await LinkFortySDK.getDeepLinkData();

if (data && data.productId) {
// Validate product ID exists
const product = await api.getProduct(data.productId);

if (product) {
navigation.navigate('Product', { id: product.id });
} else {
// Invalid product ID - don't navigate
console.warn('Invalid product ID from deep link');
}
}

3. Rate Limit Event Tracking

Prevent abuse:

const eventQueue = [];
const MAX_EVENTS_PER_MINUTE = 60;

async function trackEventSafely(event) {
const now = Date.now();
const recentEvents = eventQueue.filter(t => now - t < 60000);

if (recentEvents.length >= MAX_EVENTS_PER_MINUTE) {
console.warn('Event rate limit exceeded');
return;
}

eventQueue.push(now);
await LinkFortySDK.trackEvent(event);
}

Advanced Features

Custom Event Properties

Track rich event data:

await LinkFortySDK.trackEvent({
eventName: 'purchase',
value: 149.99,
currency: 'USD',
properties: {
productId: '123',
productName: 'Wireless Headphones',
category: 'Electronics',
brand: 'TechCo',
quantity: 1,
couponCode: 'SUMMER20',
paymentMethod: 'credit_card',
shippingMethod: 'express'
}
});

Timed Events

Track event duration:

const startTime = Date.now();

// User completes tutorial
const duration = Date.now() - startTime;

await LinkFortySDK.trackEvent({
eventName: 'tutorial_completed',
properties: {
duration_seconds: Math.floor(duration / 1000),
steps_completed: 5
}
});

User Properties

Set user attributes:

// After user logs in or signs up
LinkFortySDK.setUserIdentifier(user.id);

// Track user properties
await LinkFortySDK.trackEvent({
eventName: 'user_properties',
properties: {
email: user.email,
subscription_tier: 'pro',
signup_date: user.createdAt,
country: user.country
}
});

Performance Optimization

1. Lazy Initialize

For faster app startup, initialize SDK after critical path:

useEffect(() => {
// Critical startup tasks first
loadUserData();
initializeAuth();

// Then initialize LinkForty
setTimeout(() => {
LinkFortySDK.initialize({ apiKey: API_KEY });
}, 100);
}, []);

2. Batch Events

SDK automatically batches events, but you can optimize further:

const events = [];

function queueEvent(event) {
events.push(event);

// Send batch every 10 events or 30 seconds
if (events.length >= 10) {
sendBatch();
}
}

async function sendBatch() {
const batch = events.splice(0, events.length);
await Promise.all(batch.map(e => LinkFortySDK.trackEvent(e)));
}

Avoid calling getDeepLinkData() multiple times:

let cachedDeepLinkData = null;

async function getDeepLink() {
if (!cachedDeepLinkData) {
cachedDeepLinkData = await LinkFortySDK.getDeepLinkData();
}
return cachedDeepLinkData;
}

Next Steps

Support