# Photo Enrollment

As introduced in the [enrollment section](https://docs.keyless.io/consumer/mobile-sdk-guide/enrollment):

> enrollment is the process of registering a new user by connecting their facial biometrics to a Keyless account. During this process, a full and unobstructed view of the user's face is required.

If you possess a trusted source, such as an identity document, Keyless allows you to register a new user connecting their facial biometric from the identity document photo. The assumption behind the feature is that the identity document photo fulfills the requirement of a full and unobstructed view of the user's face.

{% hint style="success" %}
To retrieve a document photo Keyless offers the [Keyless Mobile Document SDK](https://docs.keyless.io/mobile-document-sdk) utility.
{% endhint %}

To enroll a user from the photo use the `PhotoEnrollConfig`.

{% tabs %}
{% tab title="Android" %}

```kotlin
// photoBitmap is the bitmap you created from the document photo.
val configuration = PhotoEnrollConfig(photo = photoBitmap)

Keyless.enroll(
  configuration = configuration,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "Enroll success - userId ${result.value.keylessId}")
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "Enroll failure - error code ${result.error.code}")
    }
  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
// photoUIImage is the UIImage you created from the document photo.
let configuration = PhotoEnrollConfig(photo: photoUIImage)

Keyless.enroll(
  configuration: configuration,
  onCompletion: { result in
    switch result {
    case .success(let enrollmentSuccess):
        print("Enrollment finished successfully. UserID: \(enrollmentSuccess.keylessId)")
    case .failure(let error):
        print("Enrollment finished with error: \(error.message)
    }
  })
```

{% endtab %}

{% tab title="Flutter" %}

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

// documentImage from eDocument.
final configuration = PhotoEnrollConfig(documentImage: documentImage);

try {
  final result = await Keyless.instance.enroll(configuration);
  print("Enrollment finished successfully. UserID: ${result.keylessId}");
} catch (error) {
  print("Enrollment finished with error: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PhotoEnrollConfig({
  photoBase64: '<photoBase64>',
});

const result = await Keyless.enroll(config);
result.fold({
  onSuccess(data) {
    logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
  },
});
```

{% endtab %}
{% endtabs %}

## Photo Enrollment configuration

You can configure the enrollment process with optional parameters in your `PhotoEnrollConfig()` instance.

{% tabs %}
{% tab title="Android" %}

```kotlin
public data class PhotoEnrollConfig(
    public val photo: Bitmap,
    public val temporaryState: String? = null,
    public val operationInfo: OperationInfo? = null,
    public val jwtSigningInfo: JwtSigningInfo? = null
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
public struct PhotoEnrollConfig{
    public let photo: CGImage
    public let operationInfo: Keyless.OperationInfo?
    public let jwtSigningInfo: JwtSigningInfo?
    public let temporaryState: String?
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class PhotoEnrollConfig{
  final Uint8List? documentImage;
  final String? temporaryState;
  final OperationInfo? operationInfo;
  final JwtSigningInfo? jwtSigningInfo;
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript

 class PhotoEnrollConfig {
  public readonly photoBase64: string;
  public readonly operationInfo: OperationInfo | null;
  public readonly jwtSigningInfo: JwtSigningInfo | null;
  public readonly clientState: string | null;


```

{% endtab %}
{% endtabs %}

## Photo Enrollment success result

If the Enroll from photo is successful you will find in the `EnrollmentSuccess` containing the corresponding fields you requested during configuration.

{% tabs %}
{% tab title="Android" %}

```kotlin
data class EnrollmentSuccess(
    val signedJwt: String? = null,
) : KeylessSdkSuccess()
```

{% endtab %}

{% tab title="iOS" %}

```swift
public struct EnrollmentSuccess {
    public let signedJwt: String?
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class EnrollmentSuccess {
    final String? signedJwt;
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
 class EnrollmentSuccess {
    public readonly keylessId: string;
    public readonly customSecret: string;
    public readonly enrollmentFrame: string | null;
    public readonly signedJwt: string | null;
    public readonly clientState: string | null;
 }
```

{% endtab %}
{% endtabs %}

If the enrollment is successful the user is enrolled and can [authenticate](https://docs.keyless.io/consumer/mobile-sdk-guide/authentication) with Keyless from now on.
