Overview
Errors in the Seam Android SDK fall into two categories:SeamError— Thrown by SDK operations such asinitialize(),activate(),deactivate(),refresh(), andunlock(). These represent SDK setup, configuration, or API-level failures.SeamCredentialError— Stored inSeamCredential.errors. These represent issues with a specific credential that must be resolved before it can be used for an unlock.
SeamError
SeamError is a sealed class. Each subtype maps to a specific failure mode:
| Subtype | Thrown by | Description |
|---|---|---|
SeamError.AlreadyInitialized | initialize() | The SDK is already initialized. Call deactivate(deintegrate = true) before re-initializing with a new token. |
SeamError.InitializationRequired | getInstance(), activate(), refresh(), unlock() | The SDK has not been initialized; call SeamSDK.initialize() first. |
SeamError.InvalidClientSessionToken | initialize(), activate() | The client session token is malformed or has expired. Obtain a fresh token from your server. |
SeamError.InternetConnectionRequired | initialize(), activate(), refresh() | A network connection is required for this operation. |
SeamError.DeactivationInProgress | initialize(), refresh(), deactivate() | A deactivation is already running; wait for it to complete before retrying. |
SeamError.ActivationRequired | unlock() | The SDK has not been activated; call activate() first. |
SeamError.InvalidCredentialId | unlock() | No credential matches the specified ID. Verify the credential ID against credentials.value. |
SeamError.IntegrationNotFound | unlock() | No provider integration was found for this credential. Ensure you added the correct provider module (for example, seam-phone-sdk-android-assaabloy) in your Gradle dependencies. |
SeamError.CredentialErrors | unlock() | The credential has unresolved errors. Inspect e.errors (a List<SeamCredentialError>) and resolve them before retrying the unlock. |
SeamError.InvalidUnlockProximity | unlock() | The specified UnlockProximity is not supported by this credential. |
Handling SeamError in code
SeamCredentialError
SeamCredentialError is a sealed class stored in SeamCredential.errors. A credential may have zero or more errors simultaneously. Check errors before calling unlock():
| Subtype | Description |
|---|---|
SeamCredentialError.Loading | The credential is still being provisioned. Wait for the credentials StateFlow to emit an updated list where this error is no longer present. |
SeamCredentialError.Expired | The credential has expired. Contact the credential issuer or administrator to reissue it. |
SeamCredentialError.UserInteractionRequired(interaction) | The user must take a specific action before this credential can be used. Inspect the interaction property. |
SeamCredentialError.Unknown | An unclassified error occurred. Retry or contact Seam support. |
Checking credential errors before unlock
SeamRequiredUserInteraction
When a credential has aSeamCredentialError.UserInteractionRequired error, the interaction property tells you exactly what the user needs to do:
| Subtype | Description | Recommended Action |
|---|---|---|
SeamRequiredUserInteraction.CompleteOtpAuthorization(otpUrl) | The user must complete an OTP authorization flow. | Open otpUrl in a browser or WebView. |
SeamRequiredUserInteraction.EnableInternet | The device has no internet connection. | Prompt the user to enable Wi-Fi or mobile data. |
SeamRequiredUserInteraction.EnableBluetooth | Bluetooth is disabled. | Prompt the user to enable Bluetooth in Settings or the quick settings panel. |
SeamRequiredUserInteraction.GrantPermissions(permissions) | One or more Android permissions have not been granted. | Use ActivityCompat.requestPermissions() with the list of permission strings in permissions. |
Handling required user interactions
Handling unlock errors end-to-end
The following example shows a complete unlock handler that covers both pre-flight credential checks and runtimeSeamError cases:
Best Practices
- Check
credential.errorsbefore callingunlock()— An unlock attempt on a credential with unresolved errors will throwSeamError.CredentialErrors. Checking upfront lets you present better UX before the call. - Subscribe to
unlockStatusbeforeunlock()—unlock()emits events immediately; subscribing after the call can miss early events likeScanningStarted. - Map errors to UI states — Distinguish loading states (
SeamCredentialError.Loading) from actionable errors so you show spinners rather than error messages while credentials are provisioning. - Retry transient errors —
SeamError.InternetConnectionRequiredandSeamError.DeactivationInProgressare transient. Implement retry logic with backoff for these cases.
See Also
- SeamError reference — Full type reference for all
SeamErrorsubtypes. - SeamCredentialError reference — Full type reference for all
SeamCredentialErrorsubtypes. - Quickstart — Initialize the SDK and perform your first unlock.
- Architecture — How StateFlows and the SDK lifecycle fit together.

