To enable multi-factor authentication (MFA), the user resource must have an MFA method associated with its user ID. PingOne supports email, SMS, voice, TOTP authenticator application, and native application method types for use in an MFA flow. Multiple MFA methods can be associated with a user ID. MFA methods must be in the active state to be used in the multi-factor login flow.

With this API, MFA methods are called MFA devices. The devices endpoints provide operations to manage device resources associated with a specified user ID. You need the Identity Data Admin role to perform operations on device resources.

Device order

With the release of the device order feature (Jan 11, 2021), the active devices of most users now have an order (first…last). By default, the order is according to the device activation time (oldest…newest). Each subsequently activated device is appended to the end of the order list. The first device on the list is designated the default device. In most cases, the default device is automatically used for authentication; users no longer need to select a device.

There are a small number of users whose devices do not have a default order with this feature. If a user has more than one active device as of the release of the device order feature, the current active devices and subsequently activated devices have no order. The user therefore has no default device and must choose a device each time they authenticate. In this case, the order must be explicitly set (see Setting device order).

Cases where the default device is not used for authentication

In most cases, the default device is automatically used for authentication. However, there are two exceptions:

Setting device order

The operation POST /environments/{{envID}}/users/{{userID}}/devices with required header Content-type: application/vnd.pingidentity.devices.reorder+json explicitly orders a user’s existing active devices according to the request body. The active device listed first becomes the default device.

After this operation explicitly sets device order, subsequently activated devices are appended to the end of the order list. You can use this operation to explicitly reorder active devices as many times as needed.

Retrieving an ordered list of devices

The operation GET /environments/{{envID}}/users/{{userID}}/devices returns the list of active devices sorted in their order, with the default device listed first. Devices with a status of ACTIVATION_REQUIRED are listed after the active devices, in no particular order. If devices have no order, GET /environments/{{envID}}/users/{{userID}}/devices returns the list of devices in no particular order.

You can expand the GET /environments/{{envID}}/users/{{userID}}/devices results with the expand=order query parameter. The response is then expanded to contain an array of activated device IDs listed according to device order. If devices have no order, an empty array is returned.

Deleting a default device

If the default (first) device is deleted, the second active device on the order list becomes the default device.

Removing device order

The operation POST /environments/{{envID}}/users/{{userID}}/devices with required header Content-type: application/vnd.pingidentity.devices.order.remove+json removes the ordering on a user’s active devices. With the execution of this operation, the user no longer has a default device.

Custom device pairing notification with device creation

To send a custom device pairing notification when a new email, SMS or voice device is created, add the notification property to the request body of POST /environments/{{envID}}/users/{{userID}}/devices. The status of the created device must be ACTIVATION_REQUIRED.

{
    “notification”: {
        “template”: {
            “locale”: “en”,
            “variant”: “variant_B”
            "variables": {
                        "sum": "1,000,000",
                        "currency": "USD",
                        "recipient": "Charlie Parker"
            }
       }
    }
}

When the device is created, a request is executed to select the content for the notification. The notification template is device_pairing. The deliveryMethod is Email, SMS or Voice, depending on the device created. The locale, variant, and all dynamic variables are defined in notification.

For more information on content selection, see Runtime logic for content selection. For more information on dynamic varables, see Dynamic variables.

Device failure in flows

When the flow returns a NO_USABLE_DEVICES error, and the user has devices that are temporarily unavailable (for example, the device is locked because of too many invalid OTP retries), the IDs of these devices are returned as part of the response.

In the flow response, the status property returns FAILED, and the error message includes the NO_USABLE_DEVICES error code. The following samples show common error messages for a device failure with identified unavailableDevices:

"status": "FAILED",
    "error": {
        "code": "NO_USABLE_DEVICES",
        "message": "Couldn't find authenticating device for user: {{userID}}",
      "unavailableDevices": [
            {
                "id": "edccc773-6f31-4d28-a8e1-0f427d9a9df8"
            }
        ]
    },
"status": "FAILED",
    "error": {
        "code": "NO_USABLE_DEVICES",
        "message": "Daily limit of SMS authentication attempts has been exceeded",
        "unavailableDevices": [
            {
                "id": "7ea99e29-6f8f-42be-af75-232588235e30"
            }
        ]
    },

Device properties {#device-properties}

Property Type Required? Mutable? Description
block.status String Optional Read-only Whether the device is currently blocked. The possible values are BLOCKED and UNBLOCKED.
block.blockedAt Date Optional Read-only The date and time that the device was blocked.
createdAt Date N/A Read-only The date the device was created.
environment.id String N/A Read-only The environment ID associated with the device resource.
id String N/A Read-only The device resource’s unique identifier.
lock.status String N/A Read-only Indication of whether the device is currently locked out due to too many failed attempts. Values are LOCKED, UNLOCKED.
lock.expiresAt Date N/A Read-only For devices that are currently locked out, the date and time when the lock will expire.
lock.reason String N/A Read-only For devices that are currently locked out, provides the reason for the lock. Values are OTP or PUSH. OTP means that the user passed the defined limit on the number of unsuccessful OTP tries. PUSH means that the user passed the limit on the number of push notifications that can be declined or ignored within the defined time period.
nickname String Optional Mutable Identifies the authentication method in the UI. If defined, this string also appears on the authentication screens. This property has a limit of 100 characters. All characters are supported. An empty string is also supported to delete the value. Use Update Device Nickname to set this property.
notification.policy.id String Optional Mutable The policy ID for the notification.
policy.id String Optional Mutable The device authentication policy ID associated with the device resource. Specifying a device authentication policy ID applies that policy on the API, which determines the MFA methods and mobile applications that are allowed. This property is not returned with GET operations and cannot be used with PUT operations. Currently, if a policy ID is not specified on the request, the environment policy is used. However, this behavior is temporary; it is highly recommended that you specify a policy ID in the POST operation request body.
status String Required Mutable The device status. Options:
  • ACTIVE
  • ACTIVATION_REQUIRED
type String Required Mutable The device type which must be provided. Options:
  • EMAIL
  • MOBILE
  • SMS
  • VOICE
  • TOTP (third-party TOTP authenticator applications)
  • FIDO2
  • PLATFORM - FIDO2 bound biometrics devices (deprecated, use FIDO2 instead)
  • SECURITY_KEY - FIDO2 or U2F security key devices (deprecated, use FIDO2 instead)
updatedAt Date N/A Read-only The date the device was last updated.
user.id String Optional Mutable The ID of the user associated with the device.

EMAIL device properties

Devices whose type is EMAIL also have the following properties:

Property Type Required? Mutable? Description
email String Required Immutable The email address, which is required during POST only if the device type is EMAIL. The email address must be valid.
notification String Optional Immutable Contains notification information. When this property is supplied during device creation, the information within is used to create a custom device pairing notification. For more information, see Custom device pairing notification with device creation.
notification.template String Optional Immutable An object that contains template parameters.
notification.template.locale String N/A Read-only The ISO language code (string) used for the device created notification. For example, en.
notification.template.variant String N/A Read-only The unique user-defined name for the content variant that contains the message text used for the notification. For more information on variants, see Creating custom contents.
notification.template.variables Map[String, String] Optional Read-only An object of name-value pairs that defines the dynamic variables used by the content variant. For more information on dynamic variables, see Dynamic variables.
testMode Boolean Optional Mutable To simplify automated testing of your applications, you can create dedicated testing devices. When you use the API to send authentication requests to such a device, the OTP is not sent to the actual device, but instead is returned as part of the body of the response. To specify that a device should serve as a testing device, set the value of testMode to true. If this parameter is not provided, the default value is false. For dedicated testing devices, the response to authentication requests includes the OTP value in the field test.otp.
test.otp Integer Optional Read-only If you use the testMode parameter to create a dedicated testing device, and status is set to ACTIVATION_REQUIRED in the request, the response will include test.otp, which is the passcode that you should use to activate the device.

SMS/Voice device properties

Devices whose type is SMS or VOICE also have the following properties:

Property Type Required? Mutable? Description
phone String Required Immutable The phone number, which is required only if the device type is SMS or VOICE. It must be a well-formed phone number consisting of a leading plus sign, 1 to 3-digit country code, and 4 to 14-digit phone number (e.g. +11235557890).
extension String Optional Immutable When creating a device of type VOICE, use extension for phone numbers that also have an extension. Can include digits, commas, #, and *. For nested extensions, separate the parts with a comma.
notification String Optional Immutable Contains notification information. When this property is supplied during device creation, the information within is used to create a custom device pairing notification. For more information, see Custom device pairing notification with device creation.
notification.template String Optional Immutable Contains template parameters.
notification.template.locale String Optional Read-only The ISO language code used for the device created notification. For example, en.
notification.template.variant String Optional Read-only The unique user-defined name for the content variant that contains the message text used for the notification. For more information on variants, see Creating custom contents.
notification.template.variables Map[String, String] Optional Read-only An object of name-value pairs that defines the dynamic variables used by the content variant. For more information on dynamic variables, see Dynamic variables.
testMode Boolean Optional Mutable To simplify automated testing of your applications, you can create dedicated testing devices. When you use the API to send authentication requests to such a device, the OTP is not sent to the actual device, but instead is returned as part of the body of the response. To specify that a device should serve as a testing device, set the value of testMode to true. If this parameter is not provided, the default value is false. For dedicated testing devices, the response to authentication requests includes the OTP value in the field test.otp.
test.otp Integer N/A Read-only If you use the testMode parameter to create a dedicated testing device, and status is set to ACTIVATION_REQUIRED in the request, the response will include test.otp, which is the passcode that you should use to activate the device.

Native device properties

Devices whose type is MOBILE also have the following properties:

Property Type Required? Mutable? Description
apiVersion String Required Mutable The native SDK API version.
application.id String Required Immutable The ID of the native application associated with this device.
application.nativeName String Optional Mutable The name of the application retrieved from the native app in runtime.
application.pushSandbox Boolean Optional Immutable Indicates if the native application uses production or sandbox push credentials (if the app was built and installed by a developer from Xcode, or installed ad hoc). Only relevant on iOS devices.
application.version String Optional Mutable The version of the application retrieved from the native app in runtime.
deviceIntegrityState.advice String N/A Read-only If available, Google advice for the deviceIntegrityState.reason.
deviceIntegrityState.compromised String N/A Read-only Indicates if the device’s integrity is compromised:
  • TRUE
  • FALSE
  • UNKNOWN
deviceIntegrityState.reason String N/A Read-only Indicates the cause of the device’s current integrity state:
  • JAILBROKEN
  • BASIC_INTEGRITY
  • CTS
  • DATA_UNAVAILABLE
  • SAFETYNET_UNAVAILABLE
  • SAFETYNET_ERROR
  • SAFETYNET_VALIDATION_ERROR
  • DATA_EXPIRED
  • INTERNAL_ERROR
  • INVALID_CERTIFICATE_DIGEST
  • INVALID_PACKAGE_NAME
deviceIntegrityState.timestamp Date N/A Read-only The date and time (UTC) of the latest integrity check for the device.
integrityStateCurrent String N/A Read-only Used for internal PingOne purposes.
locale String Optional Mutable The device’s locale.
lockEnabled Boolean Optional Mutable Whether the device is lock enabled.
logs.expiresAt Date N/A Read-only The date and time the request for expires, if the logs have not been sent yet. The value is set at 24 hours from the time of the request, and remains only while the logs.status is PENDING. logs.expiresAt is reset when the logs are sent, or when the system date reaches the request’s expiry time.
logs.level String Optional Mutable The level of log detail. Values:
  • VERBOSE
  • DEBUG
  • INFO (default)
  • WARN
  • ERROR
logs.status String Optional Mutable The returned status of a request for logs from a particular user device. Possible values:
  • PENDING: The request for logs was issued. When the user connects to the app, it will send the logs.
  • RECEIVED: The logs were sent from the device, and received.
manufacturer String N/A Read-only The manufacturer of the device.
model.marketingName String Required Read-only The model’s marketing name.
model.name String Required Read-only The device’s model name.
name String N/A Read-only The device name given by the manufacturer.
notificationProvider String N/A Read-only The messaging system used for push notifications. For the possible values, see the type property in the MFA push credentials data model.
os.type String Required Read-only The device’s operating system.
os.version String Required Mutable The device’s operating system version.
otpEnabled Boolean N/A Read-only Whether OTP authentication is enabled for the device.
pushEnabled Boolean N/A Read-only Whether push is enabled for the device.
pushToken String Optional Mutable The push token for this application on this device (for internal use).
rooted (Deprecated) Boolean Required Mutable Use deviceIntegrityState instead.
sdkVersion String N/A Read-only The version of the MFA Mobile SDK used.

Time-based One-time Password (TOTP) authenticator application device properties {#totp-model}

Devices whose type is TOTP also have the following properties:

Property Type Required? Mutable? Description
secret String N/A Read-only The unique secret key shared by the prover (token) and the verifier (authentication server). Only returned if the device’s activation status is ACTIVATION_REQUIRED. Both the secret and the keyURI values expire after 30 minutes.
keyUri String N/A Read-only The authenticator key URI (for example, otpauth://totp/abc@example.com?secret={secretValue}. Both the secret and the keyURI values expire after 30 minutes.

FIDO2 devices {#fido2-devices}

Devices whose type is FIDO2 also have the following properties:

Property Type Required? Mutable? Description
attestation String N/A Read-only Specifies the public key and signed challenge used to complete registration and device activation. Devices with a status of ACTIVATION_REQUIRED are activated using a valid attestation and origin. The attestation is generated by the browser as a response to a specific user action, such as a fingerprint or clicks on the security key. This is a required property for FIDO2 device activation.
attributes Object N/A Read-only Object returned in the response for FIDO2 devices.
attributes.isCrossPlatform Boolean N/A Read-only Value is true if the device has ever been cross-platform.
attributes.previousDeviceType String N/A Read-only Included in the response for devices that were converted to FIDO2 from one of the deprecated device types. Value can be SECURITY_KEY or PLATFORM.
backup Object N/A Read-only Included in the response, contains the information regarding the backup eligibility of the device.
backup.backupEligibility Boolean N/A Read-only Whether the public key credential source is allowed to be backed up.
backup.backupState Boolean N/A Read-only Whether the public key credential source is currently backed up.
displayName String N/A Read-only The name displayed for the device in self-service registration and authentication windows. The name is taken from the relevant FIDO2 policy. Returned in the response only for request to read all FIDO2 devices.
origin String Required Read-only The originating server (for example, https://apps.pingone.com). This property and the attestation property are used to activate FIDO2 devices that have a status of ACTIVATION_REQUIRED. This is a required property for FIDO2 device activation.
publicKeyCredentialCreationOptions String N/A Read-only A JSON serialization of the client data returned for registering a FIDO2 device with the webauthn navigator.credentials.create API.
rp Object Optional Immutable Information on the relying party. If not provided, the relying party ID is taken from the associated FIDO2 policy.
rp.id String Optional Immutable The ID of the relying party. The value should be a domain name, such as example.com (in lower-case characters).
rp.name String Optional Immutable The relying party’s human-readable display name (for example, acme).

PLATFORM and SECURITY_KEY webauthn device data model (deprecated, replaced by FIDO2 devices)

Devices whose type is PLATFORM or SECURITY_KEY also have the following properties:

Property Type Required? Mutable? Description
platform String N/A Read-only The type of platform associated with this MFA device. Options are BIOMETRICS, WINDOWS, ANDROID, MAC, and IPHONE. This property applies only to devices in which the type property is set to PLATFORM. The type of platform is based on the User-Agent HTTP header of the request. If it is not possible to identify the platform, the value defaults to BIOMETRICS.
publicKeyCredentialCreationOptions String N/A Read-only A JSON serialization of the client data returned for registering a FIDO2 device with the webauthn navigator.credentials.create API.
rp.id String Required Immutable The relying party identifier, which is based on a host’s domain name but without a scheme or port (for example, acme.com or login.acme.com).
rp.name String Required Immutable The relying party’s human-readable display name (for example, acme).

Device order properties

Property Type Required? Mutable? Description
order String[] Required Mutable An array of objects that determines the explicit order of a user’s devices. The first device listed becomes the default device. This property is used as a body parameter to set the order of existing devices.

Audit reporting events

To see the effects of these events for an API call, see the event types in the Audit Report, Audit Activities API, or Webhook stream.

Service Event
users DEVICE.CREATED
users DEVICE.UPDATED
users DEVICE.DELETED
users DEVICE.LOGS_RECEIVED
users DEVICE.REORDERED
users DEVICE.ACTIVATION_OTP_INVALID
users DEVICE.ACTIVATION_OTP_FAILED

Response codes

Code Message
200 Successful operation.
400 The request was invalid.
400 The request could not be completed.
401 You do not have access to this resource.
403 You do not have permissions or are not licensed to make this request.
404 The requested resource was not found.
500 Unexpected server error.

Filtering result data

You can filter GET /environments/{{envID}}/users/{{userID}}/devices results by applying a SCIM filtering expression to the request URL. For large collections, a filtering expression appended to the query returns a targeted, more useful data set.

SCIM operators can be applied to the following attributes:

Collection Attribute Supported operators Valid values
Devices mobilePayload eq (equals) The signed JWT payload from the PingOne Mobile SDK. The payload contains information about a specific device, so the collection returned will always contain just a single device.
Devices status eq (equals) “ACTIVE”, “ACTIVATION_REQUIRED”
Devices type eq (equals) “SMS”, “VOICE”, “EMAIL”, “TOTP”, “MOBILE”, “PLATFORM”, “SECURITY_KEY”

The logical operators and and or can also be used to combine filter statements.

For example, the following URL-encoded SCIM filter returns a list of SMS devices that require activation:

{{apiPath}}/environments/{{envID}}/users/{{userID}}/devices?filter=(status%20eq%20%22ACTIVATION_REQUIRED%22)%20and%20(type%20eq%20%22SMS%22)

This URL returns the device that matches the information contained in the specified payload from the PingOne Mobile SDK:

{{apiPath}}/environments/{{envID}}/users/{{userID}}/devices?filter=mobilePayload eq "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImRlNjJjZWYxLWQzNmQtNGMxMC05NDBkLTczNzQzZDk5NmYxZiJ9.eyJpc3MiOiIyNjdmNmEwMC1iZjg2LTQ4ODUtYjRjMi1mYjg5YzUzNzVlNGYiLCJmbnAiOiJiMDY4YjI2YTNhZTI2MTRmIiwiZHZjIjoiZGU2MmNlZjEtZDM2ZC00YzEwLTk0MGQtNzM3NDNkOTk2ZjFmIiwiZXhwIjoxNjg3OTQ4MTY1NTkwLCJqdGkiOiI1M2FlMmQ5YS04NmZiLTRmNGQtYjFlYS04M2MzMDQwNWU2OWEifQ.LxPIyD1mmdkXRLUmt2z3Fjeryev9b5oPgJGR2M5QxcuRR-tnd9nKNVB37CyS0W5Hj926W2U-MoSgpldvPM6-anpM4w4Ywa0a65_FB7PA0tzv-5LI4Pduat5fxhG78PTVRLXF_bwMe1hopUEFu6MBcKj13LIjz-rcrHIMoQV3OWUH5caX4mV3FXx1FPxoB-3Ighcc0-SotO4JZXvpZk2vsD-P2XJ1lFf-N2QhXnwfmBy7WthuPDCU8Rc6_a0Ca2cnv1bWDAKUKkndEsqm6S0_VFpLueCVxmHKdSy98owh86SAVhGtoZeHfOTB7WEbOb9aCAH_AinEh-JEhLKn_hMO3w"

Expanding result data

You can expand GET /environments/{{envID}}/users/{{userID}}/devices results with the expand=<value> query parameter. The following value is supported.

Value Description
order The response is expanded to contain an array of activated device IDs listed according to device order. This value is relevant only if the devices are ordered. If devices are not ordered, and empty array is returned. For more information, see Setting device order.