PingOne Platform APIs

MFA Device Authentications

The /deviceAuthentications endpoint initiates and completes an MFA action without requiring a call to the PingOne authorize service. It supports actions to select a supported MFA device device type and to validate a one-time passcode (OTP).

When a device authentication MFA flow is initiated, the flow returns a status property in the response that identifies the next action in the flow. The following flow states prompt for a specific flow action:

  • OTP_REQUIRED

    For a status value of OTP_REQUIRED, the otp.check action validates the one-time passcode.

  • DEVICE_SELECTION_REQUIRED

    For a status value of DEVICE_SELECTION_REQUIRED, the device.select action prompts the user to select a supported device type for use in a multi-factor authentication flow.

  • ASSERTION_REQUIRED

    For a status value of ASSERTION_REQUIRED, the assertion.check action validates the assertion.

  • PUSH_CONFIRMATION_REQUIRED

    For a status value of PUSH_CONFIRMATION_REQUIRED, a push was sent to the specified mobile device to confirm the authentication.

  • PUSH_CONFIRMATION_TIMED_OUT

    For a status value of PUSH_CONFIRMATION_TIMED_OUT, a push was sent to the specified mobile device, but the mobile device did not answer the push during the allowed timeframe.

Device authentication with PingID Desktop

Authentication using PingID Desktop involves a sequence of requests and responses, including interaction with the Desktop API:

  1. Send an Initiate Device Authentication request to the deviceAuthentications endpoint, providing the ID of the user or the relying party ID.

  2. The response form the PingOne server contains a field called pingIdDesktopCredentialRequestOptions, which consists of a signed JWT.

  3. Send a request to the Desktop API endpoint http://localhost:9410/authenticate. The body should consist of the JWT that was received from the PingOne server.

  4. The response from the desktop agent will contain an assertion JWT.

  5. Send a Check Assertion request to the deviceAuthentications endpoint, using the relevant header. The body of the request should consist of a field called assertion, whose value should be the JWT that was returned from the desktop agent.

  6. The PingOne server returns a success response.

Device authentications data model

Property Type Required Mutable Description

aggregateFido2Devices

Boolean

N/A

Read-only

Indication of whether the available authentication method list should include only a single generic FIDO2 option rather than including an entry for each paired FIDO2 device. The field is included in the response to the request to initiate an MFA device authentication flow (POST {{authPath}}/{{envID}}/deviceAuthentications).

application.id

String

Optional

Mutable

The requesting application’s unique identifier. This identifier is required only during device authorization flows when the mobilePayload value is provided.

assertion

String

Required

Immutable

During the process of authenticating using the PingID Desktop application, you must send a request to the Desktop API’s authenticate endpoint. The response from the desktop agent contains an assertion JWT. You must then send a request to the PingOne deviceAuthentications endpoint, with the body of the request consisting of the assertion field whose value should be the JWT that was returned from the desktop agent.

createdAt

Date

N/A

Immutable

When the resource was created.

enrollment

Object

N/A

Read-only

Included in the response to a device authentication initialization request when the Auto Enrollment option is enabled in the relevant MFA policy and the request contains the parameters required for auto-enrollment, application.id and mobilePayload.

enrollment.pairingKey

String

N/A

Read-only

The pairing key that the end user should use to pair their device.

enrollment.pairingKeyId

String

N/A

Read-only

The ID of the pairing key resource.

enrollment.status

String

N/A

Read-only

Indication of whether the pairing key was generated and returned successfully. Value returned will be SUCCESS or FAILED.

error

Object

N/A

Read-only

The error field indicating the reason for a device authentication failure.

error.code

String

N/A

Read-only

The error code.

error.message

String

N/A

Read-only

The error message.

id

String

N/A

Read-only

The resource’s unique identifier.

mobilePayload

String

N/A

Read-only

The JSON that is the result of a getMobilePayload call (mobile app to mobile SDK). Both mobilePayload and applicationId values are required to invoke the device authorization flow using the API.

notification

Object

Optional

Immutable

Holds dynamic notification data.

notification.clientContext

Object

Optional

Immutable

Holds dynamic mobile push data.

notification.policy.id

String

Optional

Mutable

The policy ID for the notification.

notification.template

Object

Optional

Immutable

Holds dynamic template data.

notification.template.name

String

Optional

Immutable

The notification template name.

notification.template.variant

String

Optional

Immutable

The notification template variant.

notification.template.locale

String

Optional

Immutable

The notification template locale.

notification.template.variables

Map

Optional

Immutable

The notification template variables.

origin

String

Required

Immutable

For authentication with the PingID Desktop application, when you make the second call to the PingOne server and include the assertion that was provided by the desktop agent, you must also include origin in the body of the request. The value should be a subdomain of the domain that was specified as the Relying Party ID in the MFA policy or the domain that was specified with rp.id in the initial call to the PingOne server. The format used should be a complete URL, for example, https://app.pingone.eu.

pingIdDesktopCredentialRequestOptions

String

N/A

Read-only

During the process of authenticating with the PingID Desktop application, you initiate the process by sending a request to the PingOne deviceAuthentications endpoint. The response to the request contains a field called pingIdDesktopCredentialRequestOptions, which consists of a signed JWT. You then include the returned JWT in the subsequent request to the Desktop API’s authenticate endpoint.

policy.id

String

Optional

Mutable

The device authentication policy ID.

publicKeyCredentialRequestOptions

String

N/A

Read-only

A string that specifies the public key credential request options object generated for the selected device that should be used to call the navigator.credentials.get() on the browser to generate the assertion. If you are using dynamic linking to attach a unique identifier to a FIDO transaction, publicKeyCredentialRequestOptions will include the transaction information for your records.

reason

String

Optional

Mutable

In situations where the user wants to authenticate from a different device, you can cancel an authentication flow that has begun. For such requests, the body consists of a single field, reason, and the value should be set to CHANGE_DEVICE. For details, refer to the Cancel Device Authentication example.

rp.id

String

Optional

Mutable

The ID of the relying party, used for logging in without having to provide a username. The value of the field should be a domain name, such as example.com. If not provided, the relying party ID is taken from the associated FIDO2 policy. For authentication with the PingID Desktop application, the relying party ID is taken by default from the relevant MFA policy. However, you have the option of including rp.id in the body of the initial call to the PingOne server if you would like to override the value from the MfA policy with a different domain.

selectedDevice.id

String

Optional

Mutable

The unique identifier of a user’s MFA device. You can use this property to specify that authentication should be carried out with a specific device if the user has more than one. In responses, the value is the ID of the device that was in fact used for authentication.

selectedDevice.oneTime.type

String

Optional

Mutable

For organizations that prefer to maintain their own user device information, you can use the oneTime object to specify how the user should be contacted. The type property indicates the method that should be used for contacting the user. The value can be SMS, VOICE, or EMAIL. If you are using the oneTime object, you should not include the selectedDevice.id property.

selectedDevice.oneTime.phone

String

Optional

Mutable

If selectedDevice.oneTime.type is set to SMS or VOICE, use the phone property to provide the user’s phone number.

selectedDevice.oneTime.email

String

Optional

Mutable

If selectedDevice.oneTime.type is set to EMAIL, use the email property to provide the user’s email address.

selectedDevice.oneTime.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 one-time 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 includes the OTP value in the field test.otp. Note that the test.otp field is included in the response for authentication requests only when using the API directly or via DaVinci. The field is not included in the API response that is sent to the PingOne user interface.

selectedDevice.otp

String

Optional

Mutable

Enables the user to enter their OTP when triggering MFA.

status

String

N/A

Read-only

The flow status. Options are DEVICE_SELECTION_REQUIRED, PUSH_CONFIRMATION_REQUIRED, PUSH_CONFIRMATION_TIMED_OUT, OTP_REQUIRED, ASSERTION_REQUIRED, COMPLETED, and FAILED.

test.otp

String

N/A

Read-only

If you are using a test device or you used the testMode parameter to specify that a one-time device should serve as a testing device, the response includes the OTP value in the field test.otp. Note that the test.otp field is included in the response for authentication requests only when using the API directly or via DaVinci. The field is not included in the API response that is sent to the PingOne user interface.

updatedAt

Date

N/A

Immutable

When the resource was last updated.

user.id

String

Required

Mutable

The requesting user’s unique identifier.

webAuthn.challenge

String

Optional

Immutable

If you want to use dynamic linking to attach a unique identifier to a FIDO transaction, provide a value for the webAuthn.challenge parameter. The value should be a custom challenge to replace the automatically-generated challenge sent with the authentication request. Must be a valid and unique Base64URL string that decodes to a data array of at least 32 bytes. You can generate a challenge that meets these criteria by adding a random nonce to the transaction details to ensure uniqueness and then using SHA-256 to hash the information.

_embedded.devices

Array

N/A

Read-only

The list of authenticating devices.

_embedded.devices[].otpStatus.status

String

N/A

Read-only

Whether or not the device can be used currently for OTP-based authentication. Value returned is ENABLED or DISABLED. Relevant only for devices where type is MOBILE.

_embedded.devices[].otpStatus.reason

String

N/A

Read-only

If the status is DISABLED, contains the reason that the device cannot be used for OTP-based authentication, for example, that the application used a version of the MFA SDK that does not support OTP. Relevant only for devices where type is MOBILE.

_embedded.devices[].pushStatus.status

String

N/A

Read-only

Whether or not the device can be used currently for push-based authentication. Value returned is ENABLED or DISABLED. Relevant only for devices where type is MOBILE.

_embedded.devices[].pushStatus.reason

String

N/A

Read-only

If the status is DISABLED, contains the reason that the device cannot be used for push-based authentication, for example, that the push option was disabled for the application in the MFA policy. Relevant only for devices where type is MOBILE.

_embedded.devices[].usableStatus.status

String

N/A

Read-only

Whether or not the device can be used currently for authentication. Value returned is ENABLED or DISABLED.

_embedded.devices[].usableStatus.reason

String

N/A

Read-only

If the status is DISABLED, contains the reason that the device cannot be used for authentication, for example, that the defined daily notifications limit has already been reached.

Device authentication events generated

Refer to Audit Reporting Events for the events generated.

Device authentications errors

In addition to the general error codes, deviceAuthentications operations can return the following errors:

HTTP status Top‑level code Detail code When it happens and what the response contains

400

INVALID_DATA

EMPTY_VALUE or INVALID_VALUE

Message: Validation Error : [<property> <message>]

When and details

When: An initialize request omits user.id, supplies a malformed or missing rp.id, or omits required selectedDevice.oneTime values, or a check request omits payload

Details: must have an id for an omitted rp.id (detail INVALID_VALUE), must be a valid domain name with a valid TLD for a malformed rp.id (detail INVALID_VALUE), must not be null for an omitted user or payload (detail EMPTY_VALUE), must not be blank for an omitted selectedDevice.oneTime.phone or selectedDevice.oneTime.email (detail EMPTY_VALUE), or invalid value for an unrecognized payload.type (detail INVALID_VALUE), for example Validation Error : [rp must be a valid domain name with a valid TLD]

400

INVALID_DATA

INVALID_VALUE

Message: The request could not be completed. One or more validation errors were in the request.

When and details

When: An otp.check request supplies a passcode that does not match the passcode sent to the device

Details: Wrong OTP was provided (detail code INVALID_OTP) with target otp and an attemptsRemaining inner error

400

INVALID_DATA

INVALID_VALUE

Message: One or more issues were found in the request data.

When and details

When: An otp.check request runs after the OTP session expired

Details: The provided OTP was expired with target otp

400

INVALID_DATA

INVALID_VALUE

Message: The request could not be completed. One or more validation errors were in the request.

When and details

When: An otp.check, device.select, or assertion.check request runs against a flow whose status does not match the requested action, or a device authentication action targets a user-selected device that is not part of the flow

Details: Expected status to be <expected> but it was <actual> with target status and expected and actual inner errors, or Invalid device was selected. with target device and an allowedValues inner error listing the selectable device IDs

400

INVALID_DATA

EXTRA_OTP_REQUIRED or RESYNC_OATH_OTP

Message: The request could not be completed. One or more validation errors were in the request.

When and details

When: An otp.check request for an OATH token device requires an additional passcode to complete the resync, or the resync passcode window was missed

Details: An extra OTP is required (detail code EXTRA_OTP_REQUIRED) with target otp, or To resync this token, wait for the next passcode on your device and enter it. (detail code RESYNC_OATH_OTP) with target otp and an attemptsRemaining inner error

400

REQUEST_FAILED

CONSTRAINT_VIOLATION

Message: The request violates a constraint imposed by the service.

When and details

When: An otp.check request is made after the configured number of unsuccessful OTP attempts, or an assertion.check request after the configured number of unsuccessful assertion attempts

Details: Too many unsuccessful OTP attempts (detail code QUOTA_EXCEEDED) with target otp, or Too many unsuccessful assertion validations attempts (detail code QUOTA_EXCEEDED) with target fido2. The message is suffixed with , please try again in a few minutes when a cool-down applies, and both include a quotaLimit inner error and, when a cool-down applies, a coolDownExpiresAt inner error.

400

REQUEST_FAILED

CONSTRAINT_VIOLATION

Message: The request violates a constraint imposed by the service.

When and details

When: A device authentication action runs in the context of a policy evaluation whose action does not allow device authentication

Details: Device Authentication is forbidden for Policy Evaluation Action: '<action>' (detail code INVALID_POLICY_ACTION) with target policyId

400

REQUEST_FAILED

CONSTRAINT_VIOLATION

Message: The request violates a constraint imposed by the service.

When and details

When: An assertion check or device selection request runs against a device authorization session that is in an invalid state

Details: Invalid state during device authorization flow with target status

400

REQUEST_FAILED

None

Message: The request could not be completed. There was an issue processing the request.

When and details

When: A device selection or OTP check request selects a device that is blocked, the user has no usable authentication devices, the user is disabled, suspended, or mid-update, MFA is disabled for the user, or the authentication is canceled or denied

Details: Selected device is blocked (detail code DEVICE_BLOCKED) with target device and an allowedValues inner error, Couldn’t find authenticating device for user: <userId> (detail code NO_USABLE_DEVICES) with allowedMethods, deviceAuthenticationPolicy, and unusableDevices inner errors when applicable, The user is disabled (detail code ACCOUNT_NOT_USABLE) with target user, User suspended (detail code USER_SUSPENDED) with target user, User in process (detail code USER_IN_PROCESS) with target user, MFA is disabled for user: <userId> (detail code MFA_DISABLED), or Authentication Canceled (detail code AUTHENTICATION_CANCELED)

400

REQUEST_FAILED

LIMIT_EXCEEDED

Message: The request could not be completed. There was an issue processing the request.

When and details

When: A device selection or OTP check request for an SMS, Voice, Email, or WhatsApp device exceeds the notifications policy cooldown or resend limit

Details: Temporarily locked or Too many notifications have been sent with coolDownExpiresAt, deliveryMethod, and resendLimit inner errors

403

ACCESS_FAILED

INSUFFICIENT_PERMISSIONS

Message: You do not have permissions or are not licensed to make this request.

When and details

When: The actor lacks the mfa:authenticate:device permission, sends the x-skip-bypass header without a platform-level token, or uses a test-mode one-time device without the mfa:create:createTestDevice permission

Details: You do not have permissions or are not licensed to make this request.

404

NOT_FOUND

None

Message: The request could not be completed. The requested resource was not found.

When and details

When: A device authentication operation references a flow or user that does not exist in the environment

Details: None

429

REQUEST_LIMITED

None

Message: The request could not be completed. A rate or quota limit was reached. Please try again later.

When and details

When: The request exceeds a rate limit applied to the device authentication service

Details: None

A payload check request (application/vnd.pingidentity.payload.check+json) that recognizes the browser but fails remembered device validation returns HTTP 200 with a status of FAILED and an error object whose error.code and error.message fields describe the reason. For the list of remembered device error codes, refer to Remembered devices.