# PIN authentication

For authentication scenarios that don't necessitate biometric recognition, you can use PIN as an alternative.

{% hint style="warning" %}
PIN authentication has limited capabilities compared to biometric authentication. PIN supports:

* [operation info](/consumer/mobile-sdk-guide/authentication.md#operation-info),
* [jwt signing](/consumer/mobile-sdk-reference/jwt-signing.md),
  {% endhint %}

Keyless requires at least one of the following authentication factor to be present for each user:

* biometric factor
* PIN factor

PIN factor can be any valid `String`. Numbers are not enforced but are recommended, given the familiarity of numeric PINs for end users.

## Enrollment with PIN

To enroll using the PIN factor create the following configuration:

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

```kotlin
val configuration = PinEnrollConfig(pin = "1234")

Keyless.enroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinEnrollConfig(pin: "1234")

Keyless.enroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration = EnrollmentConfiguration.builder
  .withPin("1234")
  .build()

Keyless.enroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration = Keyless.EnrollmentConfiguration.builder
  .withPin("1234")
  .build()

Keyless.enroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinEnrollConfig(
    pin: "myPin"
);

try {
    await Keyless.instance.enroll(configuration);
    print("Enrollment successful");
} catch (error) {
    print("Enrollment failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinEnrollConfig({
  pin: '1234',
});

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

{% endtab %}
{% endtabs %}

To enroll multiple authentication factors you need call `Keyless.enroll` for each factor.

## Authentication with PIN

To authenticate using the PIN factor create the following configuration:

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

```kotlin
val configuration = PinAuthConfig(pin = "1234")

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234")

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration = AuthenticationConfiguration.builder
  .withPin("1234")
  .build()

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration = Keyless.AuthenticationConfiguration.builder
  .withPin("1234")
  .build()

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinAuthConfig(
    pin: "1234"
);

try {
    final result = await Keyless.instance.authenticate(configuration);
    print("Authentication successful");
} catch (error) {
    print("Authentication failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
});

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

{% endtab %}
{% endtabs %}

## De-enrollment with PIN

{% hint style="warning" %}
Note that de-enrolling deletes the user biometric factor as well as the PIN factor. If you just want to remove the PIN authentication factor, use the [PIN utilities](#pin-utilities) instead.
{% endhint %}

To de-enroll using the PIN authentication factor, create the following configuration:

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

```kotlin
val configuration = PinDeEnrollConfig(pin = "1234")

Keyless.deEnroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinDeEnrollConfig(pin: "1234")

Keyless.deEnroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration =
DeEnrollmentConfiguration.builder
  .withPin("myPin")
  .build()

Keyless.deEnroll(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration =
Keyless.DeEnrollmentConfiguration.builder
  .withPin("myPin")
  .build()

Keyless.deEnroll(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = PinDeEnrollConfig(
    pin: "1234"
);

try {
    await Keyless.instance.deEnroll(configuration);
    print("De-enrollment successful");
} catch (error) {
    print("De-enrollment failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinDeEnrollConfig('1234');

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

{% endtab %}
{% endtabs %}

## Remove PIN (keeping biometric factor)

To remove the PIN factor, while still keeping the biometric factor, perform a biometric authentication using the following configuration:

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

```kotlin
val configuration = BiomAuthConfig(shouldRemovePin = true)

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  BiomAuthConfig(shouldRemovePin: true)

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Android 4.6" %}

```kotlin
val configuration =
AuthenticationConfiguration.builder
  .removingPin()
  .build()

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS 4.6" %}

```swift
let configuration =
Keyless.AuthenticationConfiguration.builder
  .removingPin()
  .build()

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
final configuration = BiomAuthConfig(
    shouldRemovePin: true
);

try {
    await Keyless.instance.authenticate(configuration);
    print("Pin remove successful");
} catch (error) {
    print("Pin remove failed: $error");
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript

const config = new BiomAuthConfig({
  shouldRemovePin: true,
});

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

{% endtab %}
{% endtabs %}

## PIN utilities

To change the PIN use the `newPin` parameter in the `PinAuthConfig`:

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

```kotlin
val configuration = PinAuthConfig(pin = "1234", newPin = "5678")

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234", newPin: "5678")

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Future<void> changePin({
  required String oldPin,
  required String newPin
}) async
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
  newPin: '5678',
});

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

{% endtab %}
{% endtabs %}

To remove the PIN factor and keep the user enrolled with the biometric factor use the `shouldRemovePin` parameter in `PinAuthConfig`:

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

```kotlin
val configuration = PinAuthConfig(pin = "1234", shouldRemovePin = true)

Keyless.authenticate(
  configuration = configuration,
  onCompletion = { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
let configuration =  PinAuthConfig(pin: "1234", shouldRemovePin: true)

Keyless.authenticate(
  configuration: configuration,
  onCompletion: { /*TODO: process result*/  }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Future<void> removePin({
  required String pin
}) async
```

{% endtab %}

{% tab title="React Native" %}

```typescript
const config = new PinAuthConfig({
  pin: '1234',
  shouldRemovePin: true,
});

const result = await Keyless.authenticate(config);
result.fold({
  onSuccess(data) {
    logConsole('Auth result success ' + JSON.stringify(data, null, 2));
  },
  onFailure(error) {
    logConsole('Auth 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/pin-authentication.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.
