# Import Passkeys API

API documentation for the FusionAuth Import Passkeys API.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

This API is used to bulk import multiple passkeys into FusionAuth. Reasonable defaults are provided for optional fields. This request is useful for migrating data from an existing database into FusionAuth.

## Request

[API Key Authentication](https://fusionauth.io/docs/apis/authentication.md#api-key-authentication)

Import Multiple Passkeys

`POST /api/webauthn/import`

#### Request Headers

`X-FusionAuth-TenantId`

*   String
*   optional

The unique Id of the tenant used to scope this API request. The tenant Id is not required on this request when only one tenant has been configured. If there is more than one tenant, the tenant Id is required.

Supply the tenant Id via this header or by using an API Key scoped to a tenant, which implicitly supplies the tenant Id.

See [Making an API request using a Tenant Id](https://fusionauth.io/docs/apis/authentication.md#making-an-api-request-using-a-tenant-id) for additional information.

### Request Body

`credentials`

*   Array
*   required

The list of passkeys to import.

`credentials[x].algorithm`

*   Long
*   required

The identifier for the signing algorithm used with the passkey. These values are defined by the [IANA COSE Algorithms registry](https://www.iana.org/assignments/cose/cose.xhtml). FusionAuth supports a subset of these algorithms.

*Supported algorithms*

| Name | Value | Description |
| --- | --- | --- |
| RS256 | \-257 | RSASSA-PKCS1-v1\_5 using SHA-256 |
| RS384 | \-258 | RSASSA-PKCS1-v1\_5 using SHA-384 |
| RS512 | \-259 | RSASSA-PKCS1-v1\_5 using SHA-512 |
| PS256 | \-37 | RSASSA-PSS w/ SHA-256 |
| PS384 | \-38 | RSASSA-PSS w/ SHA-384 |
| PS512 | \-39 | RSASSA-PSS w/ SHA-512 |
| ES256 | \-7 | ECDSA w/ SHA-256 |
| ES384 | \-35 | ECDSA w/ SHA-384 |
| ES512 | \-36 | ECDSA w/ SHA-512 |

`credentials[x].attestationType`

*   String
*   optional
*   Defaults to none

The attestation type provided when the passkey was registered. FusionAuth doesn't validate the attestation on import. Supported values are:

*   `anonymization-ca`
*   `attestation-ca`
*   `basic`
*   `none`
*   `self`

Passkeys registered in FusionAuth currently only support the `none` option, but another value can be supplied during passkey import.

`credentials[x].authenticatorSupportsUserVerification`

*   Boolean
*   optional
*   Defaults to false

Indicates whether this authenticator supports user verification. User verification ensures that the user is authorized to use the authenticator.

`credentials[x].credentialId`

*   String
*   required

The credential Id generated by the authenticator is stored as a base64url-encoded string. This value is used by authenticators to look up a passkey during an authentication ceremony.

`credentials[x].data`

*   Object
*   optional

An object that can hold any information about the passkey that should be persisted.

`credentials[x].discoverable`

*   Boolean
*   optional
*   Defaults to false

Indicates whether the passkey is "client-side discoverable." Discoverable passkeys can be used in authentication ceremonies without first identifying the user (e.g. by requiring the user to provide their username).

`credentials[x].displayName`

*   String
*   required

The display name for the passkey.

`credentials[x].id`

*   UUID
*   optional
*   Defaults to secure random UUID

The Id of the passkey. If not specified a secure random UUID will be generated.

`credentials[x].insertInstant`

*   Long
*   optional
*   Defaults to now

The [instant](https://fusionauth.io/docs/reference/data-types.md#instants) when the passkey was created.

`credentials[x].lastUseInstant`

*   Long
*   optional
*   Defaults to now

The [instant](https://fusionauth.io/docs/reference/data-types.md#instants) when the passkey was last used.

`credentials[x].name`

*   String
*   required

A unique name meant to disambiguate passkeys with the same **credential.displayName**.

Prior to version `1.42.0` this field was optional.

`credentials[x].publicKey`

*   String
*   required

The passkey's public key, encoded in PEM format.

`credentials[x].relyingPartyId`

*   String
*   required

The Relying Party Id used at the time the passkey was registered.

> **CAUTION:** This value **must** match the `rpId` value when the passkey was created, *and* the browser origin during WebAuthn authentication in FusionAuth must be compatible with that Relying Party Id.

`credentials[x].signCount`

*   Integer
*   optional
*   Defaults to 0

The last known signature count for the passkey.

`credentials[x].transports`

*   Array<String>
*   optional

A list of transport types supported by the authenticator that generated the passkey. This value is used as a hint during the WebAuthn authentication ceremony to help identify eligible authenticators.

FusionAuth treats the list of transports as strings to maximize authenticator compatibility. These values are used as hints during WebAuthn ceremonies and missing, extra, or unexpected values should not cause a ceremony to fail. Some common values are:

*   `internal` - the authenticator is integrated with the client device
*   `usb` - the authenticator can be contacted over USB
*   `nfc` - the authenticator can be contacted over Near Field Communication (NFC)
*   `ble` - the authenticator can be contacted over Bluetooth Smart (Bluetooth Low Energy, or BLE)
*   `cable` - "cloud-assisted" BLE. This transport is used for Android devices acting as an authenticator connected to the computer over Bluetooth
*   `hybrid` - replacement for the `cable` transport

The default value is the empty set, which means that no hints are provided. This does not negatively impact the authentication ceremony.

`credentials[x].userAgent`

*   String
*   optional

The user agent at the time the passkey was registered. This can be useful for troubleshooting WebAuthn passkey issues.

`credentials[x].userId`

*   UUID
*   required

The Id of the user to which this passkey belongs.

`validateDbConstraints`

*   Boolean
*   optional
*   Defaults to false

Set this value to `true` in order to perform additional validation of the request.

The import request is intended to be used to migrate existing users' passkeys from one system to another, this means FusionAuth expects all user Ids from the request to exist for the provided tenant. If a non-existent user Id is encountered a `500` will be returned unless this field is set to `true`.

In order to get additional details about database constraint violations on import, set this value to `true` and a `400` response will be returned with a JSON body indicating the missing values encountered.

Setting this value to `true` will dramatically decrease the performance of this request. If importing large numbers of passkeys in a single request you may need to increase request timeouts to ensure this request does not timeout before it has completed.

*Example Request JSON*

```json
{
  "credentials": [
    {
      "algorithm": -7,
      "credentialId": "vBD52q2FMMM-zxaO-ZMgrN3ewjbmb0ra5E-QCX_3kz0",
      "displayName": "YubiKey",
      "name": "richard@fusionauth.io",
      "publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEz9DI9AQfZn1aDJG5sw3Ckl7SoQ7E\nLPElDoJMijphvVigTcNMTc8H9Xptl8B20QHMOXGTzaUxLGNY1c8yhw9VVA==\n-----END PUBLIC KEY-----",
      "relyingPartyId": "piedpiper.com",
      "userId": "703fe2d2-2d39-4cb7-b76d-0b9918ed2457"
    },
    {
      "algorithm": -7,
      "attestationType": "none",
      "authenticatorSupportsUserVerification": true,
      "credentialId": "HdN9wqP9mqOonacmiM2gIjASFYg",
      "data": {},
      "displayName": "Chrome Touch ID",
      "name": "richard@fusionauth.io",
      "id": "c664318a-2384-4c35-9475-9a200e1d3b72",
      "insertInstant": 1668011701792,
      "discoverable": false,
      "lastUseInstant": 1668021630599,
      "publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEz9DI9AQfZn1aDJG5sw3Ckl7SoQ7E\nLPElDoJMijphvVigTcNMTc8H9Xptl8B20QHMOXGTzaUxLGNY1c8yhw9VVA==\n-----END PUBLIC KEY-----",
      "relyingPartyId": "piedpiper.com",
      "signCount": 41,
      "transports": [
        "internal"
      ],
      "userId": "703fe2d2-2d39-4cb7-b76d-0b9918ed2457"
    }
  ]
}
```

## Response

Only a status code is available on the Import API, no JSON body will be returned.

*Response Codes*

| Code | Description |
| --- | --- |
| 200 | The request was successful. The response will contain a JSON body. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](https://fusionauth.io/docs/apis/errors.md) JSON Object with the specific errors. This status will also be returned if a paid FusionAuth license is required and is not present. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](https://fusionauth.io/docs/apis/authentication.md). |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
---

## Other pages in Webauthn

> For the full index of this section, see [Apis](https://fusionauth.io/docs/llms-apis.txt).

- [Complete a WebAuthn Passkey Assertion API](https://fusionauth.io/docs/apis/webauthn/complete-a-webauthn-passkey-assertion.md): API documentation for the FusionAuth Complete a WebAuthn Passkey Assertion API.
- [Complete a WebAuthn Passkey Authentication API](https://fusionauth.io/docs/apis/webauthn/complete-a-webauthn-passkey-authentication.md): API documentation for the FusionAuth Complete a WebAuthn Passkey Authentication API.
- [Complete a WebAuthn Passkey Registration API](https://fusionauth.io/docs/apis/webauthn/complete-a-webauthn-passkey-registration.md): API documentation for the FusionAuth Complete a WebAuthn Passkey Registration API.
- [Delete a Passkey API](https://fusionauth.io/docs/apis/webauthn/delete-a-passkey.md): API documentation for the FusionAuth Delete a Passkey API.
- [WebAuthn API](https://fusionauth.io/docs/apis/webauthn.md): Learn about the APIs for starting and completing WebAuthn ceremonies and retrieving, importing and deleting WebAuthn passkeys.
- [Retrieve a Passkey API](https://fusionauth.io/docs/apis/webauthn/retrieve-a-passkey.md): API documentation for the FusionAuth Retrieve a Passkey API.
- [Start a WebAuthn Passkey Assertion or Authentication API](https://fusionauth.io/docs/apis/webauthn/start-a-webauthn-passkey-assertion-or-authentication.md): API documentation for the FusionAuth Start a WebAuthn Passkey Assertion or Authentication API.
- [Start a WebAuthn Passkey Registration API](https://fusionauth.io/docs/apis/webauthn/start-a-webauthn-passkey-registration.md): API documentation for the FusionAuth Start a WebAuthn Passkey Registration API.
