SignalSeal Docs

Android

Install the SignalSeal Android SDK in your Kotlin or Java app.

The SignalSeal Android SDK reports installs, sends events, and powers in-app attribution.

Requirements

  • Android 5.0 (API 21) or higher
  • Kotlin or Java 17 toolchain

Install

Add the SDK to your app module's build.gradle.kts:

dependencies {
  implementation("io.github.signalseal:signalseal-android-sdk:0.2.5")
}

Or in build.gradle:

dependencies {
  implementation 'io.github.signalseal:signalseal-android-sdk:0.2.5'
}

The SDK declares INTERNET, ACCESS_NETWORK_STATE, and com.google.android.gms.permission.AD_ID permissions in its manifest; they merge into your app automatically.

Initialize

Call configure(...) once in Application.onCreate().

import net.signalseal.attribution.SignalSealSDK

class MyApp : Application() {
  override fun onCreate() {
    super.onCreate()
    SignalSealSDK.configure(
      context = this,
      apiKey = "ak_android_..."
    )
  }
}

Don't forget to register your Application class in the manifest:

<application android:name=".MyApp" ... >

Configuration parameters

fun configure(
  context: Context,
  apiKey: String,
  isDebug: Boolean = false,
  endpointBaseUrl: String = DEFAULT_ENDPOINT_BASE_URL,
  logLevel: LogLevel = LogLevel.INFO,
  listener: InitListener? = null,
  customerUserId: String? = null,
  environment: SignalSealEnvironment? = null,
  respectLimitAdTracking: Boolean = true,
)
ParameterTypeDescription
contextContextRequired. Your Application context.
apiKeyStringRequired. Your Android SDK key (ak_android_…) from Settings → SDK.
isDebugBooleanDefaults to false. When true, every event is tagged is_debug so it's visible in the Live Feed but not forwarded to ad networks.
endpointBaseUrlStringOverride the ingestion URL. Leave unset unless SignalSeal told you to set it. Must end with /.
logLevelLogLevelDefaults to INFO. One of DEBUG, INFO, WARN, ERROR, OFF.
listenerInitListener?Optional callback (see below).
customerUserIdString?Your app's stable user ID, if you have one. Helpful for cross-device identity.
environmentSignalSealEnvironment?Auto-detected from your build (debuggable → SANDBOX, otherwise PRODUCTION). Pass SANDBOX explicitly when running QA tracks on the Play Console.
respectLimitAdTrackingBooleanDefaults to true. Honor the user's "Limit ad tracking" setting on Android. Setting this to false violates Google Play Developer Program Policies for the AD_ID permission - only do it with a clear legal basis.

configure(...) is idempotent - the second call is logged and ignored.

The SDK fires the INSTALL event automatically the first time configure(...) runs on a device. Don't send it manually.

InitListener

Optionally, pass an InitListener to be told when initialization completes or fails:

SignalSealSDK.configure(
  context = this,
  apiKey = "ak_android_...",
  listener = object : InitListener {
    override fun onError(t: Throwable) {
      Log.e("SignalSeal", "init failed", t)
    }
    override fun onInitialized(
      mainThreadDurationMs: Long,
      totalDurationMs: Long
    ) {
      Log.i("SignalSeal", "init ok in $totalDurationMs ms")
    }
  }
)

Send events

SignalSealSDK.sendEvent(
  event = EventType.PURCHASE,
  parameters = mapOf(
    "value" to 9.99,
    "proceeds" to 6.99,
    "currency" to "USD"
  )
)

value is the gross amount in the buyer's currency. proceeds is optional - the net you keep after store commission and tax, in the same currency; pass it if you know it (e.g. from your receipt-validation backend). currency is the ISO-4217 code; omit it and value is treated as USD.

For events that don't fit any of the standard types, use EventType.CUSTOM with a name:

SignalSealSDK.sendEvent(
  event = EventType.CUSTOM,
  name = "onboarding_completed",
  parameters = mapOf("steps" to 5)
)

sendEvent(...) is fire-and-forget. Events queue in memory and flush in the background.

Event types

enum class EventType {
  INSTALL,
  LOGIN, SIGN_UP, REGISTER,
  PURCHASE, ADD_TO_CART, ADD_TO_WISHLIST,
  INITIATE_CHECKOUT, START_TRIAL, SUBSCRIBE,
  LEVEL_START, LEVEL_COMPLETE,
  TUTORIAL_COMPLETE, SEARCH, VIEW_ITEM, VIEW_CONTENT, SHARE,
  CUSTOM,
}

Set user attributes

Attach known user data to all subsequent events. Pass only the fields you have.

SignalSealSDK.setUserAttributes(
  UserAttributes(
    email = "alice@example.com",
    firstName = "Alice",
    country = "US",
    externalId = "user_42"
  )
)

Available fields:

FieldTypeNotes
emailString?
phoneString?E.164 format recommended.
firstName, lastNameString?
dobString?ISO-8601 (YYYY-MM-DD).
genderString?
city, state, zip, countryString?country should be ISO-3166-1 alpha-2.
externalIdString?Your app's internal user ID after login.

Helpers

Get the SignalSeal ID

A stable per-install ID, useful for bridging to RevenueCat, SuperWall, or your own backend.

val id: String? = SignalSealSDK.getSignalSealId()

Returns null until configure(...) has finished setting up.

Get attribution parameters

Returns the install's attribution data - the campaign that drove it, plus raw click IDs for any further server-side correlation.

val params: Map<String, String> = SignalSealSDK.getAttributionParams()
// {
//   "signalseal_id": "...",
//   "signalseal_adnetwork": "google",
//   "signalseal_campaign_id": "...",
//   "gclid": "...",
//   ...
// }

Organic installs return { "signalseal_id": "..." } only. Attributed installs add signalseal_* keys plus any raw click IDs the original ad carried (gclid, fbclid, ttclid, wbraid, etc.).

Flush

Force-flush the in-memory event queue. Useful in tests.

SignalSealSDK.flush()

Reset

Wipe all locally-stored SDK state - installation ID, queued events, cached user data. Use this for "log out" or "forget me" flows. The SDK re-mints an installation ID and re-fires the INSTALL event on the next call.

SignalSealSDK.resetData()

Status checks

SignalSealSDK.isConfigured()    // true once configure() has returned
SignalSealSDK.isEnabled()       // true if SDK is up and not killswitched
SignalSealSDK.isSdkDisabled()   // true if SDK was disabled (e.g. bad API key)

Debug mode

Pass isDebug = true when configuring during development:

SignalSealSDK.configure(
  context = this,
  apiKey = "ak_android_...",
  isDebug = BuildConfig.DEBUG
)

In debug mode every event is tagged is_debug - events still appear in the SignalSeal dashboard so you can verify they look right, but they won't be forwarded to your ad networks.

What's next