# Biometrics



**Access:** `startiapp.Biometrics`

<Callout type="info">
  For step-by-step guides to implementing biometric login — see [Biometric Login](/sdk/how-to/biometric-login) and [Biometric Login with OAuth](/sdk/how-to/biometric-oauth-login).
</Callout>

Methods [#methods]

scan(title?, reason?): Promise<boolean> [#scantitle-reason-promiseboolean]

Triggers a biometric scan (fingerprint or face recognition) and returns whether it succeeded.

**Parameters:**

| Parameter | Type     | Required | Default                            | Description                             |
| --------- | -------- | -------- | ---------------------------------- | --------------------------------------- |
| title     | `string` | No       | `"Prove you have fingers!"`        | The title shown in the biometric prompt |
| reason    | `string` | No       | `"Can't let you in if you don't."` | The reason/subtitle shown in the prompt |

**Returns:** `Promise<boolean>` —`true` if the scan was successful.

**Example:**

```typescript
const success = await startiapp.Biometrics.scan(
  "Verify Identity",
  "Please authenticate to continue"
);

if (success) {
  console.log("Biometric scan passed");
}
```

***

getAuthenticationType(): Promise<BiometricsAuthenticationType> [#getauthenticationtype-promisebiometricsauthenticationtype]

Returns the type of biometric authentication available on the device.

**Returns:** `Promise<BiometricsAuthenticationType>` —`"face"`, `"fingerprint"`, or `"none"`.

**Example:**

```typescript
const type = await startiapp.Biometrics.getAuthenticationType();

if (type === "face") {
  console.log("Face ID available");
} else if (type === "fingerprint") {
  console.log("Fingerprint available");
} else {
  console.log("No biometrics available");
}
```

***

checkAccess(): Promise<PermissionStatus> [#checkaccess-promisepermissionstatus]

Checks the current permission status for biometrics on the device.

**Returns:** `Promise<PermissionStatus>` —Object with a `granted` boolean.

**Example:**

```typescript
const status = await startiapp.Biometrics.checkAccess();

if (status.granted) {
  console.log("Biometrics access granted");
}
```

***

setSecuredContent(content: unknown): Promise<void> [#setsecuredcontentcontent-unknown-promisevoid]

Saves arbitrary content to the device's secure keychain storage. The content is JSON-serialized before storing.

**Parameters:**

| Parameter | Type      | Required | Description                                 |
| --------- | --------- | -------- | ------------------------------------------- |
| content   | `unknown` | Yes      | The data to store (will be JSON-serialized) |

**Returns:** `Promise<void>`

**Example:**

```typescript
await startiapp.Biometrics.setSecuredContent({
  apiToken: "abc123",
  refreshToken: "xyz789",
});
```

***

getSecuredContent<T>(title?, reason?): Promise<T | null> [#getsecuredcontentttitle-reason-promiset--null]

Retrieves previously stored secured content. Triggers a biometric scan to authorize access.

**Parameters:**

| Parameter | Type     | Required | Default                            | Description                 |
| --------- | -------- | -------- | ---------------------------------- | --------------------------- |
| title     | `string` | No       | `"Prove you have fingers!"`        | The biometric prompt title  |
| reason    | `string` | No       | `"Can't let you in if you don't."` | The biometric prompt reason |

**Returns:** `Promise<T | null>` —The deserialized content, or `null` if nothing is stored or parsing fails.

**Example:**

```typescript
interface Tokens {
  apiToken: string;
  refreshToken: string;
}

const tokens = await startiapp.Biometrics.getSecuredContent<Tokens>(
  "Access Tokens",
  "Authenticate to retrieve your saved tokens"
);

if (tokens) {
  console.log("API Token:", tokens.apiToken);
}
```

***

hasSecuredContent(): Promise<boolean> [#hassecuredcontent-promiseboolean]

Checks whether secured content exists in the keychain without triggering a biometric scan.

**Returns:** `Promise<boolean>` —`true` if secured content exists.

**Example:**

```typescript
const hasContent = await startiapp.Biometrics.hasSecuredContent();

if (hasContent) {
  console.log("Secured content is stored");
}
```

***

removeSecuredContent(): Promise<void> [#removesecuredcontent-promisevoid]

Removes the secured content from the keychain.

**Returns:** `Promise<void>`

**Example:**

```typescript
await startiapp.Biometrics.removeSecuredContent();
```

***

setUsernameAndPassword(username, password): Promise<void> [#setusernameandpasswordusername-password-promisevoid]

Saves a username and password pair to the device's secure keychain.

**Parameters:**

| Parameter | Type     | Required | Description           |
| --------- | -------- | -------- | --------------------- |
| username  | `string` | Yes      | The username to store |
| password  | `string` | Yes      | The password to store |

**Returns:** `Promise<void>`

**Example:**

```typescript
await startiapp.Biometrics.setUsernameAndPassword("john@example.com", "s3cret");
```

***

getUsernameAndPassword(title?, reason?): Promise<{ username: string; password: string } | null> [#getusernameandpasswordtitle-reason-promise-username-string-password-string---null]

Retrieves the saved username and password. Triggers a biometric scan to authorize access.

**Parameters:**

| Parameter | Type     | Required | Default                            | Description                 |
| --------- | -------- | -------- | ---------------------------------- | --------------------------- |
| title     | `string` | No       | `"Prove you have fingers!"`        | The biometric prompt title  |
| reason    | `string` | No       | `"Can't let you in if you don't."` | The biometric prompt reason |

**Returns:** `Promise<{ username: string; password: string } | null>` —The credentials, or `null` if none are stored.

**Example:**

```typescript
const credentials = await startiapp.Biometrics.getUsernameAndPassword(
  "Login",
  "Authenticate to auto-fill your credentials"
);

if (credentials) {
  console.log("Username:", credentials.username);
  // Auto-fill the login form
  document.querySelector<HTMLInputElement>("#username")!.value = credentials.username;
  document.querySelector<HTMLInputElement>("#password")!.value = credentials.password;
}
```

***

hasUsernameAndPassword(): Promise<boolean> [#hasusernameandpassword-promiseboolean]

Checks whether a username and password pair is stored without triggering a biometric scan.

**Returns:** `Promise<boolean>` —`true` if credentials are stored.

**Example:**

```typescript
const hasCreds = await startiapp.Biometrics.hasUsernameAndPassword();

if (hasCreds) {
  console.log("Saved credentials available — show biometric login button");
}
```

***

removeUsernameAndPassword(): Promise<void> [#removeusernameandpassword-promisevoid]

Removes the saved username and password from the keychain.

**Returns:** `Promise<void>`

**Example:**

```typescript
await startiapp.Biometrics.removeUsernameAndPassword();
```

***

startSaveUsernameAndPassword(request): Promise<void> [#startsaveusernameandpasswordrequest-promisevoid]

Begins the automatic credential capture flow. This attaches middleware to a login form's submit button that captures the username and password when the user submits the form.

After a successful login, call [`endSaveUsernameAndPassword()`](#endsaveusernameandpasswordconfig-promisevoid) to finalize saving.

**Parameters:**

| Parameter | Type                                                                            | Required | Description                                       |
| --------- | ------------------------------------------------------------------------------- | -------- | ------------------------------------------------- |
| request   | [`SaveUsernameAndPasswordConfiguration`](#saveusernameandpasswordconfiguration) | Yes      | Configuration for form selectors and localization |

**Returns:** `Promise<void>`

**Example:**

```typescript
await startiapp.Biometrics.startSaveUsernameAndPassword({
  usernameInputFieldSelector: "#username",
  passwordInputFieldSelector: "#password",
  submitButtonSelector: "#login-button",
  title: "Save Login",
  reason: "Save your credentials for quick login next time",
  language: "en",
});
```

***

endSaveUsernameAndPassword(config?): Promise<void> [#endsaveusernameandpasswordconfig-promisevoid]

Completes the credential capture flow. Call this after a successful login. It will prompt the user (if they have not previously consented) to save credentials using biometrics, then store them if the user agrees.

**Parameters:**

| Parameter | Type                                                                                  | Required | Description                                |
| --------- | ------------------------------------------------------------------------------------- | -------- | ------------------------------------------ |
| config    | [`EndSaveUsernameAndPasswordConfiguration`](#endsaveusernameandpasswordconfiguration) | No       | Optional key to identify the configuration |

**Returns:** `Promise<void>`

**Example:**

```typescript
// After successful login
await startiapp.Biometrics.endSaveUsernameAndPassword();
```

***

Types [#types]

BiometricsAuthenticationType [#biometricsauthenticationtype]

```typescript
type BiometricsAuthenticationType = "none" | "face" | "fingerprint";
```

PermissionStatus [#permissionstatus]

```typescript
interface PermissionStatus {
  granted: boolean;
}
```

SaveUsernameAndPasswordConfiguration [#saveusernameandpasswordconfiguration]

Full configuration for the automated credential capture flow. Combines form selectors with internationalization settings.

```typescript
type SaveUsernameAndPasswordConfiguration = {
  key?: string;
} & SaveUsernameAndPasswordConfigurationSelectors &
  SaveUsernameAndPasswordI18n;
```

SaveUsernameAndPasswordConfigurationSelectors [#saveusernameandpasswordconfigurationselectors]

```typescript
type SaveUsernameAndPasswordConfigurationSelectors = {
  usernameInputFieldSelector: string;
  passwordInputFieldSelector: string;
  submitButtonSelector: string;
  executingButtonSelector?: string;
};
```

SaveUsernameAndPasswordI18n [#saveusernameandpasswordi18n]

Internationalization options for the biometric consent dialog. Provide one of three options:

1. A built-in `language` (`"da"` or `"en"`)
2. A `confirmMessageTemplate` with optional biometrics type translations
3. Full custom `translations`

```typescript
type SaveUsernameAndPasswordI18n = {
  title: string;
  reason: string;
} & (
  | { language?: "da" | "en" }
  | {
      confirmMessageTemplate: string;
      biometricsTypeTranslations?: {
        face: string;
        fingerprint: string;
      };
    }
  | {
      translations: {
        nextTime: {
          title: string;
          subtitle: string;
          acceptedButtonText: string;
          declinedButtonText: string;
        };
        biometricsType: {
          face: string;
          fingerprint: string;
        };
      };
    }
);
```

EndSaveUsernameAndPasswordConfiguration [#endsaveusernameandpasswordconfiguration]

```typescript
type EndSaveUsernameAndPasswordConfiguration = {
  key?: string;
};
```

BiometricsResultResponse [#biometricsresultresponse]

```typescript
type BiometricsResultResponse<T> = {
  key: string;
  result: T;
};
```
