Android SDK reference
The Android SDK returns a RevokeGPT token from one call. It solves a proof of work on the device, attests the app with Play
Integrity and, when your site’s rules ask for it, shows the hosted challenge page in a sheet. Your server then verifies the
token with siteverify. It needs Android 7.0 (API 24) or later, and a WebView with WEB_MESSAGE_LISTENER for the challenge sheet. The only permission is INTERNET. For a step-by-step setup see the
Android quickstart.
Install
Section titled “Install”Include sdks/android as a composite build in settings.gradle.kts, then depend on it:
includeBuild("../path/to/sdks/android") { dependencySubstitution { substitute(module("com.revokegpt:revokegpt-android")).using(project(":revokegpt")) }}// app moduledependencies { implementation("com.revokegpt:revokegpt-android:0.1.0") }After the first release the same dependency line resolves from Maven Central, with no includeBuild. R8 and ProGuard need
nothing from you: the library ships consumer rules that keep its public API.
Link a Google Cloud project to your app in the Play Console, add your app (package name and signing certificate SHA-256) under Apps in the dashboard, and upload the service account JSON key there.
Options
Section titled “Options”RevokeGPTOptions is passed to init.
RevokeGPTOptions( endpoint, widgetOrigin, timeoutMillis, cloudProjectNumber, locale, theme, debugLogging, wrapper)| Setting | Default | Notes |
|---|---|---|
endpoint |
https://api.revokegpt.com |
https:; plain http: only to 127.0.0.1, localhost, [::1] or 10.0.2.2, and only in a debuggable app. It may carry a path; never userinfo, a query or a fragment. |
widgetOrigin |
https://js.revokegpt.com |
The hosted challenge page’s origin: a bare, lowercase origin. The same scheme rules apply. |
timeoutMillis |
10 000 | 1 000 to 60 000. Covers the network calls, the proof of work and the attestation, not the time the sheet is on screen. |
cloudProjectNumber |
none | Your Google Cloud project number, which must be positive. Without it the SDK does not call Play and every token carries the attestation unavailable. |
locale |
the device’s language | The hosted page’s language (en, pt-BR, …). |
theme |
Theme.AUTO |
LIGHT, DARK or AUTO. |
debugLogging |
off | Logs event names to android.util.Log (tag RevokeGPT). Logs never contain a value. |
wrapper |
null |
For the Flutter and React Native plugins only. Apps leave it null. |
Presentation says where a challenge sheet may appear: Presentation.Automatic (over your app’s resumed Activity),
Presentation.From { activity } (a lambda that returns the Activity to show it over, or null) or Presentation.Never.
Methods
Section titled “Methods”All methods are on the RevokeGPT object.
fun init(context: Context, siteKey: String, options: RevokeGPTOptions = RevokeGPTOptions())Call once in Application.onCreate. A later call replaces the configuration. The SDK prepares Play’s token provider once
per process, in the background, as soon as you call init.
RevokeGPT.init(this, "rgpk_...", RevokeGPTOptions(cloudProjectNumber = 123456789012L))execute
Section titled “execute”suspend fun execute( action: String? = null, cdata: String? = null, presentation: Presentation = Presentation.Automatic,): StringReturns the RevokeGPT token. action is 1 to 100 of A-Z a-z 0-9 / _. cdata is 0 to 255 of A-Z a-z 0-9 _ -. Calls may
run concurrently. Cancelling the coroutine cancels the call (a CancellationException) and closes the sheet.
try { val token = RevokeGPT.execute(action = "login") // Send `token` to your server with the login request.} catch (e: RevokeGPTException) { // e.code}executeAsync
Section titled “executeAsync”fun executeAsync( action: String?, cdata: String?, callback: RevokeGPTCallback, presentation: Presentation = Presentation.Automatic,): CancellableFor Java. The callback (onSuccess(String token), onError(RevokeGPTException error)) runs on the main thread, and nothing is
delivered after cancel(), which also closes the sheet.
Cancellable call = RevokeGPT.executeAsync("login", null, new RevokeGPTCallback() { @Override public void onSuccess(String token) { /* send it to your server */ } @Override public void onError(RevokeGPTException error) { /* error.getCode() */ }});challengeAccount and challengeAccountAsync
Section titled “challengeAccount and challengeAccountAsync”suspend fun challengeAccount( requestToken: String, languageCode: String? = null, presentation: Presentation = Presentation.Automatic,): String
fun challengeAccountAsync( requestToken: String, languageCode: String?, callback: RevokeGPTCallback, presentation: Presentation = Presentation.Automatic,): CancellableAccount verification: shows the hosted page for the request token your server got from RevokeGPT and returns the token the page produces.
Errors and failure model
Section titled “Errors and failure model”RevokeGPTException has code, status (the HTTP status), requestId (the server’s, when it sent a well-formed one) and
retryAfterSeconds. Its message and toString() carry only the code and the status: never a token, a site key or a
server message.
| Code | Meaning |
|---|---|
invalid-argument |
A setting or argument is malformed. |
not-configured |
execute before init. |
network-error |
No connection, a TLS failure or a refused connection. |
timeout |
The call’s deadline passed. |
http-error |
A non-200 answer without a known error, or a redirect (never followed). retryAfterSeconds is set on 429 and 503. |
invalid-response |
The answer was not valid, or it named another app. |
challenge-required |
A challenge is needed and could not be shown (Never, or no Activity within 5 s). No token is returned. |
challenge-unsupported |
The device cannot show the challenge safely (no WEB_MESSAGE_LISTENER, or a Safe Browsing warning). |
cancelled |
The person closed the challenge (Close, Back or a tap outside). |
busy |
init during a call, or a second sheet while one is up. |
internal |
An unexpected state. |
| API codes | For example rate-limited, invalid-site-key, app-not-allowed, plan-required, passed through unchanged. |
Never retry in a tight loop. There is no option to skip a challenge, so your server never receives a low-score token presented as a passed one. See errors for the API codes.
Configuration
Section titled “Configuration”- Without a cloud project number, or where Play is missing or unusable (an emulator without Play, an old Play Store, no
Play services), the token carries
unavailable. Two Play errors that Google treats as a possible attack (APP_NOT_INSTALLED,APP_UID_MISMATCH) send no attestation at all, which scores as failed. - If Play’s provider is not ready in time, the solve goes out as
unavailablewhile preparation continues for the next call. - Local development: point
endpointandwidgetOriginathttp://10.0.2.2:...in a debuggable build, with a debug network security config that allows cleartext to that host.
Security notes
Section titled “Security notes”- Only the public site key goes in the app. The secret key stays on your server: verify the token with siteverify and check
success, the action and the app (siteverify returnsapk_package_namein place ofhostname). The server SDKs takeexpectedAppwith platformandroid. See the Go and Java references. - The SDK never reads the advertising ID,
ANDROID_ID, accounts, location, contacts or installed apps, and stores nothing on the device. - The challenge sheet is a WebView of
https://js.revokegpt.comonly, withFLAG_SECURE(no screenshots or recents), no other site loadable, no file access, no mixed content, no cache and Safe Browsing on. On close its history and form data are cleared and the WebView is destroyed. - RevokeGPT’s servers see the IP address of every request, for fraud prevention and security.