Skip to main content

API reference & changelog

optolink_flutter 2.0.0 exports one entry point (OptoLink) and its config, data, and error types from package:optolink_flutter/optolink_flutter.dart. The public Dart API is source-compatible with 1.x; setup lives in install & initialize.

// ---------- entry point ----------
class OptoLink {
/// The one throwing API: config errors (native `invalid_argument`,
/// e.g. a malformed baseUrl) and any native init failure — including
/// a missing native plugin — surface as a thrown OptoLinkError.
/// A failed call resets the singleton, so retry is allowed. Repeat
/// calls after success return the same instance.
static Future<OptoLink> initialize(OptoLinkConfig config);

/// StateError before initialize — programming error.
static OptoLink get instance;

/// The most recent channel failure, or null when the last call
/// succeeded. Set on every rejected call; cleared on the next success.
static OptoLinkError? get lastError;

/// Stable per-install device ID (minted natively); null before initialize.
String? get deviceId;
OptoLinkConfig get config;

/// Deferred + warm direct links. Cold-start direct links NEVER appear
/// here (see the delivery rule on handle deep links). The deferred
/// link resolved inside initialize replays to the first subscriber.
/// Malformed payloads are logged at warning and dropped — the stream
/// never throws.
Stream<OptoLinkData> get onLink;

/// The cold-start direct link, natively resolved. Idempotent. Null when
/// the app was not deep-link-launched — or on channel failure, with
/// lastError set.
Future<OptoLinkData?> getInitialLink();

/// Manual re-attempt of the deferred flow (the automatic run happens
/// natively on first launch). Null on no-match or failure + lastError.
Future<OptoLinkData?> resolveDeferredLink();

// ---- identity & events: Future<bool> is channel success; false only
// on native error (details in lastError) or a missing plugin. ----
Future<bool> setIdentity(String externalId);
Future<bool> clearIdentity();

/// Property values coerced to strings at the channel edge (the natives
/// are String→String); null values dropped; each change logged at info.
Future<bool> trackEvent(String eventName, {Map<String, dynamic>? properties});

/// Resets the Dart client only — native state is process-owned.
void dispose();
}

What each call returns​

CallSuccessFailure
initialize(config)Instance returned, deviceId setThrows OptoLinkError (bad config, native init failure, missing plugin); singleton reset so retry works
getInitialLink() / resolveDeferredLink()OptoLinkData?null + lastError set
setIdentity / clearIdentity / trackEventtruefalse + lastError set
onLinkone stream, replay-lastnever throws; malformed payloads logged and dropped

Config​

class OptoLinkConfig {
final String apiKey; // CLIENT-tier opl_sdk_… key from the portal
final String orgKey; // the /orgKey/ segment of your short URLs
final String baseUrl; // your OptoLink origin — serves your short links and /match
final Duration timeout; // default 10 s, per HTTP attempt
final int maxRetries; // default 2, native exponential backoff
final bool clipboardEnabled; // default true; false skips the clipboard leg
final OptoLinkLogger? logger; // default null
}

typedef OptoLinkLogger = void Function(
OptoLinkLogLevel level, String message, {Object? error});
enum OptoLinkLogLevel { info, warning, error }

baseUrl is a String, not a Uri: the native side validates it, and a malformed value makes initialize throw.

OptoLinkData​

class OptoLinkData {
final String? linkId; // null for direct links not resolved server-side
final String path; // e.g. /promo/flash-24h
final Map<String, dynamic>? params;
final String matchType; // raw wire string, values below
final MatchConfidence confidence; // exact | high | medium | low
final int? score; // FINGERPRINT_SCORED matches only, 0–100
final bool isDeferred;
}

enum MatchConfidence { exact, high, medium, low }

matchType values​

ValueMeaningconfidencescore
DIRECTUniversal Link / App Link openexactnull
CLIPBOARDClipboard token on first launchexactnull
INSTALL_REFERRERPlay Install Referrer (Android only)exactnull
FINGERPRINT_EXACTAll device attributes matched exactlyhighnull
FINGERPRINT_SCOREDWeighted scoring across attributeshigh / medium / low0–100
IP_FUZZYSame IP onlylownull

matchType carries the native wire string verbatim ('unknown' if a payload omits it). An unrecognized confidence value falls back to medium.

OptoLinkError​

Surfaced via OptoLink.lastError and thrown by initialize; nothing else throws.

class OptoLinkError {
final int? status; // HTTP status when server-side
final String message;
final String? requestId; // support correlation
final int? retryAfterSeconds; // when throttled
final List<Map<dynamic, dynamic>>? details; // 400 validation entries
final bool isConnectionError; // timeout / unreachable host
}

Logging​

LevelMeaning
infoProgress trail: init summary (key redacted), per-rung deferred decisions, HTTP request lines, link emissions
warningTransient failure; the native SDK will retry
errorTerminal failure; the SDK gave up

With a logger wired, native onLog entries and Dart-edge events (coercions, failures) all reach it. Without one, entries go to debugPrint in debug builds only; production is silent unless a logger is wired.

Changelog​

The plugin runs its own semver clock; a breaking change in the native SDKs or the backend forces a plugin major. The 2.0.0 behavioral deltas and their migration notes: Migrating from 1.x.

  • 2.0.0 — converted to a thin channel client over the native OptoLink SDKs (Swift on iOS — resolved via SPM or vendored for CocoaPods apps; Kotlin via Maven Central). API source-compatible with 1.x. Added OptoLinkData.score, OptoLink.lastError + OptoLinkError, the info log level. Removed DeviceIdStore and the OptoLinkData factories; cold-start direct links now arrive only via getInitialLink(). New floors: Flutter 3.38.0, iOS 15.0, Android minSdk 23. Zero Dart dependencies.
  • 1.2.0 — trackEvent(name, {properties}) custom events, capped at 10 KiB serialized.
  • 1.1.0 — deviceId, setIdentity / clearIdentity, automatic session registration on app open.
  • 1.0.0 — initial release: direct links, deferred pipeline, confidence levels, logger hook.