# Generating client state via the Mobile SDK

## What is the client state?

The Keyless *client state* contains all the necessary information to restore an account. It can be created during enrollment and authentication

{% hint style="info" %}
To create and use the client state Keyless requires the user's biometric to be authenticated.
{% endhint %}

The temporay state internals are not important but you can expect a string similar to the following that you should pass as-is to recover the account:

```json
"{\"artifact\":{\"family\":\"davideface_lite\",\"version\":\"1.2.0\",\"target\":\"mobile_sdk\",\"liveness\":\"liveness\"},\"core-client-state\":\"BASE_64_STATE\"}"
```

{% hint style="warning" %}
Note that when generating the client state within your client app using the Keyless Mobile SDK a maximum of 50 client states are allowed to be generated. This ensures that the experience remains performant.
{% endhint %}

## Obtain the client state

Use the `generatingClientState` parameter of the `BiomEnrollConfig` or `BiomAuthConfig`. When doing so, we recommend choosing `BACKUP` as the client state type to be generated. Note: if you’re using Flutter, this parameter will instead be named `shouldRetrieveTemporaryState`.

{% tabs %}
{% tab title="Android" %}
Dunring the enrollment flow:

```kotlin
val enrollConfig = BiomEnrollConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.enroll(
  configuration = enrollConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {

      	val clientState = result.value.clientState
      	// store the client state on your backend to recover the account in the future

      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)

```

During the authentication flow:

```kotlin
val authConfig = BiomAuthConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.authenticate(
  configuration = authConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {

      	val clientState = result.value.clientState
      	// store the client state on your backend to recover the account in the future

      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)
```

{% endtab %}

{% tab title="iOS" %}
During the enrollment flow:

```swift
let enrollConfig = BiomEnrollConfig(generatingClientState: .backup)

Keyless.enroll(
  configuration: enrollConfig,
  onCompletion: { result in
    switch result {
    case .success(let enrollSuccess):
    	
    	let clientState = enrollSuccess.clientState
    	// store the client state on your backend to recover the account in the future

    case .failure(let error):
        print("error code: \(error.code)
    }
  })
```

During the authentication flow:

```swift
let authConfig = BiomAuthConfig(generatingClientState: .backup)

Keyless.authenticate(
  configuration: authConfig,
  onCompletion: { result in
    switch result {
    case .success(let authSuccess):
    	
    	let clientState = authSuccess.clientState
    	// store the client state on your backend to recover the account in the future

    case .failure(let error):
        print("error code: \(error.code)
    }
  })
```

{% endtab %}

{% tab title="Flutter" %}
During the enrollment flow:

```dart
import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';

final enrollConfig = BiomEnrollConfig(shouldRetrieveTemporaryState: true);

try {
    final result = await Keyless.instance.enroll(enrollConfig);
    if (result.temporaryState != null) {
        // store the temporary state on your backend to recover the account in the future
        print("Temporary state retrieved: ${result.temporaryState}");
    }
} catch (error) {
    print("Enrollment failed: $error");
}
```

During the authentication flow:

```dart
import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';

final authConfig = BiomAuthConfig(shouldRetrieveTemporaryState: true);

try {
    final result = await Keyless.instance.authenticate(authConfig);
    if (result.temporaryState != null) {
        // store the temporary state on your backend to recover the account in the future
        print("Temporary state retrieved: ${result.temporaryState}");
    }
} catch (error) {
    print("Authentication failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}
During the enrollment flow:

```typescript
const config = new BiomEnrollConfig({
  generatingClientState: ClientStateType.BACKUP,
});

const result = await Keyless.enroll(config);
result.fold({
  onSuccess(data) {
    logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
    const clientState = data.clientState;
    // store the client state on your backend to recover the account in the future
    logConsole('Client state ' + JSON.stringify(clientState, null, 2));
  },
  onFailure(error) {
    logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
  },
});
```

During the authentication flow:

```typescript
const config = new BiomAuthConfig({
  generatingClientState: ClientStateType.BACKUP,
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Authenticate result success ' + JSON.stringify(data, null, 2));
    const clientState = data.clientState;
    // store the client state on your backend to recover the account in the future
    logConsole('Client state ' + JSON.stringify(clientState, null, 2));
  },
  onFailure(error) {
    logConsole('Authenticate result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keyless.io/consumer/mobile-sdk-reference/generating-client-state-via-the-mobile-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
