Guides
Android integration (Kotlin)
Protect Android signup and login through your backend and the AbuseGraph session and check APIs.
Keep the secret on your backend
Never include an sk_ key in a public APK. Have the app call an endpoint you own with the account and device fields. Your backend creates a short-lived session, binds it to a check, and returns the verdict.
App request
Use your app's existing HTTPS client. For example, with OkHttp:
import java.io.IOException
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
val body = JSONObject()
.put("email", email)
.put("event", "signup")
.put("visitorId", visitorId)
.toString()
.toRequestBody("application/json; charset=utf-8".toMediaType())
val request = Request.Builder()
.url("https://your-api.example.com/signup-risk-check")
.post(body)
.build()
okHttpClient.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Signup was not approved")
val result = JSONObject(response.body!!.string())
check(result.getBoolean("ok"))
}
// Continue only after the backend has approved and completed signup.Backend flow
Your backend uses its server-held secret for both API calls. Store device fields in the session, then pass the returned sessionId with the account fields to check.
const headers = {
"content-type": "application/json",
"x-api-key": process.env.ABUSEGRAPH_SECRET_KEY!,
"x-abusegraph-site": process.env.ABUSEGRAPH_SITE!,
};
const site = process.env.ABUSEGRAPH_SITE!;
const sessionResponse = await fetch("https://abusegraph.com/api/v1/session", {
method: "POST",
headers,
body: JSON.stringify({ visitorId, fingerprint }),
});
if (!sessionResponse.ok) throw new Error("Unable to create risk session");
const { sessionId } = await sessionResponse.json();
const checkResponse = await fetch("https://abusegraph.com/api/v1/check", {
method: "POST",
headers,
body: JSON.stringify({ email, event, site, sessionId }),
});
if (!checkResponse.ok) throw new Error("Unable to check account risk");
const result = await checkResponse.json();
if (result.verdict === "block") return Response.json({ ok: false }, { status: 403 });
if (result.verdict === "challenge") return Response.json({ ok: false }, { status: 428 });
// Create the account / issue the session here, after the decision.
return Response.json({ ok: true });The session expires after 24 hours. Events: signup, login, password_reset, and email_change. See iOS and React Native.