> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send click and conversion events with InstantSearch Android

> Unlock Algolia's most powerful features by sending click and conversion events from your InstantSearch Android app.

export const UserToken = () => <Tooltip tip="A user token is a pseudonymous ID that represents an individual user across Algolia searches and events. It links queries, clicks, and conversions to a user profile, enabling user-level analytics, personalization, and recommendations." cta="User token" href=" /doc/guides/sending-events/concepts/usertoken">
    user token
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

Events are actions that users take on your app or website.
They unlock powerful features, such as recommendations,
personalization, smarter search results,
and analytics that help you optimize your user experience.
For more information, see [Choose how to send events](/doc/guides/sending-events/getting-started).

To send events from your InstantSearch Android app, follow these steps:

1. Add the `insights` client.
2. Add [click events](#send-click-events) when users click search results.
3. [Track conversions](#send-conversion-events) that start in your InstantSearch app.

## Add the InstantSearch Insights library

Add the library as a dependency to your `build.gradle` file:

```groovy Gradle theme={"system"}
implementation "com.algolia:instantsearch-insights-android:4.+"
```

## Add the Insights client

To add the Insights client, you'll need your Algolia application ID, (search) API key, and the <Index /> name.
You can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account/api-keys).

```kotlin Kotlin theme={"system"}
val appID = "applicationID"
val apiKey = "apiKey"
val indexName = "indexName"
val configuration = Insights.Configuration(
    connectTimeoutInMilliseconds = 5000,
    readTimeoutInMilliseconds = 5000
)

registerInsights(context, appID, apiKey, indexName, configuration)
```

To send events without timestamps, and be automatically attributed on the server, set the `generateTimestamps` parameter to `false`:

```kotlin Kotlin theme={"system"}
val configuration = Insights.Configuration(generateTimestamps = false)
registerInsights(context, appID, apiKey, indexName, configuration)
```

## Set the user token

All events must have a <UserToken /> to specify the user it relates to.
You can set it in three ways:

* Globally, for all events
* Per app, for every event tracked by the app
* Individually, for each event

```kotlin Kotlin theme={"system"}
// Global userToken default value
val configuration = Insights.Configuration(
    connectTimeoutInMilliseconds = 5000,
    readTimeoutInMilliseconds = 5000,
    defaultUserToken = "userToken"
)
registerInsights(context, appID, apiKey, indexName, configuration)

// App userToken overrides global default
sharedInsights(indexName).apply {
    userToken = "userToken"
}

// Event userToken overrides previous defaults
sharedInsights?.clickedObjectIDsAfterSearch(
    eventName = "eventName",
    indexName = "indexName",
    userToken = "userToken",
    timestamp = System.currentTimeMillis(),
    queryID = "queryId",
    objectIDs = listOf("objectID1"),
    positions = listOf(1)
)
```

### User opt-out

You can exclude users who opted out from tracking with the following code:

```kotlin Kotlin theme={"system"}
sharedInsights(indexName)?.enabled = false
// Alternatively, by getting the latest registered Insights instance
sharedInsights?.enabled = false
```

## Enable automatic view events tracking

InstantSearch can automatically send view events when hits are returned from Algolia. To enable this feature, set `isAutoSendingHitsViewEvents` to `true` when you initialize [`HitsSearcher`](/doc/api-reference/widgets/instantsearch/android#hitssearcher):

```kotlin Kotlin theme={"system"}
val searcher = HitsSearcher(
  applicationID = "ALGOLIA_APPLICATION_ID",
  apiKey = "ALGOLIA_SEARCH_API_KEY",
  indexName = "indexName",
  isAutoSendingHitsViewEvents = true
)
```

## Create a `HitsTracker` to track events from search results

```kotlin Kotlin theme={"system"}
val hitsTracker = HitsTracker(
    eventName = "hits",
    searcher = searcher,
    insights = sharedInsights(indexName)
)
```

## Create a `FilterTracker` to track events from filters

```kotlin Kotlin theme={"system"}
val filterTracker = FilterTracker(
    eventName = "demo",
    searcher = searcher,
    insights = sharedInsights(indexName)
)
```

## Send events

Use the `trackView`, `trackClick`, and `trackConversion` methods to send events.
When you add events, check them in the [**Events Debugger**](https://dashboard.algolia.com/events/debugger) in the Algolia dashboard.
For more information, see [Validate your events](/doc/guides/sending-events/guides/validate).

### Send view events

```kotlin Kotlin theme={"system"}
// HitsTracker
hitsTracker.trackView(hit)

// FilterTracker
filterTracker.trackView(facet)
```

### Send click events

```kotlin Kotlin theme={"system"}
// HitsTracker
hitsTracker.trackClick(hit, position)

// FilterTracker
filterTracker.trackClick(facet)
```

### Send conversion events

```kotlin Kotlin theme={"system"}
// HitsTracker
hitsTracker.trackConvert(hit)

// FilterTracker
filterTracker.trackConversion(facet)
```

<Info>
  If you upgraded from InstantSearch Android 3.x to 4.x:

  * Your hit model must include an `objectID` and implement the [Indexable interface](/doc/guides/building-search-ui/upgrade-guides/android#indexable-interface).
  * Facet results are now `FacetHits` (they used to be `Facet`).
</Info>

Conversions often happen outside your search pages.
For example, the Order completed event for a successful purchase happens in the shopping cart.
To capture these conversions, [keep track of the query ID](/doc/guides/sending-events/guides/queryid) across your app.

### Event batching

By default, events are sent in batches of 10.
To customize this, adjust the `minBatchSize` parameter:

```kotlin Kotlin theme={"system"}
// Customize at registration
registerInsights(context, appID, apiKey, indexName, configuration).apply {
    minBatchSize = 1
}
// Customize by getting shared insights
sharedInsights(indexName).apply {
    minBatchSize = 1
}
```

## Enable logging

You can also check if you've sent an event by enabling logging:

```kotlin Kotlin theme={"system"}
// Check at insights registration
registerInsights(context, appID, apiKey, indexName, configuration).apply {
    loggingEnabled = true
}
// Check by getting shared insights
sharedInsights(indexName).apply {
    loggingEnabled = true
}
```

After you've enabled it, check the output for success messages or errors.

```txt theme={"system"}
// Success
[Algolia Insights - appName] Sync succeded for EventsPackage(id: "37E9A093-8F86-4049-9937-23E99E4E4B33", events: [{
    eventName = "search result click";
    eventType = click;
    index = "my index";
    objectIDs =     (
        1234567
    );
    positions =     (
        3
    );
    queryID = 08a76asda34fl30b7d06b7aa19a9e0;
    timestamp = 1545069313405;
    userToken = "C1D1322E-8CBF-432F-9875-BE3B5AFDA498";
}], region: nil)

//Error
[Algolia Insights - appName] The objectID field is missing (Code: 422)
```

<Note>
  For the `positions` parameter of the [`clickedObjectIdsAfterSearch`](/doc/libraries/sdk/v1/methods/clicked-object-ids-after-search) method, the first object in the list of search results has a value of 1 (not 0), the second has a value of 2.
</Note>
