Skip to main content

SDK Integration

Integrate a LinkForty mobile SDK to enable deferred deep linking, attribution tracking, and in-app event analytics. This page is a cross-platform overview — each SDK's complete API lives on its own page.

What the SDK does​

  • Deferred deep linking — route new users to specific content after install
  • Direct deep linking — handle links when the app is already installed
  • Install attribution — match installs to the link click that drove them (fingerprint matching, no device IDs required)
  • Event tracking — log in-app events and revenue tied to attribution data

Prerequisites​

  1. A LinkForty account (Cloud) or a running self-hosted Core server
  2. Your server's base URL (e.g. https://go.yourdomain.com)
  3. For Cloud: your workspace App Token (at_…, found under Workspace Settings → App Token) — recommended so organic installs are attributed
  4. (Optional) an API key (dl_…, from Settings → API Keys) — only needed if you create links programmatically from the app

Platform SDKs​

Pick your platform and follow its full guide:

PlatformInstallFull guide
React Nativenpm install @linkforty/mobile-sdk-react-nativeReact Native SDK
Exponpx expo install @linkforty/mobile-sdk-expoExpo SDK
iOS (Swift)pod 'LinkFortySDK', '~> 1.0' (or Swift Package Manager)iOS SDK
Android (Kotlin)implementation("com.linkforty:sdk:1.3.0")Android SDK
Flutterlinkforty_flutter in pubspec.yamlFlutter SDK

All SDKs share the same flow: initialize → handle the deferred deep link → track events.

Each platform page also carries a Copy prompt for AI block: a prompt for Claude Code, Cursor or Codex that does the whole install in your project — Expo, React Native, iOS, Android, Flutter.

How integration works​

1. Initialize at app launch​

Initialize the SDK as early as possible with your server baseUrl and (for Cloud) your appToken.

React Native:

import LinkForty from '@linkforty/mobile-sdk-react-native';

LinkForty.init({
baseUrl: 'https://go.yourdomain.com',
appToken: 'at_your_app_token', // recommended for Cloud
apiKey: 'dl_your_api_key', // only if you create links from the app
debug: __DEV__,
});

iOS (Swift):

import LinkFortySDK

let config = LinkFortyConfig(
baseURL: "https://go.yourdomain.com",
appToken: "at_your_app_token"
)
try await LinkForty.shared.initialize(config: config)

Android (Kotlin):

import com.linkforty.sdk.LinkForty
import com.linkforty.sdk.LinkFortyConfig

val config = LinkFortyConfig(
baseUrl = "https://go.yourdomain.com",
appToken = "at_your_app_token"
)
LinkForty.initialize(this, config)

Flutter:

import 'package:linkforty_flutter/link_forty.dart';
import 'package:linkforty_flutter/models/link_forty_config.dart';

final config = LinkFortyConfig(
baseUrl: 'https://go.yourdomain.com',
appToken: 'at_your_app_token',
);
await LinkForty.initialize(config: config);

Register a deferred deep link handler. On a new install attributed to a link, it fires with the link's data so you can route the user to the right content. It receives null for organic installs.

React Native:

LinkForty.onDeferredDeepLink((data) => {
if (data) {
// e.g. navigate using data.deepLinkPath / data.customParameters
navigateToContent(data);
}
});

iOS (Swift):

LinkForty.shared.onDeferredDeepLink { deepLinkData in
guard let data = deepLinkData else { return } // organic install
navigateToContent(data)
}

Android (Kotlin):

LinkForty.shared.onDeferredDeepLink { deepLinkData ->
deepLinkData?.let { navigateToContent(it) }
}

Flutter:

LinkForty.instance.onDeferredDeepLink((deepLinkData) {
if (deepLinkData != null) {
navigateToContent(deepLinkData);
}
});

Use the corresponding direct deep link handler (e.g. onDeepLink) to route links opened while the app is already installed — see your platform's SDK page.

3. Track in-app events​

Track the actions that matter (signups, purchases) so they're attributed to the originating link. Use the dedicated revenue method for monetary events so amounts aggregate consistently across SDKs.

// React Native
LinkForty.trackEvent('signup', { method: 'email' });
LinkForty.trackRevenue(29.99, 'USD', { productId: 'sku-123', orderId: 'order-456' });

Events appear in the dashboard under Analytics → Events. See Events & Conversions and your platform's SDK page for the exact signatures.

Send in-app events from the app
Signup, purchase and activation events from an app that already has the SDK, with revenue and currency, plus screen views for the funnel.
Show the prompt
I use LinkForty (https://linkforty.com), a deep-linking and mobile attribution platform: short links that route each click to the app, the app store or the web, and record clicks, installs and in-app events per link.

Before writing any code, read the LinkForty documentation index at https://docs.linkforty.com/llms-full.txt and the pages listed under "Docs" below. Work from what the docs say, not from assumptions about how similar products work. If something you need is not in the docs or in this prompt — an ID, a token, a URL — stop and ask me for it rather than inventing a placeholder that looks real.

## Task: send in-app events from this app to LinkForty

The LinkForty SDK is already installed and initialized in this app, and installs are being attributed. What is missing is everything after the install: the sign-ups, purchases and key actions that turn an install count into a funnel. Add event tracking so those moments are recorded against the install and the link that produced it.

If the SDK is **not** in this app, stop and tell me — installing it is a separate task with its own prompt.

## Values

- **App token**: already in the app's SDK initialization (it starts with `at_`; the dashboard shows it under Workspace Settings → App Token). Do not add it a second time or move it.
- **Event names**: chosen with me in step 2. Short, stable, lower_snake_case.
- **Money**: amount as a number plus an ISO 4217 currency code (`'USD'`), through the SDK's revenue method — never a formatted string.

## How to work

1. **Look before you change anything.** Identify the framework, its version, the navigation/router library and where the app initializes at launch. List the screens (routes) you found, and **ask me which screen each incoming link should open and what parameter it needs** — for example "a link with `productId` opens the product screen". Wait for my answer before editing; do not guess routes.
2. **Work on a new git branch.** If the working tree has uncommitted changes, stop and tell me instead of building on top of them.
3. **Follow the docs pages named below, not memory.** Package names, method names and config keys come from those pages; LinkForty's SDKs are not the same as other attribution SDKs you may know.
4. **Do not invent values.** Anything in "Values" that says "ask me" is something you ask for. Never commit a token to source.
5. **Keep the app working without a link.** A launch with no matching click must behave exactly as before: no crash, no error surfaced to the user, no blocked start-up.
6. **Finish with a summary**: every file you changed and why; the manual steps that remain for me (Apple Team ID and bundle ID, Play signing SHA-256 fingerprint, store listing, a rebuild and reinstall) and where in the LinkForty dashboard each one goes (Workspace Settings → App Configuration); and anything you were unsure about.
7. **Verify.** Run the app once, then check the LinkForty dashboard: the SDK Doctor badge in the sidebar (https://docs.linkforty.com/guides/attribution/sdk-health) should report the SDK as installed. If the MCP server is available, create a test link with `create_link` and open it on a device or simulator; the click and the deep link should reach the screen we agreed on.

## Steps

1. **Find the SDK.** Locate where LinkForty is initialized (`init` / `initialize`) and which package it is — `@linkforty/mobile-sdk-react-native`, `@linkforty/mobile-sdk-expo`, `LinkFortySDK` (Swift), `com.linkforty.sdk` (Kotlin) or `linkforty_flutter`. Every event goes through that same instance so it attaches to the install; never create a second one.
2. **Find the moments that matter** and list them with file and line: account created, onboarding finished, the first key action (whatever "activated" means in this app), purchase or subscription, and the two or three screens a new user must reach. **Ask me which to track and what to call each** before writing anything. Names are short, stable, lower_snake_case — `signup`, `onboarding_completed`, `purchase` (https://docs.linkforty.com/guides/analytics/events#event-naming-conventions). Not one event per tap.
3. **Fire each event once, at completion.** On the success path — after the account exists, after the payment is confirmed — not when a screen appears or a button is rendered. Guard against double-firing on re-render, retry or resume.
4. **Use the platform's own methods** from the SDK page (https://docs.linkforty.com/guides/analytics/events#custom-events): the track-event method for plain events with a small flat properties object; the revenue method — `trackRevenue(amount, currency, …)` — for anything with money, so the dashboard can sum it per currency (https://docs.linkforty.com/guides/analytics/events#revenue-events). No personal data in properties: no names, emails, phone numbers, precise location.
5. **Add screen views for the funnel** (https://docs.linkforty.com/guides/analytics/app-analytics): on React Native and Expo, prefer `autoTrackNavigation` with the app's `navigationRef` (screen names only — the default); on Android with Jetpack Navigation, `LinkFortyNavObserver`; otherwise `trackScreenView('ScreenName')` on the handful of screens from step 2. Never inside a render function or a hot loop — on navigation, or in the screen's appear/mount hook.
6. **Keep the app unaffected.** Event calls must not block the UI or throw into user code; the SDK queues offline and retries, so do not add your own retry layer.
7. **Verify** by running the app through the agreed flow once, then checking the LinkForty dashboard: the events on the Events dashboard, attached to the install; a purchase with its amount and currency; screens in the screen flow; and SDK Doctor showing events flowing (https://docs.linkforty.com/guides/attribution/sdk-health).

## Docs

- Events guide — custom events, revenue events, naming: https://docs.linkforty.com/guides/analytics/events
- App analytics and screen flow: https://docs.linkforty.com/guides/analytics/app-analytics
- Event Library (what the dashboard expects a name to mean): https://docs.linkforty.com/guides/analytics/event-library
- Your platform's SDK page, "Track Events" / "Track Screen Views": https://docs.linkforty.com/sdks/react-native#track-events · https://docs.linkforty.com/sdks/expo#track-events · https://docs.linkforty.com/sdks/ios#track-events · https://docs.linkforty.com/sdks/android#track-events · https://docs.linkforty.com/sdks/flutter#track-events

## Done when

- Each agreed event fires exactly once at completion, from the existing SDK instance.
- A purchase reports its amount and currency through the revenue method.
- Screen views arrive for the agreed screens without touching render paths.
- The events show in the LinkForty dashboard attached to the install, and SDK Doctor reports events flowing.

When you are done, tell me: exactly which files changed and why, how I can verify it worked end to end (what to tap or run, and what I should see in the LinkForty dashboard), and anything you were unsure about.

Core concepts​

Deferred deep linking​

Routes new users to specific content after they install:

  1. User taps a link (e.g. a product page)
  2. App isn't installed → user goes to the App Store / Play Store
  3. User installs and opens the app
  4. The SDK retrieves the attributed link data
  5. Your app navigates to the original content

Attribution​

LinkForty matches installs to clicks using device fingerprinting (typically 70%+ accuracy without device IDs), within the link's attribution window. View attributed installs under Analytics → Installs, or per link.

Event tracking​

In-app events are tied to the install's attribution, so a purchase made weeks after install is still credited to the link and campaign that drove it: the link the user last opened the app through, otherwise the one they installed from. See how events are credited.

Testing your integration​

Fingerprint matching is unreliable on simulators/emulators — test on a real device:

  1. Uninstall the app from the device
  2. Tap a test link that points to your app
  3. Install the app from the store (or your dev build)
  4. Open the app
  5. Verify the deferred deep link handler fires with the expected data (enable debug to see logs)
  6. Confirm the install appears under Analytics → Installs

Universal Links let a tapped LinkForty URL open your app directly (instead of the browser) when it's installed. Two pieces are required:

  1. Associated Domains in your app. In Xcode, add the Associated Domains capability to your target and list your link domain:

    applinks:go.yourdomain.com
  2. The Apple App Site Association (AASA) file on your server. LinkForty serves this automatically at /.well-known/apple-app-site-association once you provide your Apple Team ID and bundle ID.

    • LinkForty Cloud: set these in your workspace's app configuration.
    • Self-hosted Core: set the IOS_TEAM_ID and IOS_BUNDLE_ID environment variables. If they're unset, the AASA endpoint returns a 404.

Verify the file is served (no .json extension, application/json content type, over HTTPS):

curl https://go.yourdomain.com/.well-known/apple-app-site-association

See also Universal Links vs App Links.

Android App Links are the equivalent mechanism for opening your app from a verified domain. Two pieces are required:

  1. An intent filter in your AndroidManifest.xml with android:autoVerify="true" for your link host (see the React Native SDK guide for a full example).

  2. The Digital Asset Links file on your server. LinkForty serves this automatically at /.well-known/assetlinks.json once you provide your package name and signing-certificate fingerprints.

    • LinkForty Cloud: set these in your workspace's app configuration.
    • Self-hosted Core: set the ANDROID_PACKAGE_NAME and ANDROID_SHA256_FINGERPRINTS (comma-separated) environment variables. If they're unset, the assetlinks.json endpoint returns a 404.

Verify the file is served:

curl https://go.yourdomain.com/.well-known/assetlinks.json

See also Universal Links vs App Links.

Best practices​

  • Initialize early — in your app entry point, before navigation, so the deferred deep link is ready on first launch.
  • Test on real devices — fingerprint matching is unreliable on simulators/emulators.
  • Keep secrets appropriately — the appToken (at_…) is safe to ship in your app bundle; an API key (dl_…) is a secret, so only embed it if you truly need in-app link creation, and load it from a secure config.
  • Track meaningful events — focus on value events (signup, purchase) rather than every interaction; use the revenue method for money.
  • Validate deep link data — don't trust it blindly; verify IDs exist before navigating.

Troubleshooting​

  • The attribution window may have expired (user installed too long after clicking)
  • Different network between click and install (VPN, iOS Private Relay) can prevent a fingerprint match
  • Ensure the SDK is initialized before registering the handler
  • Enable debug to see detailed logs, and test on a real device

Events not appearing​

  • Events require a successful install report — confirm the SDK has an install ID
  • Check connectivity and your baseUrl
  • Allow 1–2 minutes for events to appear in the dashboard

Lower-than-expected attribution​

  • Increase the attribution window if users install later than it allows
  • VPN/proxy usage and cellular↔Wi-Fi switching reduce match accuracy
  • Always measure on real devices

Next Steps​

Support​