Certainty at the one boundary the platforms don't cover.
Initialise once, listen to one stream, and get told how the answer was reached. There is very little surface area here — the complexity belongs on our side of the boundary.
What you are actually integrating against
Universal Links and App Links are already solved for you when the app is installed. Everything difficult lives in the minutes where it isn't — the user is in the App Store, your process does not exist, and there is nowhere on the device the destination is allowed to live. Every deep-linking SDK claims to close that gap. The question worth asking a vendor is what happens when it can't close it cleanly.
- No payload survives the store
- iOS and Android hand off to the store with no channel back into a process that has not launched yet.
- The click and the open are separate events
- Minutes apart, different network, sometimes a different OS version. Nothing links them by default.
- Silence is indistinguishable from success
- A user landing on your home screen looks exactly like a user who wanted your home screen.
Four beats, start to finish
Click
The redirect records the click on your domain with whatever the device offers, then hands off.
Install
The store round-trip. Minutes may pass. Nothing of yours is running.
Launch
OptoLink.initialize() runs before runApp() and the chain resolves the pending journey.
Route
One event on onLink carries path, params, method and confidence. You navigate.
What you get told, and how sure it is
The chain stops at the first method that answers. The result carries which one it was, so you can treat a deterministic match differently from a network-level guess — gate a discount on exact, and merely navigate on low.
- A token the phone carriesexact
- The store's own receipthigh
- The device, exactly as it washigh
- The device, mostly as it wasmedium
- The last thing we knowlow
- OptoLink.initialize(config) before runApp() — apiKey and orgKey both required.
- One Stream<OptoLinkData> delivers direct and deferred links to the same handler.
- Every event carries path, params, matchType, confidence, isDeferred and linkId.
- getInitialLink() for cold starts; resolveDeferredLink() to run the chain explicitly.
- clipboardEnabled: false skips the iOS 16+ paste banner without disabling the rest.
- A logger hook forwards diagnostics to Crashlytics, Sentry, or your own sink.
// main.dart — before runApp()
await OptoLink.initialize(
OptoLinkConfig(
apiKey: 'ol_live_…',
orgKey: 'acme',
clipboardEnabled: true, // false skips the iOS 16+ paste banner
),
);
// One stream. Direct opens and deferred installs arrive the same way.
OptoLink.instance.onLink.listen((OptoLinkData link) {
if (link.confidence == 'exact') {
grantReferralCredit(link.params['ref']);
}
router.go(link.path, extra: link.params);
});
Branching on confidence is the reason it is in the payload. A referral credit should require a deterministic match; navigation does not.
Where it runs
iOS
13+, via the Flutter SDK
Android
API 21+, Kotlin plugin for the store referrer
Flutter
v1.0.0 — the shipping SDK
React Native
Roadmap — not shipped
Web
Redirect and resolution endpoints
Every link finds its exact destination.
Bring us the journey that keeps breaking — the campaign that can't prove its installs, the printed code that lands on a home screen, the checkout link that only works for people who already have the app.
Optolink is built and operated by Optomatica



