> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Auth0 Authentication API specs for Native Passkeys

# Native Passkeys API

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Native passkeys is currently available in limited Early Access. To learn more about Auth0 releases, review [Product Release Stages](/docs/troubleshoot/product-lifecycle/product-release-stages).
</Callout>

Passkeys are a phishing-resistant alternative to traditional forms of authentication (such as username and password) that offer an easier and more secure user experience. For complete implementation details, review [Native Passkeys for Mobile Applications](/docs/native-passkeys-for-mobile-applications).

Native passkeys use a combination of Auth0 and native iOS or Android APIs to embed challenge flows directly into your mobile application. The endpoints listed below are a subset of the Auth0 Authentication API and are currently available in limited Early Access. To learn more about using this API, review the [Authentication API Introduction](https://auth0.com/docs/api/authentication#introduction).

This article describes how to perform three activities (or "flows") related to passkeys:

* **Signup**: Creates a new user account with a passkey as the primary authentication method.
* **Enrollment**: Adds a passkey as an authentication method to an existing user's account.
* **Login**: Challenges an existing user to authenticate using a passkey associated with their account.

## Signup Flow

### Request Signup Challenge

`POST /passkey/register`

Initiates the passkey signup flow for a new user.

In response, Auth0 returns [PublicKeyCredentialCreationOptions](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialcreationoptions) and a session ID. Check `timeout` under `authn_params_public_key` in response for session timeout.

The passkey signup flow supports Organizations through the `organization` parameter, following the behavior described in [Login Flows for Organizations](/docs/manage-users/organizations/login-flows-for-organizations). If your application is configured for **Business Users**, you must provide the `organization` parameter and a valid Organization name or identifier value. After the user registers a passkey, Auth0 enrolls them in the provided Organization.

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameter</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>client\_id</code></td>
      <td><strong>Required</strong>. The <code>client\_id</code> of your application.</td>
    </tr>

    <tr>
      <td><code>realm</code></td>
      <td><strong>Optional</strong>. The name of the connection to associate with this user.<br /><br />If a connection is not specified, your tenant's default directory is used.</td>
    </tr>

    <tr>
      <td><code>user\_profile</code></td>
      <td><strong>Required</strong>. An object containing identification information for the user. By default, this includes a valid <code>email</code> and an optional display <code>name</code>.<br /><br />If you have enabled <a href="/docs/authenticate/database-connections/activate-and-configure-attributes-for-flexible-identifiers">Flexible Identifiers</a> for your database connection, you may use a combination of <code>email</code>, <code>phone\_number</code>, or <code>username</code> as identifiers. These options can be required or optional and must match your Flexible Identifier configuration.<br /><br />If the passed identifier (such as <code>email</code>) already exists in the directory, the user should be prompted to complete the Login flow instead.</td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```text lines
POST /passkey/register
Content-Type: application/json

{
  "client_id": "<CLIENT_ID>",
  "realm": "<OPTIONAL_CONNECTION>",
  "user_profile": {
	  "email": "<VALID_EMAIL_ADDRESS>",
	  "name": "<OPTIONAL_USER_DISPLAY_NAME>",
  }
}
```

##### Response

```json lines expandable
HTTP/1.1 200 OK
Content-Type: application/json

{
  "authn_params_public_key": {
    "challenge": "<GENERATED_CHALLENGE_FOR_THIS_SESSION>",
    "timeout": <MILLISECONDS>,
    "rp": {
      "id": "<THE_CUSTOM_DOMAIN>",
      "name": "<THE_CUSTOM_DOMAIN>"
    },
    "pubKeyCredParams": [
      { type: 'public-key', alg: -8 },
      { type: 'public-key', alg: -7 },
      { type: 'public-key', alg: -257 }
    ],
    "authenticatorSelection": {
      "residentKey": "required",
      "userVerification": "preferred"
    },
    "user": {
      "id": "<GENERATED_ID>",
      "name": "<USER-ENTERED_IDENTIFIER>",
      "displayName": "<USER-ENTERED_DISPLAY_NAME_OR_IDENTIFIER_IF_MISSING>"
    }
  },
  "auth_session": "<SESSION_ID>"
}
```

#### Remarks

* After the challenge request is complete, your application can continue the user registration process using native [Android](https://developer.android.com/identity/sign-in/credential-manager#create-passkey) or [iOS](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Register-a-new-account-on-a-service) APIs.
* You must then [authenticate the new user](#authenticate-new-user) using information retrieved through the native APIs to complete the flow.

### Authenticate New User

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Native Passkey registration is not currently supported when SMS/Email OTP verification is required on the same connection during signup.
</Callout>

`POST /oauth/token`

Uses the <Tooltip tip="Token Endpoint: Endpoint on the Authorization Server that is used to programmatically request tokens." cta="View Glossary" href="/docs/glossary?term=Token+endpoint">Token endpoint</Tooltip> to authenticate the user with the provided credentials to create their account and return the requested tokens.

The `authn_response` parameter is based on the [Web Authentication API specification](https://www.w3.org/TR/webauthn-3/). In the native passkey flow, the information passed to this endpoint can be retrieved through your mobile application’s native APIs:

* [Android registration documentation](https://developer.android.com/identity/sign-in/credential-manager#create-passkey)
* [iOS registration documentation](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Register-a-new-account-on-a-service)

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameter</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>grant\_type</code></td>
      <td><strong>Required</strong>. Include the value: <code>urn:okta:params:oauth:grant-type:webauthn</code></td>
    </tr>

    <tr>
      <td><code>client\_id</code></td>
      <td><strong>Required</strong>. The <code>client\_id</code> of your application</td>
    </tr>

    <tr>
      <td><code>realm</code></td>
      <td><strong>Optional</strong>. The name of the connection to associate with the user. If a connection is not specified, your tenant's default directory is used.</td>
    </tr>

    <tr>
      <td><code>scope</code></td>
      <td><strong>Optional</strong>. Use <code>openid</code> to get an ID token or <code>openid profile email</code> to include user profile information in the ID token.</td>
    </tr>

    <tr>
      <td><code>audience</code></td>
      <td><strong>Optional</strong>. API identifier of the API for which you want to get an access token.</td>
    </tr>

    <tr>
      <td><code>auth\_session</code></td>
      <td><strong>Required</strong>. Session ID returned during the initial passkey challenge request.</td>
    </tr>

    <tr>
      <td><code>authn\_response</code></td>
      <td><strong>Required</strong>. An object containing the following items:<ul><li><code>id</code></li><li><code>rawId</code></li><li><code>type</code></li><li><code>authenticatorAttachment</code></li><li><code>response</code></li></ul></td>
    </tr>

    <tr>
      <td><code>authn\_response.id</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.rawId</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.type</code></td>
      <td><strong>Required</strong>. Include the value: <code>public-key</code></td>
    </tr>

    <tr>
      <td><code>authn\_response.authenticatorAttachment</code></td>
      <td><strong>Required</strong>. Include the values:<ul><li><code>platform</code></li><li><code>cross-platform</code></li></ul></td>
    </tr>

    <tr>
      <td><code>authn\_response.response</code></td>
      <td><strong>Required</strong>. An object containing the following items: <ul><li><code>clientDataJSON</code>: Contains JSON-compatible serialization of client data; inherited from the <a href="https://www.w3.org/TR/webauthn-3/#authenticatorresponse">AuthenticatorResponse</a>.</li><li><code>attestationObject</code>: Contains authenticator data and an attestation statement; inherited from the <a href="https://www.w3.org/TR/webauthn-3/#authenticatorresponse">AuthenticatorResponse</a>.</li></ul></td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```text lines
POST /oauth/token
Content-Type: application/json

{
  "grant_type": "urn:okta:params:oauth:grant-type:webauthn",
  "client_id": "<CLIENT_ID>",
  "realm": "<OPTIONAL_CONNECTION>",
  "scope": "<OPTIONAL_REQUESTED_SCOPE>",
  "audience": "<OPTIONAL_REQUESTED_AUDIENCE>"
  "auth_session": "<SESSION_ID_FROM_THE_FIRST_REQUEST>",
  "authn_response": {
    "id": "<BASE64URL_ID>",
    "rawId": "<BASE64URL_RAWID>",
    "type": "public-key",
    "authenticatorAttachment": "platform|cross-platform",
    "response": {
      "clientDataJSON": "<BASE64URL_CLIENT_DATA_JSON>",
      "attestationObject": "<BASE64URL_ATTESTATION_OBJECT>",
      <OTHER_PROPERTIES>
    }  
}
```

##### Response

```json lines
HTTP/1.1 200 OK
Content-Type: application/json

{
  "access_token": "<BASE64_TOKEN>",
  "refresh_token": "<BASE64_TOKEN>",
  "id_token": "<BASE64_TOKEN>",
  "token_type": "Bearer",
  "expires_in": <SECONDS>
}
```

## Enrollment Flow

Enrolling a new passkey for a user involves a two-step process using the My Account API. This flow ensures that the passkey enrollment is initiated securely and then verified.

Before initiating the enrollment flow, ensure you have an <Tooltip tip="Access Token: Authorization credential, in the form of an opaque string or JWT, used to access an API." cta="View Glossary" href="/docs/glossary?term=access+token">access token</Tooltip> with the `create:me:authentication_methods` scope for the `/me` endpoint.

### Initiate Passkey Enrollment

`POST /me/v1/authentication-methods`

The first step is to initiate the enrollment process. This is done by making a POST request to the `/me/v1/authentication-methods` endpoint.

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameter</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>type</code></td>
      <td><strong>Required</strong>. Include the value: <code>public-key</code>.</td>
    </tr>

    <tr>
      <td><code>connection</code></td>
      <td><strong>Optional</strong>. The name of the connection in which to create the passkey.</td>
    </tr>

    <tr>
      <td><code>identity</code></td>
      <td><strong>Optional</strong>. The user's identity. Used with linked accounts.</td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```json lines
{
  "type": "passkey",
  "connection": "CONNECTION_NAME",
  "identity": "IDENTITY_USER_ID"
}
```

##### Response

```json lines
{
  "authn_params_public_key": {
    "challenge": "GENERATED_CHALLENGE_FOR_THIS_SESSION",
    "timeout": MILLISECONDS,
    "rp": {
      "id": "CUSTOM_DOMAIN",
      "name": "CUSTOM_DOMAIN"
    },
    "pubKeyCredParams": [
      { type: 'public-key', alg: -8 },
      { type: 'public-key', alg: -7 },
      { type: 'public-key', alg: -257 }
    ],
    "authenticatorSelection": {
      "residentKey": "required",
      "userVerification": "preferred"
    },
    "user": {
      "id": "GENERATED_ID",
      "name": "USER_ENTERED_IDENTIFIER",
      "displayName": "USER_ENTERED_DISPLAY_NAME_OR_IDENTIFIER_IF_MISSING"
    }
  },
  "auth_session": "SESSION_ID"
}
```

#### Remarks

* The `auth_session` property in the response body is the identifier of the current authentication session. This must be passed to the `/verify` endpoint.
* After the challenge request is complete, your application can continue the user enrollment process using native [Android](https://developer.android.com/identity/sign-in/credential-manager#create-passkey) or [iOS](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Register-a-new-account-on-a-service) APIs. This will prompt the user to create a passkey with their authenticator (such as fingerprint scanner, security key, or phone).

### Verify Passkey Enrollment

`POST /me/v1/authentication-methods/passkey|new/verify`

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  The ID in the path is always `passkey|new` for new enrollments.
</Callout>

Once the user has successfully created the passkey with their authenticator, the client application will receive an AuthenticatorAttestationResponse from the WebAuthn API. This response needs to be sent back to the Auth0 service to complete and verify the enrollment.

* [Android registration documentation](https://developer.android.com/identity/sign-in/credential-manager#create-passkey)
* [iOS registration documentation](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Register-a-new-account-on-a-service)

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameters</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>auth\_session</code></td>
      <td><strong>Required</strong>. The session identifier received in the response of the first POST request to <code>/me/v1/authentication-methods</code>.</td>
    </tr>

    <tr>
      <td><code>authn\_response</code></td>
      <td><strong>Required</strong>. The <code>authn\_response</code> parameter is based on the Web Authentication API specification. In the native passkey flow, the information passed to this endpoint can be retrieved through your mobile application’s native APIs.</td>
    </tr>

    <tr>
      <td><code>authn\_response.id</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.rawId</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.type</code></td>
      <td><strong>Required</strong>. Include the value: <code>public-key</code>.</td>
    </tr>

    <tr>
      <td><code>authn\_response.authenticatorAttachment</code></td>
      <td><strong>Required</strong>. Include the values: <code>platform</code>, <code>cross-platform</code>.</td>
    </tr>

    <tr>
      <td><code>authn\_response.response</code></td>
      <td><strong>Required</strong>. An object containing the following items: <ul><li><code>clientDataJson</code>: Contains JSON-compatible serialization of client data; inherited from the <code>AuthenticatorResponse</code>.</li><li><code>attestationObject</code>: Contains authenticator data and an attestation statement; inherited from the <code>AuthenticatorResponse</code>.</li></ul></td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```json lines
{
  "auth_session": "SESSION_ID",
  "authn_response": {
    "id": "BASE64URL_ID",
    "rawId": "BASE64URL_RAWID",
    "type": "public-key",
    "authenticatorAttachment": "platform|cross-platform",
    "response": {
      "clientDataJSON": "BASE64URL_CLIENT_DATA_JSON",
      "attestationObject": "BASE64URL_ATTESTATION_OBJECT"
    }
  }
}
```

#### Remarks

Once this step is completed successfully, the passkey is enrolled for the user and can be used for future authentications.

## Login Flow

### Request Login Challenge

`POST /passkey/challenge`

Initiates the passkey login flow for an existing user who saved a passkey to their account during their initial signup.

In response, Auth0 returns [PublicKeyCredentialRequestOptions](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialrequestoptions) and a session ID. Check `timeout` under `authn_params_public_key` in response for session timeout.

The passkey login flow supports Organizations through the `organization` parameter, following the behavior described in [Login Flows for Organizations](/docs/manage-users/organizations/login-flows-for-organizations). If your application is configured for **Business Users**, you must provide the `organization` parameter and a valid Organization name or identifier value.

All issued tokens are in the context of the provided Organization. If you enabled [Auto-Membership](/docs/manage-users/organizations/login-flows-for-organizations#auto-membership) for your Organization, the user is automatically enrolled in the Organization after successfully authenticating.

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameter</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>client\_id</code></td>
      <td><strong>Required</strong>. The <code>client\_id</code> of your application.</td>
    </tr>

    <tr>
      <td><code>realm</code></td>
      <td><strong>Optional</strong>. The name of the connection to associate with the user.<br /><br />If a connection is not specified, your tenant's default directory is used.</td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```text lines
POST /passkey/challenge
Content-Type: application/json

{
  "client_id": "<CLIENT_ID>",
  "realm": "<OPTIONAL_CONNECTION>"
}
```

##### Response

```json lines
HTTP/1.1 200 OK
Content-Type: application/json

{
  "authn_params_public_key": {
    "challenge": "<GENERATED_CHALLENGE_FOR_THIS_SESSION>",
    "timeout": <AUTH_TIMEOUT_IN_MILLISECONDS>,
    "rpId": "<CUSTOM_DOMAIN>",
    "userVerification": "preferred"
  },
  "auth_session": "<SESSION_ID>"
}
```

#### Remarks

* After the challenge request is complete, your application can continue the login process using native [Android](https://developer.android.com/identity/sign-in/credential-manager#sign-in) or [iOS](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Connect-to-a-service-with-an-existing-account) APIs.
* You must then [authenticate the existing user](#authenticate-existing-user) using information retrieved through the native APIs to complete the flow.

### Authenticate Existing User

`POST /oauth/token`

Uses the Token endpoint to authenticate the user with the provided credentials and return the requested tokens.

The `authn_response` parameter is based on the [Web Authentication API specification](https://www.w3.org/TR/webauthn-3/). In the native passkey flow, the information passed to this endpoint can be retrieved through your mobile application’s native APIs:

* [Android login documentation](https://developer.android.com/identity/sign-in/credential-manager#sign-in)
* [iOS login documentation](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Connect-to-a-service-with-an-existing-account)

#### Request Parameters

<table class="table">
  <thead>
    <tr>
      <th><strong>Parameter</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>grant\_type</code></td>
      <td><strong>Required</strong>. Include the value: <code>urn:okta:params:oauth:grant-type:webauthn</code></td>
    </tr>

    <tr>
      <td><code>client\_id</code></td>
      <td><strong>Required</strong>. The <code>client\_id</code> of your application</td>
    </tr>

    <tr>
      <td><code>realm</code></td>
      <td><strong>Optional</strong>. The name of the connection to associate with the user. If a connection is not specified, your tenant's default directory is used.</td>
    </tr>

    <tr>
      <td><code>scope</code></td>
      <td><strong>Optional</strong>. Use <code>openid</code> to get an ID token or <code>openid profile email</code> to include user profile information in the ID token.</td>
    </tr>

    <tr>
      <td><code>audience</code></td>
      <td><strong>Optional</strong>. API identifier of the API for which you want to get an access token.</td>
    </tr>

    <tr>
      <td><code>auth\_session</code></td>
      <td><strong>Required</strong>. Session ID returned during the initial passkey challenge request.</td>
    </tr>

    <tr>
      <td><code>authn\_response</code></td>
      <td><strong>Required</strong>. An object containing the following items:<ul><li><code>id</code></li><li><code>rawId</code></li><li><code>type</code></li><li><code>authenticatorAttachment</code></li><li><code>response</code></li><li><code>clientExtensionResults</code></li></ul></td>
    </tr>

    <tr>
      <td><code>authn\_response.id</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.rawId</code></td>
      <td><strong>Required</strong>. Base64URL credential ID.</td>
    </tr>

    <tr>
      <td><code>authn\_response.type</code></td>
      <td><strong>Required</strong>. Include the value: <code>public-key</code></td>
    </tr>

    <tr>
      <td><code>authn\_response.authenticatorAttachment</code></td>
      <td><strong>Required</strong>. Include the values:<ul><li><code>platform</code></li><li><code>cross-platform</code></li></ul></td>
    </tr>

    <tr>
      <td><code>authn\_response.response</code></td>
      <td><strong>Required</strong>. An object containing the following items: <ul><li><code>authenticatorData</code>: Contains <a href="https://www.w3.org/TR/webauthn-3/#authenticator-data">authenticator data</a> returned by the authenticator.</li><li><code>clientDataJSON</code>: Contains JSON-compatible serialization of client data; inherited from the <a href="https://www.w3.org/TR/webauthn-3/#authenticatorresponse">AuthenticatorResponse</a>.</li><li><code>signature</code>: Base64URL signature returned from the authenticator.</li><li><code>userHandle</code>: Base64URL identifier for the user account, returned as <code>user.id</code> in registration step.</li></ul></td>
    </tr>

    <tr>
      <td><code>authn\_response.clientExtensionResults</code></td>
      <td><strong>Optional</strong>. Contains results of processing client extensions requested by the relying party.</td>
    </tr>
  </tbody>
</table>

#### Code Samples

##### Request

```text lines
POST /oauth/token
Content-Type: application/json

{
  "grant_type": "urn:okta:params:oauth:grant-type:webauthn",
  "client_id": "<CLIENT_ID>",
  "realm": "<OPTIONAL_CONNECTION>",
  "scope": "<OPTIONAL_REQUESTED_SCOPE>",
  "audience": "<OPTIONAL_REQUESTED_AUDIENCE>"
  "auth_session": "<SESSION_ID_FROM_THE_FIRST_REQUEST>",
  "authn_response": {
    "id": "<BASE64URL_ID>",
    "rawId": "<BASE64URL_RAWID>",
    "type": "public-key",
    "authenticatorAttachment": "platform|cross-platform",
    "response": {
      "authenticatorData": "<BASE64URL_AUTHENTICATORDATA>",
      "clientDataJSON": "<BASE64URL_CLIENTDATAJSON>",
      "signature": "<BASE64URL_SIGNATURE>",
      "userHandle": "<BASE64URL_USERHANDLE>"
    },
    "clientExtensionResults": <OPTIONAL_OBJECT>
}
```

##### Response

```json lines
HTTP/1.1 200 OK
Content-Type: application/json

{
  "access_token": "<BASE64_TOKEN>",
  "refresh_token": "<BASE64_TOKEN>",
  "id_token": "<BASE64_TOKEN>",
  "token_type": "Bearer",
  "expires_in": <SECONDS>
}
```
