Quickstart with Android (Kotlin)
Call your PromptHelm prompts from any Android application.
This quickstart walks you through minting an API token, adding the
PromptHelm Android SDK to a Gradle project, and making your first
call from Kotlin. By the end you will have a working completion, a
Kotlin Flow streaming example, and a checklist for shipping to the
Play Store.
SDK status
The Android SDK is in pre-release. The 0.1.0 artifact is being
staged on Maven Central; track
Runivox/prompt-helm-sdk-android
for the release announcement. The public API below is stable — only
the distribution channel is finalising.
Prerequisites
- Android Gradle Plugin 8.2 or newer (Kotlin 1.9+).
minSdk24 (Android 7.0) or higher.- A PromptHelm account. Join the waitlist if you need an invite.
Sign in to the dashboard and open Settings → API tokens. Click New token, name it (e.g.
android-app-dev), and copy the value immediately — tokens are revealed exactly once.Keep the token out of source control
Never commit an API token to your repository. Read it from
gradle.properties(gitignored), inject it intoBuildConfigfor local builds, and use a secrets manager or remote config for release builds.Add the dependency to your app module's
build.gradle.kts. The artifact is published to Maven Central, so no extra repository configuration is required if you already declaremavenCentral()in yoursettings.gradle.kts.app/build.gradle.kts dependencies { implementation("app.prompthelm:sdk-android:0.1.0") }Make sure your manifest declares the network permission:
app/src/main/AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" />Read the API key from
local.properties(gitignored) and surface it onBuildConfigso it never lives in source.app/build.gradle.kts import java.util.Properties val localProps = Properties().apply { val f = rootProject.file("local.properties") if (f.exists()) f.inputStream().use { load(it) } } android { defaultConfig { buildConfigField( "String", "PROMPTHELM_API_KEY", "\"${localProps.getProperty("promptHelmApiKey", "")}\"", ) } buildFeatures { buildConfig = true } }In the dashboard, navigate to Prompts → New prompt. Give it a slug (for example,
welcome), pick a default model, and write the prompt body. Use{{ variable_name }}for runtime variables. Saving publishesv1on themainenvironment.Learn more
See Concepts → Prompts for versions, environments, and promotion semantics.
Construct a single
PromptHelminstance per process — typically inside yourApplicationsubclass or a Hilt@Singletonprovider — and callexecutefrom a coroutine.app/src/main/java/com/example/Quickstart.kt import app.prompthelm.sdk.PromptHelm val ph = PromptHelm(apiKey = BuildConfig.PROMPTHELM_API_KEY) val response = ph.execute(ExecuteRequest( promptSlug = "welcome", variables = mapOf("name" to "World") )) println(response.output)The call appears in the dashboard's Logs view with the full request/response payload, the per-call cost, and the round-trip latency.
For chat-style UIs, switch to the streaming API. The SDK exposes a cold
Flow<StreamEvent>that surfaces typed chunks as they arrive.app/src/main/java/com/example/Stream.kt ph.stream(ExecuteRequest(promptSlug = "welcome", variables = mapOf("name" to "World"))) .collect { event -> when (event) { is StreamEvent.Chunk -> print(event.content) is StreamEvent.Done -> println("\n${event.totalTokens} tokens, $${event.cost}") is StreamEvent.Err -> println("Error ${event.errorCode}: ${event.message}") } }Cancelling the enclosing
CoroutineScope(for example aviewModelScopewhen the user leaves the screen) cancels the SSE connection automatically.Before you publish to the Play Store, run through this checklist:
- Source the API key from a secrets manager in release builds (or
Firebase Remote Config).
BuildConfiginjection is fine for debug builds; never ship a production key embedded in the APK. - R8 / ProGuard rules ship inside the SDK as
consumer-rules.pro, so you do not need to add keep rules in your app module. Verify with a release build that streaming events still deserialise correctly. - Cancel coroutines on lifecycle teardown. Use
viewModelScopeorlifecycleScopeso cancellation propagates to the SDK and closes open SSE streams. - Catch typed errors. Every SDK call throws
PromptHelmExceptionwith a stableerrorCode. Map known codes to retries; let unknown codes surface to your crash reporter. - Pin an environment. Default
mainto Play Store traffic and promote new prompt versions throughstaginganddevfirst.
- Source the API key from a secrets manager in release builds (or
Firebase Remote Config).