# Kotlin / Android

URL: https://pieowl.com/docs/sdks/kotlin





Pieowl doesn't ship a Kotlin or Android SDK. You send events from Kotlin with a plain HTTP request to the [Track API](/docs/api/track). The example below uses `HttpURLConnection` and `org.json`, which are built into Android, so there is nothing to add to Gradle.

<Callout>
  Looking for a step-by-step tutorial? Read the [Kotlin analytics guide](/guides/kotlin-analytics).
</Callout>

Before you start [#before-you-start]

You need a client ID and a client secret. Find them in the dashboard under **Settings → Developers → Keys**. Apps can't send the browser headers Pieowl uses to check where a request comes from, so app requests include the secret.

Add the internet permission to your `AndroidManifest.xml` if your app doesn't have it yet:

```xml
<uses-permission android:name="android.permission.INTERNET" />
```

Send an event [#send-an-event]

Every request is a `POST` to `https://api.pieowl.com/track` with a JSON body of `{ "type": ..., "payload": ... }`. Android doesn't allow network calls on the main thread, so the example uses a coroutine on `Dispatchers.IO`.

```kotlin title="Pieowl.kt"
import java.net.HttpURLConnection
import java.net.URL
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONObject

object Pieowl {
    private const val TRACK_URL = "https://api.pieowl.com/track"
    private const val CLIENT_ID = "YOUR_CLIENT_ID"
    private const val CLIENT_SECRET = "YOUR_CLIENT_SECRET"
    private const val TIMEOUT_MS = 5_000

    suspend fun send(type: String, payload: JSONObject): Int = withContext(Dispatchers.IO) {
        val body = JSONObject().put("type", type).put("payload", payload).toString()
        val connection = URL(TRACK_URL).openConnection() as HttpURLConnection
        try {
            connection.requestMethod = "POST"
            connection.connectTimeout = TIMEOUT_MS
            connection.readTimeout = TIMEOUT_MS
            connection.doOutput = true
            connection.setRequestProperty("Content-Type", "application/json")
            connection.setRequestProperty("pieowl-client-id", CLIENT_ID)
            connection.setRequestProperty("pieowl-client-secret", CLIENT_SECRET)
            connection.outputStream.use { it.write(body.toByteArray()) }
            connection.responseCode
        } finally {
            connection.disconnect()
        }
    }
}
```

Usage [#usage]

Call `send` from a coroutine, for example `lifecycleScope.launch { ... }` in an activity.

Tracking events [#tracking-events]

```kotlin
Pieowl.send("track", JSONObject()
    .put("name", "signup")
    .put("profileId", "user_123") // optional
    .put("properties", JSONObject().put("plan", "pro")))
```

Tracking screen views [#tracking-screen-views]

To fill the pages report, send a `screen_view` event with the screen name in `__path`:

```kotlin
Pieowl.send("track", JSONObject()
    .put("name", "screen_view")
    .put("properties", JSONObject().put("__path", "/settings")))
```

Identifying users [#identifying-users]

```kotlin
Pieowl.send("identify", JSONObject()
    .put("profileId", "user_123") // required
    .put("firstName", "Joe")
    .put("lastName", "Doe")
    .put("email", "joe@doe.com")
    .put("properties", JSONObject().put("tier", "premium")))
```

Incrementing and decrementing properties [#incrementing-and-decrementing-properties]

`value` is optional and defaults to 1.

```kotlin
Pieowl.send("increment", JSONObject()
    .put("profileId", "user_123").put("property", "visits").put("value", 1))
Pieowl.send("decrement", JSONObject()
    .put("profileId", "user_123").put("property", "credits").put("value", 1))
```

Good to know [#good-to-know]

* **Errors:** `send` returns the HTTP status. A `2xx` status means Pieowl accepted the request. Network errors throw an `IOException`, so catch it if analytics must never crash your app.
* **Offline:** Requests fail while the device is offline. If you need offline support, store events and send them later.
* **More event types:** Revenue, groups and the full request schema are in the [Track API reference](/docs/api/track).
