Skip to main content

Quickstart

One link, two journeys: open it with the app installed (direct App Link), then install the app from a click (deferred match). This picks up after install & initialize — the app config, intent-filter, and SDK initialization are in place.

In the OptoLink portal, create a link with the path /promo/flash-24h. Its canonical URL is https://links.yourdomain.com/acme/<shortCode>; share that URL to a device.

Direct open (app installed)​

With the app already installed, tap the link in Chrome. Android verifies the autoVerify intent-filter, opens your activity directly, and hands it the Intent. Forward it and collect:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
OptoLink.instance().handleIntent(intent)
scope.launch {
OptoLink.instance().links.collect { data ->
Log.d("OptoLink", "$data")
}
}
}

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
OptoLink.instance().handleIntent(intent) // warm starts land here
}

Logcat shows the resolved link:

OptoLinkData(linkId=clxk…, path=/promo/flash-24h, params={utm_source=instagram}, matchMethod=DIRECT, confidence=EXACT, isDeferred=false, score=null)

handleIntent is safe to call before initialize finishes; the intent is parked and processed once initialization completes.

Deferred match (install from a click)​

On a device without the app:

  1. Tap the link. The OptoLink redirect page opens and copies a one-time attribution token to the clipboard, then shows the Get it on Google Play button (from your AppConfig storeUrl).
  2. Install and open the app.
  3. On first launch, initialize reads the clipboard token, matches it server-side, and emits the link on links:
OptoLinkData(linkId=clxk…, path=/promo/flash-24h, params={utm_source=instagram}, matchMethod=CLIPBOARD, confidence=EXACT, isDeferred=true, score=null)
note

On Android 12+, the first-launch clipboard read shows a system toast ("… pasted from your clipboard"). That toast is the expected output of this test: it confirms the deferred match ran.

The match runs once per install. If the first launch had no network, the opportunity isn't lost: call resolveDeferredLink() later to re-run the match manually; it returns an OptoLinkData? (null = no match) and throws on network failure.

What you have​

Both journeys end in the same place: an OptoLinkData on the links stream, with matchMethod telling you how it arrived. From here:

  • Every method and shape: API reference
  • What throws, what retries: Errors & retries
  • Bind the device to a user or report events with setIdentity / trackEvent — same reference.