Skip to content

Attributing app opens

A link that opens your app directly never reaches Tolinku. iOS and Android hand the URL straight to the app, the browser never loads, and nothing is recorded.

That is not simply a gap. The taps that go missing are the ones from people who already have your app, so your click figures over-represent everyone else:

Who taps the linkWhat happensCounted by default
Someone with your appthe operating system opens ityes, see below
Someone without your appthe page loads, then the storeyes

Left alone, a campaign aimed at your existing customers reads as a failure exactly when it worked, and any funnel that begins with a click is missing its most engaged people.

Settings → General → App open attribution, on your Appspace. It has three values and is set to Always for a new Appspace.

Tolinku holds the link back from the operating system, so every tap loads the hand-off page and is counted. Nothing needs adding to your app and nothing needs releasing.

Your app opens a moment after the tap rather than instantly, and on iOS the visitor confirms once. These taps count and bill as clicks.

This overrides Universal Links / App Links on every route: one route opening the app directly would be a gap in the same guarantee.

Your app opens instantly, and a tap counts where your app calls trackLinkOpen. Until that is written and released, taps from people who already have your app are not counted, and campaigns aimed at them look like they got no traffic.

None of them are counted, ever, and campaigns aimed at people who already have your app will always look like they got no traffic. They cost nothing.

Needed for Only when your app reports it, and harmless under the other two. Call it wherever your app receives an incoming link.

A link arrives in two places, and both need it. A link that launches the app cold arrives somewhere different from one tapped while the app is already running, and instrumenting only the second misses the more common case.

// Flutter
final initial = await appLinks.getInitialAppLink();
if (initial != null) Tolinku.instance.trackLinkOpen(initial.toString());
appLinks.uriLinkStream.listen((uri) {
Tolinku.instance.trackLinkOpen(uri.toString());
});
// Android
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent?.data?.let { lifecycleScope.launch { Tolinku.trackLinkOpen(it.toString()) } }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { lifecycleScope.launch { Tolinku.trackLinkOpen(it.toString()) } }
}
// iOS, which covers both a launch and a resume in one place
func application(_ app: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let url = userActivity.webpageURL {
Task { await Tolinku.shared?.trackLinkOpen(url.absoluteString) }
}
return true
}
// React Native
const initial = await Linking.getInitialURL();
if (initial) Tolinku.trackLinkOpen(initial);
Linking.addEventListener('url', ({ url }) => Tolinku.trackLinkOpen(url));

Wiring both is safe. Some link plugins hand the launching link to the listener as well, and the same link inside a few seconds is reported once rather than counted, and billed, twice.

Only http and https links are reported. A custom scheme means Tolinku’s own hand-off page opened your app, and that tap was counted when the page was served.

The call never throws and never blocks, because it sits on the path that routes somebody somewhere.

An app open costs the same to process and store as any other click, so it counts and bills the same, on the same line.

Your analytics separate them, so a rise in volume is explicable rather than mysterious: web clicks and app opens are shown apart even though they share an allowance.

App opens are deliberately left out of the install funnel. Someone opening your app already has it, so they can never convert to an install, and counting them at the top would inflate the first step and depress every rate below it.

Always if you want the complete picture without touching your app, and can accept your app opening a moment later.

Only when your app reports it if the instant open matters more and you are willing to ship the integration.

Never if you only care about acquiring new customers and would rather not pay to observe the ones you already have.