Skip to main content

API reference

com.optomatica:optolink-android exposes one entry point, OptoLink, plus its config, data, and error types, all under com.optomatica.optolink (errors under com.optomatica.optolink.error). Setup and initialization live in install & initialize; failure behavior in errors & retries.

The surface is Kotlin-first: suspend functions and Flow. There is no builder, no listener API, and no Java async variants.

// ---------- entry point ----------
class OptoLink private constructor(context, config) {
companion object {
/** Idempotent, concurrency-safe; awaits the once-per-install deferred match.
* Network failure during match: logged, NOT thrown
* (never blocks startup; re-attempt via resolveDeferredLink). */
suspend fun initialize(context: Context, config: OptoLinkConfig): OptoLink
fun instance(): OptoLink // IllegalStateException if not initialized
}
val deviceId: String // UUID v4, persisted
val config: OptoLinkConfig

// ---------- links ----------
/** SharedFlow(replay = 1): the deferred link replays to the first collector.
* Never errors — failures log via config.logger. */
val links: Flow<OptoLinkData>
/** Forward from Activity.onCreate AND onNewIntent.
* Safe to call before initialize completes — the latest intent is
* parked and processed once initialization finishes. */
fun handleIntent(intent: Intent)
/** Manual deferred re-attempt. null = no match;
* throws on network failure. */
suspend fun resolveDeferredLink(): OptoLinkData?

// ---------- identity & events (throw on failure) ----------
suspend fun setIdentity(externalId: String)
suspend fun clearIdentity()
suspend fun trackEvent(name: String,
properties: Map<String, String> = emptyMap())

fun dispose()
}

// ---------- data ----------
data class OptoLinkData(
val linkId: String?, // null for raw direct links
val path: String,
val params: Map<String, String>?, // verified flat string→string on the wire
val matchMethod: MatchMethod,
val confidence: MatchConfidence,
val isDeferred: Boolean,
val score: Int? = null, // backend matchScore: present only on FINGERPRINT_SCORED
)
enum class MatchMethod { CLIPBOARD, INSTALL_REFERRER,
FINGERPRINT_EXACT, FINGERPRINT_SCORED, IP_FUZZY,
DIRECT, NONE }
enum class MatchConfidence { EXACT, HIGH, MEDIUM, LOW }

// ---------- errors (two-class model, JVM naming) ----------
sealed class OptoLinkException(message: String) : Exception(message)
class OptoLinkApiException(
val status: Int,
val requestId: String?, // present only when the caller sent x-request-id
val details: List<OptoLinkErrorDetail>?, // 400 validation only
val retryAfterSeconds: Long?, // regexed from the 429 message
val raw: String?, // full body text verbatim
) : OptoLinkException(...)
class OptoLinkConnectionException(cause: IOException) : OptoLinkException(...)
data class OptoLinkErrorDetail(val message: String, val field: String?)

// ---------- config ----------
data class OptoLinkConfig(
val apiKey: String, // CLIENT-tier opl_sdk_… (no env fallback)
val orgKey: String,
val baseUrl: String,
val timeout: Duration = 10.seconds, // per HTTP attempt
val maxRetries: Int = 2,
val clipboardEnabled: Boolean = true, // opt-out of the deferred match's clipboard leg
val logger: OptoLinkLogger? = null, // @JvmOverloads on the constructor
)
fun interface OptoLinkLogger {
fun log(level: OptoLinkLogLevel, message: String, error: Throwable?)
}
enum class OptoLinkLogLevel { INFO, WARNING, ERROR }
SourcematchMethodisDeferred
Verified App Link open, resolution succeededDIRECTfalse
Custom-scheme or non-matching-org open, or backend unreachable at resolve timeDIRECT (linkId = null)false
First-launch clipboard matchCLIPBOARDtrue
First-launch install-referrer matchINSTALL_REFERRERtrue
First-launch fingerprint matchFINGERPRINT_EXACT / FINGERPRINT_SCOREDtrue
First-launch IP matchIP_FUZZYtrue

confidence is backend-reported and applies to deferred matches; direct opens carry EXACT. params is flat string → string and null when the link has none. score carries the backend's numeric match score on FINGERPRINT_SCORED matches only; every other method leaves it null.

Release history: changelog.