Skip to content

Mobile apps

This page is for developers. The Android and iOS SDKs open a channel full screen inside your app and tell your app what happens in the game. Flutter and React Native apps use a web view for now.

The SDKs show the same games, pre-game pages and reward pages as the web, from https://play.keliplay.com. When a game is updated, your app gets the update without a new release.

Android 6.0 (API 23) or later. The SDK is on Maven Central:

build.gradle.kts
dependencies {
implementation("com.keliplay:games-sdk:0.1.0")
}
  1. Register your app. In the dashboard, open Settings, then Allowed origins, choose Add origin and pick Android app or iOS app. Enter the app’s application id or bundle id, such as com.example.app. See Allowed origins.

  2. Mint the token on your backend. When the app is about to show the game, it asks your backend for a client token. Your backend mints one with origin set to your registered app, android:com.example.app or ios:com.example.app. See Client tokens. Never put your API key in the app.

    {
    "channelId": "3f6b1c0a-8e2d-4b7a-9c15-2d4e6f8a0b1c",
    "participantRef": "user_8412",
    "origin": "android:com.example.app"
    }
  3. Open the channel. The SDK asks your token provider for a token each time it opens, because a token is good for one play.

KeliplayGames.open(
activity,
KeliplayGamesConfig(
channelId = "3f6b1c0a-8e2d-4b7a-9c15-2d4e6f8a0b1c",
playBaseUrl = "https://play.keliplay.com",
tokenProvider = { callback ->
backend.mintToken(
onSuccess = { token -> callback.onToken(token) }, // null between campaigns
onError = { error -> callback.onFailure(error) },
)
},
),
) { event ->
when (event) {
is KeliplayGameEvent.SessionCompleted -> showThanks(event.score)
is KeliplayGameEvent.Closed -> refreshHome()
else -> Unit
}
}

When nothing is live on the channel, your backend gets a null token. Pass it on: the screen shows the channel’s between-campaigns message instead of an error.

close() closes the game screen from your code. Players close it with the back button on Android, and with the close button on iOS.

Events arrive on the main thread, in order. Nothing follows Closed.

Event When
Ready The game has loaded and the player can play.
SessionStarted A play has started and counts towards the player’s limit.
OutcomeRevealed An instant-win game has shown its result: a label and whether it is a win. Never a coupon code.
SessionCompleted The play is over and scored.
Error Something went wrong. See the codes below.
Closed The game screen has gone. The reason is USER_DISMISSED, PROGRAMMATIC, AFTER_COMPLETE or ERROR.

Coupon codes and winners reach your backend through webhooks, never through the app.

The codes are the same on both platforms. GAME_REPORTED keeps the game open; every other code is followed by Closed.

Code Meaning
NO_TOKEN Your token provider failed, or did not answer in time.
NETWORK_UNAVAILABLE The device is offline.
LOAD_FAILED The game could not load.
HTTP_ERROR The game’s page answered with an error.
SSL_ERROR The secure connection failed. The SDK never continues past a certificate error.
BLOCKED_ORIGIN Something tried to leave the Keliplay play address. Links a player taps open in the browser.
LOAD_TIMEOUT The first page did not finish loading in time.
RENDER_PROCESS_GONE The system stopped the web view.
BAD_MESSAGE The game sent something the SDK did not recognise.
GAME_REPORTED The game reported a problem. The game stays open.
Option Default Description
channelId The channel to open. Required.
playBaseUrl (Android), playBaseURL (iOS) https://play.keliplay.com. Required.
tokenProvider Fetches a client token from your backend.
theme the game’s own LIGHT or DARK (Android), .light or .dark (iOS).
locale the game’s own A language tag such as en-GB.
orientation any Lock the game screen to portrait or landscape. Your app’s own orientation is untouched.
loadTimeoutMs / loadTimeout 30 seconds How long the first page may take to load. Time a player spends on the pre-game page is never counted.
tokenTimeoutMs / tokenTimeout 15 seconds How long your token provider may take.
showsCloseButton (iOS) true Turn off only if your app closes the game itself with close().

On iOS, open throws if the screen you call it from cannot show the game right now, for example because it is already showing something else.

The game fills the screen. Its background, its position on the screen and any decorations come from the campaign’s Branding tab, so you can change them without an app release.

Host a small page on your own site that embeds the channel with the web SDK, then open that page in a web view.

  1. Add your site to allowed origins. The page is served from your site, so its address is the origin to allow, for example https://app.example.com.

  2. Mint the token on your backend. Your backend mints a client token with origin set to your site and returns a link to the page, for example https://app.example.com/play#token=.... Putting the token after # keeps it out of server logs.

  3. Mount the game on the page. The page reads the token from location.hash and calls KrdsGames.mount with your channel id.

  4. Open the page in a web view. Use webview_flutter in Flutter or react-native-webview in React Native, with JavaScript enabled.

To pass game events to the app, forward them through the web view’s message bridge:

const game = KrdsGames.mount('#keliplay-game', { channelId, clientToken, playBaseUrl })
game.on('session_completed', (payload) => {
const message = JSON.stringify({ type: 'session_completed', score: payload.score })
if (window.ReactNativeWebView) window.ReactNativeWebView.postMessage(message)
else if (window.KeliplayFlutter) window.KeliplayFlutter.postMessage(message)
})

Register the matching handler: onMessage in React Native, or a JavaScriptChannel named KeliplayFlutter in Flutter. Load the page again with a new token for each play.