Sessions required
Every yes:id SDK module needs a valid session before it can run. Complete the Sessions Guide first — it takes 5 minutes and is required before the code below will work.
Using Face Authentication
The user blinks to start, completes directional challenges (look left / right / up / down), and the live face is matched against one or two reference images you provide.
Prerequisites
YesidSessionManager.setup(
api = "YOUR_API_KEY",
publishable = "YOUR_PUBLISHABLE_KEY",
consumerUsername = "YOUR_USERNAME"
)
Compose integration
import com.yesid.face.FaceAuthentication.FaceAuthenticationCamera
import com.yesid.face.FaceAuthentication.domain.FaceMatchResults
import com.yesid.face.FaceAuthentication.presentation.FaceAuthConfigurationBuilder
@Composable
fun FaceAuthScreen(sessionId: String, referenceImage: Bitmap) {
FaceAuthenticationCamera.FaceAuthCamera(
configurationBuilder = FaceAuthConfigurationBuilder
.setSessionID(sessionId),
firstImage = referenceImage,
secondImage = null,
onMatchResults = { result: FaceMatchResults ->
val similarity = result.similarity
val matched = (similarity ?: 0.0) >= 0.75
}
)
}
Matching against two reference images
FaceAuthenticationCamera.FaceAuthCamera(
configurationBuilder = FaceAuthConfigurationBuilder.setSessionID(sessionId),
firstImage = enrolledFaceBitmap,
secondImage = documentPortraitBitmap,
onMatchResultsFirstImage = { r -> },
onMatchResultsSecondImage = { r -> },
)
Liveness-only mode
FaceAuthenticationCamera.FaceAuthCamera(
configurationBuilder = FaceAuthConfigurationBuilder
.setSessionID(sessionId)
.setLivenessOnly(true),
firstImage = null,
secondImage = null,
onLivenessOnlyResults = { capturedFrames: List<Bitmap> -> }
)
Configuration reference
| Method | Type | Default | Description |
|---|---|---|---|
setSessionID(id) | String | — | Required. Session ID |
setLivenessOnly(flag) | Boolean | false | Skip matching; return captured frames |
setDisableSession(flag) | Boolean | false | Skip session validation |
setUIMessages(messages) | FaceAuthUIMessages | defaults | Override user-facing strings |
setFraudDefenseSettings(...) | — | maxAttempts=5 | Tune lockout behaviour |
setLensFacing(facing) | Int | LENS_FACING_FRONT | Camera to use |
Customising UI messages
FaceAuthConfigurationBuilder.setUIMessages(
FaceAuthUIMessages(
positionFace = "Place your face in the oval",
blinkToStart = "Blink to begin",
fraudDetected = "Verification failed. Try again later."
)
)
Resetting state
FaceAuthenticationCamera.restart()
Complete Activity example
The real integration pattern from the yes:id demo — config screen → camera → results:
class FaceMatchActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val sessionId = intent.getStringExtra("sessionId") ?: ""
setContent {
var scanning by remember { mutableStateOf(false) }
var matchResult by remember { mutableStateOf<FaceMatchResults?>(null) }
var livenessOnly by remember { mutableStateOf(false) }
val handled = remember { mutableStateOf(false) }
val config = remember {
FaceAuthConfigurationBuilder
.setUserLicense("YOUR_LICENSE_KEY")
.setSessionID(sessionId)
}
when {
scanning && matchResult == null -> {
config.setLivenessOnly(livenessOnly)
FaceAuthenticationCamera.FaceAuthCamera(
configurationBuilder = config,
firstImage = null,
secondImage = null,
onMatchResults = { res ->
if (!handled.value) {
handled.value = true
scanning = false
matchResult = res
}
},
onLivenessOnlyResults = { frames ->
if (!handled.value) {
handled.value = true
scanning = false
}
}
)
}
matchResult != null -> {
val similarity = matchResult!!.similarity ?: 0.0
val matched = similarity >= 0.6
Column(Modifier.padding(16.dp)) {
Text(if (matched) "Identity confirmed" else "No match",
style = MaterialTheme.typography.headlineSmall)
Spacer(Modifier.height(12.dp))
Text("Similarity: ${String.format("%.1f", similarity * 100)}%")
Text("Verdict: ${if (matched) "Match" else "No match"}")
Spacer(Modifier.height(16.dp))
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
Button(onClick = { finish() }) { Text("Done") }
OutlinedButton(onClick = {
handled.value = false; matchResult = null; scanning = false
}) { Text("Try again") }
}
}
}
else -> {
Column(Modifier.padding(16.dp)) {
Text("Face verification", style = MaterialTheme.typography.headlineSmall)
Spacer(Modifier.height(16.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Liveness only", Modifier.weight(1f))
Switch(checked = livenessOnly, onCheckedChange = { livenessOnly = it })
}
Spacer(Modifier.height(16.dp))
Button(onClick = { handled.value = false; matchResult = null; scanning = true }) {
Text(if (livenessOnly) "Start liveness capture" else "Match faces")
}
}
}
}
}
}
}