# API Reference

## Detour

Main SDK singleton. All methods are `@JvmStatic` for Java interoperability.

### Methods

#### `initialize`

```kotlin
Detour.initialize(context: Context, config: DetourConfig): Unit
```

Initializes the SDK. Must be called once before any other SDK method, usually in `Application.onCreate()` or at the start of your launcher `Activity`. Sets up the internal API client, fingerprint collector, install referrer helper, and analytics subsystem. If `apiKey` or `appId` is blank, the SDK logs an error and does not initialize, and it does not throw.

#### `processLink`

```kotlin
suspend fun Detour.processLink(intent: Intent): LinkResult
```

Main entry point for link processing. Automatically detects the link source from the given `Intent` and returns the appropriate result. Checks in priority order:

1. **App Links**: HTTP/HTTPS URLs from verified domains (returns `LinkType.VERIFIED`)
2. **Scheme links**: custom scheme deep links, if `linkProcessingMode` is `ALL` (returns `LinkType.SCHEME`)
3. **Deferred links**: queries the Detour API on first launch (returns `LinkType.DEFERRED`)

If a web URL has a single path segment (short link), the SDK resolves it to the full destination URL before returning.

For App Links and scheme web URLs, the SDK first verifies the click against your plan's click limit. If the limit is exceeded, the link is not delivered and the result is `LinkResult.NoLink`. See [Click limits](https://detour.swmansion.com/docs/sdk/android/sdk-usage#click-limits).

#### `getDeferredLink`

```kotlin
suspend fun Detour.getDeferredLink(): LinkResult
```

Resolves deferred links only, ignoring App Links and scheme links. Useful when you handle other link types separately. Returns `LinkResult.NotFirstLaunch` on subsequent calls within the same session, because deferred matching runs only once per app install.

#### `resolveShortLink`

```kotlin
suspend fun Detour.resolveShortLink(url: String): ShortLinkResponse?
```

Resolves a Detour short link URL to its full destination. Returns `null` if resolution fails or the URL is not a valid short link.

## DetourDelegate

Lifecycle-aware helper that wraps `Detour.processLink()` for `Activity` / `Fragment` integrations. Manages coroutine scope internally and delivers results via callback.

### Constructor

```kotlin
DetourDelegate(
    lifecycleOwner: LifecycleOwner,
    config: DetourConfig,
    onLinkResult: (LinkResult) -> Unit,
)
```

<PropertyList>
  <Property name="lifecycleOwner" type={"LifecycleOwner"}>
    The Activity, AppCompatActivity or Fragment that owns this delegate.
  </Property>
  <Property name="config" type={"DetourConfig"} typeHref="#detourconfig">
    SDK configuration. Also used to call `Detour.initialize()` if the SDK is not initialized yet.
  </Property>
  <Property name="onLinkResult" type={"(LinkResult) -> Unit"}>
    Callback invoked with the link processing result.
  </Property>
</PropertyList>

### Methods

#### `onCreate`

```kotlin
fun onCreate(intent: Intent): Unit
```

Call from `Activity.onCreate()`. Processes the launching intent for App Links, scheme links, and deferred links.

#### `onNewIntent`

```kotlin
fun onNewIntent(intent: Intent): Unit
```

Call from `Activity.onNewIntent()`. Processes links received while the app is already running.

## DetourConfig

SDK configuration object. Accepts required credentials and optional behavioral settings.

### Data class

```kotlin
data class DetourConfig(
    val apiKey: String,
    val appId: String,
    val linkProcessingMode: LinkProcessingMode = LinkProcessingMode.ALL,
    val storage: DetourStorage? = null,
)
```

<PropertyList>
  <Property name="apiKey" type={"String"} required>
    Publishable API key from the Detour Dashboard. Sent as a Bearer token on every API call: deferred link matching, short-link resolution, and analytics.
  </Property>
  <Property name="appId" type={"String"} required>
    Unique app identifier from the Detour Dashboard. Routes API requests to the correct app.
  </Property>
  <Property
    name="linkProcessingMode"
    type={"LinkProcessingMode"}
    typeHref="#linkprocessingmode"
    default={"LinkProcessingMode.ALL"}
  >
    Which link sources the SDK processes. See [LinkProcessingMode](#linkprocessingmode) for each value.
  </Property>
  <Property
    name="storage"
    type={"DetourStorage?"}
    typeHref="#detourstorage"
    default={"null"}
  >
    Custom storage adapter for SDK persistence. The SDK stores a first-entrance flag (for deferred link matching) and a device ID (for analytics). Left `null`, it falls back to a SharedPreferences-based implementation.
  </Property>
</PropertyList>

### Java builder

For Java callers, a builder pattern is available:

```kotlin
DetourConfig.Builder(apiKey: String, appId: String)
    .linkProcessingMode(LinkProcessingMode)
    .storage(DetourStorage)
    .build()
```

## LinkResult

Sealed class returned by `processLink()` and `getDeferredLink()`. Pattern-match on the subtype to handle each outcome.

```kotlin
sealed class LinkResult {
    data class Success(
        val url: String,
        val route: String,
        val pathname: String,
        val type: LinkType,
        val params: Map<String, String>,
    ) : LinkResult()

    data object NotFirstLaunch : LinkResult()
    data object NoLink : LinkResult()
    data class Error(val exception: Exception) : LinkResult()
}
```

### Subtypes

| Subtype | Description |
| --- | --- |
| `Success` | A link was successfully resolved. Contains the parsed link data, listed below |
| `NotFirstLaunch` | No deferred link available because this is not the first app launch. Only returned by the deferred link flow |
| `NoLink` | Normal app launch without any deep link |
| `Error` | An error occurred during link processing. The `exception` field contains the cause |

### Success fields

<PropertyList>
  <Property name="url" type={"String"}>
    Full URL that was matched or opened.
  </Property>
  <Property name="route" type={"String"}>
    In-app route for navigation, as a path with query string, first path segment (app hash) stripped (e.g. `/promo/123?utm=1`).
  </Property>
  <Property name="pathname" type={"String"}>
    Route path without query string (e.g. `/promo/123`).
  </Property>
  <Property name="type" type={"LinkType"} typeHref="#linktype">
    How the link arrived: `DEFERRED`, `VERIFIED`, or `SCHEME`.
  </Property>
  <Property name="params" type={"Map<String, String>"}>
    Parsed query parameters as key-value pairs.
  </Property>
</PropertyList>

## LinkProcessingMode

```kotlin
enum class LinkProcessingMode {
    ALL,
    WEB_ONLY,
    DEFERRED_ONLY,
}
```

Controls which link sources `Detour.processLink()` handles:

| Value | Behavior |
| --- | --- |
| `ALL` (default) | Processes all link sources: deferred links from the Detour API, App Links (verified HTTP/HTTPS URLs), and custom scheme deep links |
| `WEB_ONLY` | Same as `ALL` but filters out custom scheme links. Only deferred links and App Links (HTTP/HTTPS) are processed |
| `DEFERRED_ONLY` | Only processes deferred links from the Detour API. Skips App Link and scheme link detection. Recommended when your navigation framework already handles runtime deep links |

## LinkType

```kotlin
enum class LinkType {
    DEFERRED,
    VERIFIED,
    SCHEME,
}
```

Describes how the link arrived in the app:

| Value | Meaning |
| --- | --- |
| `DEFERRED` | The link was obtained from the Detour deferred-link API. This happens when a user who does not have the app installed clicks a Detour link, installs the app, and opens it. The SDK retrieves the original link from the backend on first launch |
| `VERIFIED` | The link arrived as an Android App Link, an HTTP/HTTPS URL from a verified domain that the OS delivered directly to your app |
| `SCHEME` | The link arrived via a custom URL scheme (e.g. `myapp://path`). These are non-HTTP URLs that the OS routes to your app based on the registered intent filter |

## ShortLinkResponse

```kotlin
data class ShortLinkResponse(
    val link: String,
    val route: String?,
    val parameters: String?,
)
```

Returned by `Detour.resolveShortLink()`.

<PropertyList>
  <Property name="link" type={"String"}>
    The full destination URL after short-link resolution.
  </Property>
  <Property name="route" type={"String?"}>
    Extracted in-app route, or `null` if not available.
  </Property>
  <Property name="parameters" type={"String?"}>
    Raw query parameter string, or `null` if none.
  </Property>
</PropertyList>

## DetourStorage

```kotlin
interface DetourStorage {
    suspend fun getItem(key: String): String?
    suspend fun setItem(key: String, value: String)
    suspend fun removeItem(key: String) { }
}
```

Interface for custom storage adapters. The SDK persists a first-entrance flag (used for deferred link matching, which only runs on first app install) and a stable device ID (used for analytics). All methods are suspending functions.

By default, the SDK uses a SharedPreferences-based implementation. Provide a custom adapter if you need encrypted storage, DataStore, or another persistence layer. See [Custom Storage](https://detour.swmansion.com/docs/sdk/android/custom-storage) for examples.

## DetourAnalytics

Analytics module initialized by `Detour.initialize()`. All calls are fire-and-forget. They run on a background dispatcher and never propagate exceptions. Both methods are `@JvmStatic` for Java interoperability.

### Methods

#### `logEvent`

```kotlin
DetourAnalytics.logEvent(eventName: DetourEventNames, data: Any? = null): Unit
```

Records a user action or custom event and sends it to the Detour backend. Pass one of the predefined [`DetourEventNames`](#detoureventnames) values. The optional `data` parameter accepts any Gson-serializable object (maps, primitives, data classes, etc.).

#### `logRetention`

```kotlin
DetourAnalytics.logRetention(eventName: String): Unit
```

Records a retention/lifecycle event for user engagement tracking with a free-form event name string.

### Automatic events

Besides the events you log manually, the SDK reports some on its own, with no wiring needed:

- `app_open` — a retention event logged once per session when `Detour.initialize()` runs on a cold start.

App Link and Universal Link opens are recorded server-side through a dedicated click endpoint (see [Click limits](https://detour.swmansion.com/docs/sdk/android/sdk-usage#click-limits)) rather than as a client event.

All API requests the SDK sends also include an `X-SDK: android/<version>` header for diagnostics and SDK-usage analysis. It requires no configuration.

## DetourEventNames

| Category | Event Name | String Value |
| :--- | :--- | :--- |
| **General** | `Login` | `login` |
|  | `Search` | `search` |
|  | `Share` | `share` |
|  | `SignUp` | `sign_up` |
|  | `TutorialBegin` | `tutorial_begin` |
|  | `TutorialComplete` | `tutorial_complete` |
|  | `ReEngage` | `re_engage` |
|  | `Invite` | `invite` |
|  | `OpenedFromPushNotification` | `opened_from_push_notification` |
| **Sales** | `AddPaymentInfo` | `add_payment_info` |
|  | `AddShippingInfo` | `add_shipping_info` |
|  | `AddToCart` | `add_to_cart` |
|  | `RemoveFromCart` | `remove_from_cart` |
|  | `Refund` | `refund` |
|  | `ViewItem` | `view_item` |
|  | `BeginCheckout` | `begin_checkout` |
|  | `Purchase` | `purchase` |
|  | `AdImpression` | `ad_impression` |

## Related pages

- [Usage](https://detour.swmansion.com/docs/sdk/android/sdk-usage)
- [Custom Storage](https://detour.swmansion.com/docs/sdk/android/custom-storage)
- [Testing & Troubleshooting](https://detour.swmansion.com/docs/sdk/android/testing)