Install & initialize
Three steps: register the app in your OptoLink org, ship the App Links intent-filter, add the SDK and initialize it. When you're done, a link click opens your app directly and the SDK hands you the link data.
This page covers the app-side work only; step ① is the only part that touches the portal.
Requirements
- minSdk 23 in your app.
- A CLIENT-tier API key (
opl_sdk_…), minted in the OptoLink portal. - An OptoLink backend at v2.1.0 or newer.
- Distribution via Google Play — install-referrer attribution reads the Play Install Referrer.
① Register the app in the portal
During portal onboarding (set up your organization), fill in the ANDROID app config for your org:
| Field | Value | Example |
|---|---|---|
bundleId | Your applicationId, from defaultConfig.applicationId in the module's build.gradle.kts | com.example.shop |
storeUrl | Your Google Play listing URL | https://play.google.com/store/apps/details?id=com.example.shop |
fingerprints[] | SHA-256 fingerprints of the certs that sign your releases | AA:BB:CC:… |
Get the fingerprint of a keystore with keytool:
keytool -list -printcert -jarfile app-release.apk
# or, for the keystore directly:
keytool -list -v -keystore release.keystore -alias your-alias
While testing, also add your debug keystore's fingerprint: debug installs verify App Links against the debug cert, and a build without it falls back to the link disambiguer.
② Add the intent-filter to your manifest
In AndroidManifest.xml, give your launcher activity an android:autoVerify intent-filter for your link domain:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="links.yourdomain.com"
android:scheme="https"
android:pathPrefix="/acme" />
</intent-filter>
Canonical OptoLink links look like https://links.yourdomain.com/acme/shortCode; host plus pathPrefix must cover them.
android:autoVerify makes Android fetch https://links.yourdomain.com/.well-known/assetlinks.json at install time and check that it names your app. The OptoLink backend serves that file for you, built from the AppConfig you registered in step ①; you don't host it. It must contain a statement like:
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.shop",
"sha256_cert_fingerprints": ["AA:BB:CC:…"]
}
}
]
The backend refreshes the file hourly (Cache-Control: max-age=3600), so a freshly registered fingerprint can take up to an hour to reach verifiers. Links you open before verification succeeds still resolve, through the disambiguer instead of a direct app open.
Using OptoLink's default share domain instead of your own? Same intent-filter shape with android:host="<default-domain-host>" and pathPrefix="/acme". The backend serves an aggregated assetlinks.json there, one statement per org with an Android config.
③ Add the dependency and initialize
dependencies {
implementation("com.optomatica:optolink-android:0.1.1")
}
Initialize once, from Application.onCreate:
class App : Application() {
override fun onCreate() {
super.onCreate()
val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
appScope.launch {
OptoLink.initialize(
applicationContext,
OptoLinkConfig(
apiKey = "opl_sdk_…", // CLIENT-tier key from the portal
orgKey = "acme",
baseUrl = "https://api.optolink.app",
),
)
}
}
}
The key has no env-var fallback; orgKey is the middle segment of your canonical links. Point baseUrl at your deployment — https://api.optolink.app is the intended public default, not live yet.
On Android 12+, the first-launch clipboard read shows a system toast ("… pasted from your clipboard"). Expected platform behavior. Set clipboardEnabled = false in OptoLinkConfig to skip the deferred match's clipboard leg.
Verify the wiring by collecting links from an Activity: the quickstart takes it from here.