> ## Documentation Index
> Fetch the complete documentation index at: https://docs.authsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# In-app verification

> Implement in-app verification using the Authsignal SDKs for iOS, Android, React Native, and Flutter.

<Info>
  Check out our end-to-end guide on [how to implement in-app
  verification](/authentication-methods/app-verification/in-app).
</Info>

## Adding a credential

Adding an in-app credential generates a private/public key pair, where the private key is secured on the user's mobile device and the public key is held by Authsignal.

This operation must be authorized with a short-lived token, which can be obtained by [tracking an action from your backend](/authentication-methods/app-verification/push#1-generate-enrollment-token) in an authenticated context.

<CodeGroup>
  ```swift iOS theme={null}
  await authsignal.inapp.addCredential(token: "eyJhbGciOiJ...")
  ```

  ```kotlin Android theme={null}
  authsignal.inapp.addCredential(token = "eyJhbGciOiJ...")
  ```

  ```ts React Native theme={null}
  await authsignal.inapp.addCredential({ token: "eyJhbGciOiJ..." });
  ```
</CodeGroup>

### Parameters

<ResponseField name="token" type="string">
  A short-lived token obtained by [tracking an
  action](/advanced-usage/authenticator-binding#tracking-an-action-to-generate-a-token).
</ResponseField>

<ResponseField name="performAttestation" type="boolean">
  When set to `true`, the SDK will generate a platform-specific attestation during enrollment:

  * **iOS**: Uses [App Attest](https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity) (DCAppAttestService) to generate an attestation bound to the device.
  * **Android**: Uses [Play Integrity](https://developer.android.com/google/play/integrity) to generate an integrity token.

  The attestation is generated internally by the SDK and sent to the Authsignal server for verification.
  This provides an additional layer of assurance that the credential is being enrolled from a legitimate app on a real device.
</ResponseField>

### Response

<ResponseField name="response" type="AuthsignalResponse<AppCredential>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error.
    </ResponseField>

    <ResponseField name="errorCode" type="string">
      A formatted error code which may additionally be present if the SDK call encountered an error.
      Possible values are: `token_not_set`, `expired_token` or `network_error`.
    </ResponseField>

    <ResponseField name="data" type="AppCredential | null">
      <Expandable title="properties">
        <ResponseField name="credentialId" type="string" required>
          The ID of the app credential.
        </ResponseField>

        <ResponseField name="createdAt" type="string" required>
          The date and time the app credential was created.
        </ResponseField>

        <ResponseField name="userId" type="string" required>
          The user ID of the user that the app credential belongs to.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Getting a credential

Get information about the in-app credential stored on the device, if one exists.

<CodeGroup>
  ```swift iOS theme={null}
  let response = await authsignal.inapp.getCredential()
  ```

  ```kotlin Android theme={null}
  val response = authsignal.inapp.getCredential()
  ```

  ```ts React Native theme={null}
  const response = await authsignal.inapp.getCredential();
  ```

  ```dart Flutter theme={null}
  final response = await authsignal.inapp.getCredential();
  ```
</CodeGroup>

### Response

<ResponseField name="response" type="AuthsignalResponse<AppCredential>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error.
    </ResponseField>

    <ResponseField name="errorCode" type="string">
      A formatted error code which may additionally be present if the SDK call encountered an error.
      Possible values are: `invalid_credential` when the credential exists on the device but has
      been removed from the server.
    </ResponseField>

    <ResponseField name="data" type="AppCredential">
      <Expandable title="properties">
        <ResponseField name="credentialId" type="string" required>
          The ID of the app credential.
        </ResponseField>

        <ResponseField name="createdAt" type="string" required>
          The date and time the app credential was created.
        </ResponseField>

        <ResponseField name="lastAuthenticatedAt" type="string">
          The date and time the app credential was last used for authentication. Will be null if the
          credential has never been used.
        </ResponseField>

        <ResponseField name="userId" type="string" required>
          The user ID of the user that the app credential belongs to.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Removing a credential

<CodeGroup>
  ```swift iOS theme={null}
  await authsignal.inapp.removeCredential()
  ```

  ```kotlin Android theme={null}
  authsignal.inapp.removeCredential()
  ```

  ```ts React Native theme={null}
  await authsignal.inapp.removeCredential();
  ```

  ```dart Flutter theme={null}
  await authsignal.inapp.removeCredential();
  ```
</CodeGroup>

### Response

<ResponseField name="response" type="AuthsignalResponse<boolean>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error. This could
      occur if the credential on the device is no longer valid because the corresponding user
      authenticator has been deleted in the Authsignal Portal.
    </ResponseField>

    <ResponseField name="data" type="boolean">
      True if the app credential was successfully removed.
    </ResponseField>
  </Expandable>
</ResponseField>

## Verifying an action

Verify an action in your app using the credential stored securely on the device.

<CodeGroup>
  ```swift iOS theme={null}
  let response = await authsignal.inapp.verify()

  let token = response.data?.token
  ```

  ```kotlin Android theme={null}
  val response = authsignal.inapp.verify()

  val token = response.data?.token
  ```

  ```ts React Native theme={null}
  const response = await authsignal.inapp.verify();

  const token = response.data?.token;
  ```

  ```dart Flutter theme={null}
  final response = await authsignal.inapp.verify();

  final token = response.data?.token;
  ```
</CodeGroup>

### Response

<ResponseField name="response" type="AuthsignalResponse<VerifyDeviceResponse>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error. This could
      occur if the credential on the device is no longer valid because the corresponding user
      authenticator has been deleted in the Authsignal Portal.
    </ResponseField>

    <ResponseField name="data" type="VerifyDeviceResponse">
      <Expandable title="properties">
        <ResponseField name="token" type="string" required>
          A token which can be used for [server-side
          validation](/sdks/server/challenges#validate-challenge).
        </ResponseField>

        <ResponseField name="userId" type="string" required>
          The user ID of the user that the device credential belongs to.
        </ResponseField>

        <ResponseField name="userAuthenticatorId" type="string" required>
          The user authenticator ID that the device credential belongs to.
        </ResponseField>

        <ResponseField name="username" type="string">
          The username of the user that the device credential belongs to.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Creating a PIN

Create a custom PIN backed by a cryptographic in-app credential stored securely on the user's device.

<CodeGroup>
  ```swift iOS theme={null}
  let response = await authsignal.inapp.createPin(
      token: "eyJhbGciOiJ...",
      username: "jane.smith@authsignal.com",
      pin: "123456"
  )
  ```

  ```kotlin Android theme={null}
  val response = authsignal.inapp.createPin(
      token = "eyJhbGciOiJ...",
      username = "jane.smith@authsignal.com",
      pin = "123456",
  )
  ```

  ```ts React Native theme={null}
  const response = await authsignal.inapp.createPin({
    token: "eyJhbGciOiJ...",
    username: "jane.smith@authsignal.com",
    pin: "123456",
  });
  ```
</CodeGroup>

### Parameters

<ResponseField name="token" type="string">
  A short-lived token obtained by [tracking an
  action](/advanced-usage/authenticator-binding#tracking-an-action-to-generate-a-token).
</ResponseField>

<ResponseField name="username" type="string">
  The username associated with the PIN. A device can have multiple PINs stored for different users.
</ResponseField>

<ResponseField name="pin" type="string">
  The PIN value. Must be a valid 6-digit numeric value.
</ResponseField>

### Response

<ResponseField name="response" type="AuthsignalResponse<AppCredential>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error.
    </ResponseField>

    <ResponseField name="errorCode" type="string">
      A formatted error code which may additionally be present if the SDK call encountered an error.
      Possible values are: `token_not_set`, `expired_token` or `network_error`.
    </ResponseField>

    <ResponseField name="data" type="AppCredential | null">
      <Expandable title="properties">
        <ResponseField name="credentialId" type="string" required>
          The ID of the app credential.
        </ResponseField>

        <ResponseField name="createdAt" type="string" required>
          The date and time the app credential was created.
        </ResponseField>

        <ResponseField name="userId" type="string" required>
          The user ID of the user that the app credential belongs to.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Verifying a PIN

Check a submitted PIN value against the value stored on the device and use the associated in-app credential to verify the user.

<CodeGroup>
  ```swift iOS theme={null}
  let response = await authsignal.inapp.verifyPin(
      username: "jane.smith@authsignal.com",
      pin: "123456"
  )

  let isVerified = response.data?.isVerified
  let token = response.data?.token
  ```

  ```kotlin Android theme={null}
  val response = authsignal.inapp.verifyPin(
      username = "jane.smith@authsignal.com",
      pin = "123456",
  )

  val isVerified = response.data?.isVerified
  val token = response.data?.token
  ```

  ```ts React Native theme={null}
  const response = await authsignal.inapp.verifyPin({
    username: "jane.smith@authsignal.com",
    pin: "123456",
  });

  const isVerified = response.data?.isVerified;
  const token = response.data?.token;
  ```
</CodeGroup>

### Response

<ResponseField name="response" type="AuthsignalResponse<VerifyPinResponse>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error. This could
      occur if the credential on the device is no longer valid because the corresponding user
      authenticator has been deleted in the Authsignal Portal.
    </ResponseField>

    <ResponseField name="data" type="VerifyPinResponse">
      <Expandable title="properties">
        <ResponseField name="isVerified" type="boolean" required>
          True if PIN verification is successful.
        </ResponseField>

        <ResponseField name="token" type="string" required>
          A token which can be used for [server-side
          validation](/sdks/server/challenges#validate-challenge).
        </ResponseField>

        <ResponseField name="userId" type="string" required>
          The user ID of the user that the PIN and in-app credential belong to.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Get PIN usernames on device

Get all the usernames for PINs currently stored on the device. This method can be used if allowing multiple users to create PINs on the same device.

<CodeGroup>
  ```swift iOS theme={null}
  let response = await authsignal.inapp.getAllPinUsernames()

  let usernames = response.data
  ```

  ```kotlin Android theme={null}
  val response = authsignal.inapp.getAllPinUsernames()

  val usernames = response.data
  ```

  ```ts React Native theme={null}
  const response = await authsignal.inapp.getAllPinUsernames();

  const usernames = response.data;
  ```
</CodeGroup>

### Response

<ResponseField name="response" type="AuthsignalResponse<string[]>">
  <Expandable title="properties">
    <ResponseField name="error" type="string">
      An unstructured error description present if the SDK call encountered an error.
    </ResponseField>

    <ResponseField name="data" type="string[]">
      An array of usernames for all the PINs currently stored on the device
    </ResponseField>
  </Expandable>
</ResponseField>
