SDK Integration
Native and cross-platform SDKs for integrating deep linking into your mobile and web applications.
Overview
| SDK | Language | Min Version | Source | Status |
|---|---|---|---|---|
| iOS (Swift) | Swift 5.9+ | iOS 15+ | deeplink-sdk-ios/ |
Stable |
| Android (Kotlin) | Kotlin 1.9+ | Android 7+ (API 24) | deeplink-sdk-android/ |
Stable |
| Kotlin Multiplatform | Kotlin | iOS 15+ / Android 7+ | deeplink-sdk-kmp/ |
Stable |
| React Native | TypeScript | RN 0.73+ | deeplink-sdk-rn/ |
Beta |
| Flutter | Dart | Flutter 3.16+ | deeplink-sdk-flutter/ |
Beta |
| Web JS | TypeScript / ES2020 | Modern browsers | deeplink-sdk-web/ |
Stable |
| Node.js | TypeScript | Node 18+ | deeplink-sdk-node/ |
Stable |
| Python | Python 3.10+ | — | deeplink-sdk-python/ |
Alpha |
| Go | Go 1.21+ | — | deeplink-sdk-go/ |
Alpha |
| Unity (C#) | C# / Unity 2022+ | — | deeplink-sdk-unity/ |
Beta |
Feature Matrix — what's available where
Quick overview of which features are supported on each SDK. Use this to evaluate before integrating, or to know if you can reach feature parity across platforms.
| Feature | iOS | Android | KMP | RN | Flutter | Web JS | Node | Python | Go | Unity |
|---|---|---|---|---|---|---|---|---|---|---|
| Setup & Identity | ||||||||||
configure() / init | ✅ 1.0 | ✅ 1.0 | ✅ 0.5 | ✅ 0.9 | ✅ 0.9 | ✅ 1.0 | ✅ 1.0 | ✅ 1.0 | ✅ 0.9 | ⚠️ 0.5 |
identify(userId) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
setUserProperties() | ✅ | ✅ | ⚠️ | ✅ | ⚠️ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Deep linking | ||||||||||
Universal Link / App Link handleOpenURL() | ✅ | ✅ | ✅ | ✅ | ✅ | n/a | n/a | n/a | n/a | ⚠️ |
| Deferred matching (post-install) | ✅ | ✅ | ✅ | ✅ | ✅ | n/a | n/a | n/a | n/a | ⚠️ |
A/B test routing (handleOpenURL /ab/) | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | n/a | n/a | n/a | n/a | ❌ |
Server-side buildLink() / shorten | n/a | n/a | n/a | n/a | n/a | n/a | ✅ | ✅ | ✅ | n/a |
| Tracking & events | ||||||||||
trackEvent(name, props) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
Batch upload /events/batch | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Offline event queue (auto-retry) | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | ❌ | n/a | n/a | n/a | ❌ |
| Session tracking auto | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | ✅ | n/a | n/a | n/a | ❌ |
| Custom event schema (validation) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Identity privacy (mobile) | ||||||||||
| ATT prompt (iOS 14.5+) | ✅ requestATT() | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
| IDFA collection (after consent) | ✅ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
| SKAdNetwork (SKAN) | ✅ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a |
| GAID collection | n/a | ✅ | ⚠️ | ⚠️ | ⚠️ | n/a | n/a | n/a | n/a | n/a |
| Install Referrer (Play Store) | n/a | ✅ | ⚠️ | ⚠️ | ⚠️ | n/a | n/a | n/a | n/a | n/a |
| Web-specific | ||||||||||
| Smart banner display | n/a | n/a | n/a | n/a | n/a | ✅ | n/a | n/a | n/a | n/a |
| dataLayer auto-listen (GTM) | n/a | n/a | n/a | n/a | n/a | ✅ | n/a | n/a | n/a | n/a |
| Cross-domain attribution | n/a | n/a | n/a | n/a | n/a | ⚠️ | n/a | n/a | n/a | n/a |
| Server-side / backend ops | ||||||||||
Referrals API getReferralCode/claim | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
Analytics API getSummary | n/a | n/a | n/a | n/a | n/a | n/a | ✅ | ✅ | ⚠️ | n/a |
| LTV / Ad Spend API | n/a | n/a | n/a | n/a | n/a | n/a | ✅ | ✅ | ❌ | n/a |
Sources de vérité : akeeli-tech/deeplink-sdk-{ios,android,node,python}/README.md publics ;
pour KMP / Flutter / RN / Go / Unity, état dérivé de CLAUDE.md workspace + sources récentes.
Items ⚠️ sont en backlog STORY-19 / STORY-20 / STORY-21 / STORY-22.
Items ❌ Custom event schema en backlog STORY-13.
Si une cellule est obsolète, ouvrir une issue dans deeplink-server avec label doc.
The Three Integration Points
For a complete integration you must call all three methods — each covers a different use case:
| Method | When to Call | Server Endpoint | Analytics |
|---|---|---|---|
configure(serverUrl, tenantSlug) |
Once at app startup | — | — |
initialize() |
Once at first launch after install | POST /api/v1/match |
Deferred Installs |
handleOpenURL(url) |
Every URL received — Universal Link, App Link, custom scheme | GET /api/v1/resolve/:tenant/:slug |
App Opens |
handleOpenURL is essential — when iOS/Android opens the app via Universal Link, the server is never contacted by the OS. Without this call, Universal Link taps are invisible in analytics and you cannot read custom_data.configure() Parameters
| Parameter | Required | Description |
|---|---|---|
serverUrl | Yes | HTTPS URL of the server, no trailing slash. E.g. "https://links.yourapp.com" |
tenantSlug | Yes | Your tenant slug (visible in the dashboard URL). Filters handleOpenURL to your tenant's URLs. |
debugLogs | No | If true, logs HTTP requests. Disable in production. |
iOS (Swift)
Installation
Swift Package Manager
// Package.swift
.package(
url: "https://github.com/your-org/deeplink-sdk-ios",
from: "1.0.0"
)
CocoaPods
# Podfile
pod 'DeepLinkSDK', '~> 1.0'
Full Integration — SwiftUI
import SwiftUI
import DeepLinkSDK
@main
struct MyApp: App {
init() {
DeepLinkSDK.shared.configure(
serverUrl: "https://links.yourapp.com",
tenantSlug: "main",
debugLogs: true // disable in production
)
}
var body: some Scene {
WindowGroup {
ContentView()
// (1) Deferred deep link — 1st launch after install
.task {
if case .matched(let data) = await DeepLinkSDK.shared.initialize() {
router.navigate(to: data.customData)
}
}
// (2) Universal Link — Messages, Mail, Notes…
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
guard let url = activity.webpageURL else { return }
Task {
if case .matched(let data) = await DeepLinkSDK.shared.handleOpenURL(url) {
await MainActor.run { router.navigate(to: data.customData) }
}
}
}
// (3) Custom scheme (in-app WebView fallback)
.onOpenURL { url in
Task { _ = await DeepLinkSDK.shared.handleOpenURL(url) }
}
}
}
}
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
await DeepLinkSDK.shared.identify(userId: "user_12345")
Track Custom Events
// Simple event
await DeepLinkSDK.shared.trackEvent(name: "signup")
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
await DeepLinkSDK.shared.trackEvent(
name: "purchase",
linkSlug: data.slug, // from initialize() or handleOpenURL()
properties: ["product_id": "abc"],
revenue: 29.99,
currency: "EUR"
)
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// Events tracked while offline are persisted to disk and
// sent in batch when the network becomes available.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed. The flow is:
- User taps a link → server redirects to the App Store / Play Store
- User installs the app and opens it for the first time
- The SDK calls
initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the initialize() call shown above:
if case .matched(let data) = await DeepLinkSDK.shared.initialize() {
// Navigate to the content the user originally tapped
router.navigate(to: data.customData)
}
Consent (GDPR)
// Call before initialize() if consent is required
DeepLinkSDK.shared.setConsent(granted: true)
// To withdraw consent and purge local data
DeepLinkSDK.shared.setConsent(granted: false)
applinks:links.yourapp.com (no https://, no /*, just the host). Without this, iOS will never recognize the URL as a Universal Link.Android (Kotlin)
Installation
// build.gradle.kts (app module)
dependencies {
implementation("com.yourorg:deeplink-sdk-android:1.0.0")
}
Full Integration
// Application.onCreate()
DeepLinkSDK.configure(
context = this,
serverUrl = "https://links.yourapp.com",
tenantSlug = "main",
debugLogs = BuildConfig.DEBUG
)
// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
// (1) Deferred deep link
(DeepLinkSDK.initialize() as? DeepLinkResult.Matched)?.let {
navigate(it.data)
}
}
// (2) Cold start via App Link
intent.data?.let { handleDeepLink(it) }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { handleDeepLink(it) }
}
private fun handleDeepLink(uri: Uri) = lifecycleScope.launch {
(DeepLinkSDK.handleOpenUrl(uri) as? DeepLinkResult.Matched)?.let {
navigate(it.data)
}
}
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
DeepLinkSDK.identify(userId = "user_12345")
Track Custom Events
// Simple event
DeepLinkSDK.trackEvent(name = "signup")
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
DeepLinkSDK.trackEvent(
name = "purchase",
linkSlug = data.slug,
properties = mapOf("product_id" to "abc"),
revenue = 29.99,
currency = "EUR"
)
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// Events tracked while offline are persisted to disk and
// sent in batch when the network becomes available.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed. The flow is:
- User taps a link → server redirects to the Play Store
- User installs the app and opens it for the first time
- The SDK calls
initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the initialize() call shown above:
(DeepLinkSDK.initialize() as? DeepLinkResult.Matched)?.let {
// Navigate to the content the user originally tapped
navigate(it.data)
}
Kotlin Multiplatform
Installation
// build.gradle.kts (shared module)
val commonMain by getting {
dependencies {
implementation("com.yourorg:deeplink-sdk-kmp:1.0.0")
}
}
Integration
// Shared commonMain code
import com.yourorg.deeplink.DeepLinkSDK
// Configure once at app startup
DeepLinkSDK.configure(
serverUrl = "https://links.yourapp.com",
tenantSlug = "main",
debugLogs = true
)
// Deferred deep link — first launch after install
val result = DeepLinkSDK.initialize()
if (result is DeepLinkResult.Matched) {
navigate(result.data)
}
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
DeepLinkSDK.identify(userId = "user_12345")
Track Custom Events
// Simple event
DeepLinkSDK.trackEvent(name = "signup")
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
DeepLinkSDK.trackEvent(
name = "purchase",
properties = mapOf("product_id" to "abc"),
revenue = 29.99,
currency = "EUR"
)
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// Events tracked while offline are persisted to platform storage
// and sent in batch when the network becomes available.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed:
- User taps a link → server redirects to the App Store / Play Store
- User installs the app and opens it for the first time
- The SDK calls
initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the initialize() call shown above:
val result = DeepLinkSDK.initialize()
if (result is DeepLinkResult.Matched) {
navigate(result.data)
}
React Native
Installation
npm install @deeplink/react-native-sdk
# iOS: pod install
Integration
import { DeepLinkSDK } from '@deeplink/react-native-sdk';
import { Linking } from 'react-native';
// In App.tsx
useEffect(() => {
DeepLinkSDK.configure({
serverUrl: 'https://links.yourapp.com',
tenantSlug: 'main',
});
// (1) Deferred deep link
DeepLinkSDK.initialize().then(result => {
if (result.matched) navigate(result.data.customData);
});
// (2) Universal Link / App Link
const sub = Linking.addEventListener('url', ({ url }) => {
DeepLinkSDK.handleOpenURL(url).then(result => {
if (result.matched) navigate(result.data.customData);
});
});
return () => sub.remove();
}, []);
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
DeepLinkSDK.identify('user_12345');
Track Custom Events
// Simple event
DeepLinkSDK.trackEvent('signup');
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
DeepLinkSDK.trackEvent('purchase', { product_id: 'abc' }, 29.99);
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// The native modules on both iOS and Android persist events
// to disk and send them in batch when the network returns.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed:
- User taps a link → server redirects to the App Store / Play Store
- User installs the app and opens it for the first time
- The SDK calls
initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the initialize() call shown above:
DeepLinkSDK.initialize().then(result => {
if (result.matched) navigate(result.data.customData);
});
Flutter
Installation
# pubspec.yaml
dependencies:
deeplink_sdk: ^1.0.0
Integration
import 'package:deeplink_sdk/deeplink_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
DeepLinkSDK.configure(
serverUrl: 'https://links.yourapp.com',
tenantSlug: 'main',
);
runApp(const MyApp());
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// Deferred deep link
DeepLinkSDK.initialize().then((result) {
if (result.matched) navigate(result.data!.customData);
});
// Universal / App Links
DeepLinkSDK.onLink.listen((result) {
if (result.matched) navigate(result.data!.customData);
});
}
}
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
DeepLinkSDK.identify(userId: 'user_12345');
Track Custom Events
// Simple event
DeepLinkSDK.trackEvent('signup');
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
DeepLinkSDK.trackEvent(
'purchase',
properties: {'product_id': 'abc'},
revenue: 29.99,
);
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// Events tracked while offline are persisted to disk and
// sent in batch when the network becomes available.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed:
- User taps a link → server redirects to the App Store / Play Store
- User installs the app and opens it for the first time
- The SDK calls
initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the initialize() call shown above:
DeepLinkSDK.initialize().then((result) {
if (result.matched) navigate(result.data!.customData);
});
Web JS
Installation
npm install @deeplink/web-sdk
Integration
import { DeepLinkSDK } from '@deeplink/web-sdk';
const sdk = new DeepLinkSDK({
serverUrl: 'https://links.yourapp.com',
tenantSlug: 'main',
});
// Track a page view impression
await sdk.recordImpression({ linkSlug: 'summer-sale' });
// Create a link (requires API key)
const link = await sdk.createLink({
title: 'Summer Sale',
webUrl: 'https://example.com/sale',
}, apiKey);
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
await sdk.identify('user_12345');
Track Custom Events
// Simple event
await sdk.trackEvent('signup');
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
await sdk.trackEvent('purchase', { product_id: 'abc' }, 29.99);
Offline Queue
Events are queued in localStorage when the browser is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// The SDK listens for the 'online' event and flushes
// queued events from localStorage in a single batch.
Server-Side SDKs (Node.js / Python / Go)
Node.js
npm install @deeplink/node-sdk
import { DeepLinkClient } from '@deeplink/node-sdk';
const client = new DeepLinkClient({
serverUrl: 'https://links.yourapp.com',
apiKey: process.env.DEEPLINK_API_KEY,
});
const link = await client.links.create({
title: 'Welcome Email',
webUrl: 'https://example.com/welcome',
campaign:'onboarding',
});
console.log(link.shortUrl);
Python
pip install deeplink-sdk
from deeplink_sdk import DeepLinkClient
client = DeepLinkClient(
server_url="https://links.yourapp.com",
api_key=os.environ["DEEPLINK_API_KEY"],
)
link = client.links.create(
title="Welcome Email",
web_url="https://example.com/welcome",
campaign="onboarding",
)
print(link.short_url)
Go
go get github.com/your-org/deeplink-sdk-go
import "github.com/your-org/deeplink-sdk-go/deeplink"
client := deeplink.NewClient(deeplink.Config{
ServerURL: "https://links.yourapp.com",
APIKey: os.Getenv("DEEPLINK_API_KEY"),
})
link, err := client.Links.Create(ctx, deeplink.CreateLinkRequest{
Title: "Welcome Email",
WebURL: "https://example.com/welcome",
Campaign: "onboarding",
})
Identify User (Server-Side)
Associate a user ID with events for better attribution and cohort tracking. Without this, users are identified by IP hash, which degrades cohort and LTV accuracy.
Node.js
await client.identify('user_12345');
Python
client.identify("user_12345")
Go
client.Identify(ctx, "user_12345")
Track Custom Events (Server-Side)
The revenue parameter feeds into LTV/ROAS calculations.
Node.js
// Simple event
await client.trackEvent('signup');
// Event with properties and revenue
await client.trackEvent('purchase', { product_id: 'abc' }, 29.99);
Python
# Simple event
client.track_event("signup")
# Event with properties and revenue
client.track_event(
"purchase",
properties={"product_id": "abc"},
revenue=29.99,
)
Go
// Simple event
client.TrackEvent(ctx, "signup", nil, 0)
// Event with properties and revenue
client.TrackEvent(ctx, "purchase", map[string]string{
"product_id": "abc",
}, 29.99)
Unity (C#)
Installation
Import the .unitypackage from the releases page, or add via the Unity Package Manager using the git URL.
Integration
using DeepLink;
public class GameManager : MonoBehaviour
{
async void Start()
{
DeepLinkSDK.Configure(
serverUrl: "https://links.yourapp.com",
tenantSlug: "main",
debugLogs: Debug.isDebugBuild
);
// Deferred deep link
var result = await DeepLinkSDK.Initialize();
if (result.Matched)
{
HandleDeepLink(result.Data.CustomData);
}
}
void HandleDeepLink(Dictionary<string, string> customData)
{
if (customData.TryGetValue("level", out var level))
SceneManager.LoadScene(level);
}
}
Identify User
// Associate a user ID with the current session for better attribution
// and cohort tracking. Without this, users are identified by IP hash,
// which degrades cohort and LTV accuracy.
DeepLinkSDK.Identify("user_12345");
Track Custom Events
// Simple event
DeepLinkSDK.TrackEvent("signup");
// Event with properties and revenue
// The revenue parameter feeds into LTV/ROAS calculations
DeepLinkSDK.TrackEvent(
"purchase",
properties: new Dictionary<string, string> { ["product_id"] = "abc" },
revenue: 29.99f
);
Offline Queue
Events are queued locally when the device is offline and flushed automatically when connectivity returns. The SDK batches queued events into a single request to POST /api/v1/events/batch.
// No additional code needed — offline queueing is automatic.
// Events tracked while offline are persisted to PlayerPrefs and
// sent in batch when the network becomes reachable.
Deferred Deep Linking
Deferred deep linking handles the case where the app is not yet installed:
- User taps a link → server redirects to the App Store / Play Store
- User installs the app and opens it for the first time
- The SDK calls
Initialize(), which sends aPOST /api/v1/matchrequest with device fingerprint data - The server matches the fingerprint to the original click and returns the link's
custom_data - Your app navigates to the intended content
// This is already handled by the Initialize() call shown above:
var result = await DeepLinkSDK.Initialize();
if (result.Matched)
{
HandleDeepLink(result.Data.CustomData);
}
Custom Data Routing Pattern
custom_data is an arbitrary key-value map stored on each link. Your app decides how to interpret it. Recommended pattern: a screen key plus screen-specific parameters.
// Link created with: custom_data = { "screen": "tab", "tab": "products" }
// iOS Swift router
final class Router: ObservableObject {
@Published var selectedTab: Tab = .home
func navigate(to customData: [String: String]) {
switch customData["screen"] {
case "tab":
if let tab = customData["tab"] {
selectedTab = Tab(rawValue: tab) ?? .home
}
case "product":
if let id = customData["product_id"] {
navigateToProduct(id: id)
}
case "promo":
if let code = customData["code"] {
applyPromoCode(code)
}
default:
break
}
}
}
Additional Methods
| Method | Description |
|---|---|
identify(userId:) | Associates a user ID with the current session for better attribution and cohort tracking. Without this call, users are identified by IP hash which degrades cohort/LTV accuracy |
forceCheck() | Forces initialize() to re-run the /match call (ignores the first-launch flag) — useful for QA/debug |
resetFirstLaunch() | Resets the first-launch flag — for development testing |
setConsent(granted:) | Sets GDPR consent. When false, no fingerprint data is sent and local data is purged |
trackEvent(name:linkSlug:properties:revenue:currency:) | Tracks a custom event attributed to a link |