PingOne Developer Guide

Welcome to the PingOne Platform API, our full-featured set of REST APIs and related native SDKs for PingOne services.

The Developer Guide is intended to get you up and running quickly, taking you through the steps to create your first worker application and obtain an access token, which is needed to interact with PingOne APIs. In addition, this guide also provides topics to help you answer the "big picture" questions you might have about the PingOne platform.

The Developer Guide is one of the sets of PingOne Platform API documentation. The others are:

  • The PingOne API Reference.

    The REST interfaces with example requests and responses, and an interactive UI to try out requests.

  • The PingOne Native SDKs.

    The native iOS and Android SDKs for PingOne services.

  • The PingOne How-to Guides.

    Numerous step-by-step PingOne workflows with linked Postman collections for you to download and try out requests.

See Getting started to begin, and use the feedback utility displayed on each page to let us know how we can make your journey easier.

Getting Started with the PingOne APIs

To begin using the PingOne Platform APIs, you'll need to first:

  1. Create an application connection using the PingOne admin console application.

  2. Get the application's access token (a JSON Web Token) for the application you created.

  3. Test the access token by running a simple PingOne Platform API request.

You'll then be able to make any PingOne Platform API requests allowed by the permissions encoded in your access token. For general information about PingOne Platform APIs, see Management APIs Overview and Authentication APIs Overview.

  1. (Optional) If you're using Postman to develop or test your project, you can also download the Postman collection for our entire PingOne Platform API, with the Postman environment template used in our example requests.

Create an application connection

Application connections determine how PingOne integrates with client applications. When you define the application connection, you also define the application's access to PingOne resources, which are encoded in the application's access token. To make calls to the PingOne Platform API, you must submit your access token with the API request.

Use the PingOne admin console to create your first application connection. To create the application connection:

  1. Click Connections.

  2. Click + Add Application.

  3. Select the Worker application type.

  4. Click Configure.

  5. Create the application profile by entering the following information:

    • Application name. A unique identifier for the application.

    • Description (optional). A brief characterization of the application.

    • Icon (optional). A pictorial representation of the application. Use a file up to 1MB in JPG, JPEG, GIF, or PNG format.

  6. Click Save and Close.

  7. The Applications page shows the new application. To view the application's access token, you must enable the new application:

    • Click the Enable toggle switch at the right. The toggle switch shows green to indicate that the new application is enabled.

Get an access token

To get the access token you created in Create an application connection:

  1. Click the application's details icon (located to the right of the enable/disable button).
  2. Click the Configuration tab.
  3. Click Get Access Token.
  4. From the Access Token window, click Copy Access Token to copy the access token.

To get your environment ID from the Admin Console:

  1. Click Settings.
  2. Click Environment.
  3. Click Properties.

The Properties page shows the environment ID.

Test your access token

Your PingOne account has at least one defined environment resource. You can use the PingOne APIs to return information about the environment resource associated with your application connection.

In the North America (NA) region:

curl -X GET "https://api.pingone.com/v1/environments/{environmentId}" \
-H "Authorization: Bearer jwtToken"

In the Canada region:

curl -X GET "https://api.pingone.ca/v1/environments/{environmentId}" \
-H "Authorization: Bearer jwtToken"

In the European Union (EU) region:

curl -X GET "https://api.pingone.eu/v1/environments/{environmentId}" \
-H "Authorization: Bearer jwtToken"

In the Asia Pacific (AP) region:

curl -X GET "https://api.pingone.asia/v1/environments/{environmentId}" \
-H "Authorization: Bearer jwtToken"

The jwtToken value in your request is your full base64url-encoded access token generated by the PingOne authentication service. If your token is valid, the API request returns a 200: Successful operation message. It also displays the property data for the environment and HAL links to show the related resources associated with the environment.


READ Environment API

Toggle stack MFA, Risk

GET a Worker Application Access Token

Toggle stack MFA, Risk

Download the PingOne Postman collections

The Postman master collections includes requests for all create, read, update, and delete (CRUD) operations for the PingOne Platform APIs, the PingOne MFA APIs, and the PingOne Risk APIs. The downloads also include a PingOne Postman environment template to help you assign values to variables in the request URLs.

For more information about the Postman environment template, see Use the PingOne Postman Environment Template.

The PingOne Postman collections

Platform Postman collection MFA Postman collection Risk Postman collection Verify Postman collection
Postman requests for the PingOne platform API, which includes the MFA, Risk, and Verify endpoints. Postman requests for the PingOne MFA APIs only. Postman requests for the PingOne Risk APIs only. Postman requests for the PingOne Verify APIs only.
Run in Postman Run in Postman Run in Postman Run in Postman

To download a Postman collection:

  1. Click the collection's Run In Postman button.

  2. At the prompt, click the import a copy link at the bottom of the screen.

    RunInPostman

  3. Follow the on-screen instructions to import the collection. You might be prompted to open your Postman app and to select a Postman workspace for the imported collection.

Use the PingOne Postman environment template

The Postman collection uses variables in the request URLs to specify UUIDs for PingOne resources within your organization. When you click the Run in Postman button here, this template downloads and installs automatically. With this environment template, you can associate your PingOne resource UUIDs with the common variables used in many of the requests.

For more information about using Postman environments, see the following topic in the Postman documentation: Environments in Postman.

For example, the following request from the PingOne Postman collection returns data about a specific user. This request contains variables for the api path, environment ID, and the user ID:

GET {{apiPath}}/environments/{{envID}}/users/{{userID}}

To run this request, you must define a value for the {{apiPath}} with the regional domain associated with your organization. Options are: https://api.pingone.com/v1 for environments in the North America region, https://api.pingone.ca/v1 for environments in the Canada region, https://api.pingone.eu/v1 for environments in the European Union region, and https://api.pingone.asia/v1 for environments in the Asia-Pacific region.

In addition, you must define values for the {{envID}} and {{userID}} variables with the UUIDs for your environment and the specific user resource whose data you want to return. Almost every request in PingOne requires an environment ID, and if you are working primarily in one environment and with one user for testing purposes, then setting values for these variables in the Postman environment template will save time.

In addition, every request to PingOne Management API endpoints requires an access token to authenticate the request. The Authorization type for the endpoints in the Postman collections is configured to Bearer Token and the value of the token is set as the variable {{accessToken}}. You can create an access token variable in the Postman environment and set its value to your current valid token.

For authorization requests, you must define a value for the {{authPath}} variable, which specifies the domain associated with the authorization server. If you are not using a custom domain name, the value should be set to https://auth.pingone.com (initial value in the template), https://auth.pingone.ca, https://auth.pingone.eu, and https://auth.pingone.asia, depending on your region.

Common variable names

Here are some common variables used in the PingOne API Postman collections:

Postman variable PingOne resource
accessToken A valid access token returned by the PingOne authorization server.
actionID The UUID of a sign-on flow action resource. Action IDs are associated with the /environments/{environmentId}/signOnPolicies/{policyId}/actions/{actionID} endpoint to identify specific sign-on policy actions such as Single_Factor or Multi_Factor.
activityID The UUID of an audit activity resource. Activity IDs are associated with the /environments/{environmentId}/activities/{activityId} endpoint, and they identify specific audit event actions, such as APPLICATION.DELETED.
apiPath The regional domain for the PingOne server. These IDs identify a specific configured application in PingOne. Options are: https://api.pingone.com/v1 for environments the North America region, https://api.pingone.ca/v1 for environments in the Canada region, https://api.pingone.eu/v1 for environments in the European Union region, and https://api.pingone.asia/v1 for environments in the Asia-Pacific region.
appID The UUID of an application resource. These IDs identify a specific configured application in PingOne. The appID is used to associate OIDC or SAML connection settings with the application specified by its UUID.
appSecret The value of the application secret. This ID has a minimum length of 64 characters per SHA-512 requirements when using the HS512 algorithm to sign ID tokens using the secret as the key.
attributeID The UUID of a custom attribute resource. Attribute IDs are associated with the /environments/{environmentId}/schemas/{schemaId}/attributes/{attributeID} endpoint to identify custom schema attributes.
authPath The domain for the PingOne authentication server. Options are: https://auth.pingone.com for the North America region, https://auth.pingone.ca for the Canada region, https://auth.pingone.eu for the European Union region, and https://auth.pingone.asia for the Asia-Pacific region.
certID The UUID of a certificate resource. Certificate IDs are associated with the /environments/{environmentId}/certificates/{certID} endpoint to identify uploaded customer-provided certificates.
contentID The UUID of a content resource. Content IDs are associated with the /environments/{environmentId}/templates/{templateName}/contents/{contentID} endpoint to identify specific email, SMS or voice notifications content.
domID The UUID of a custom domain resource. Custom domain IDs are associated with the /environments/{{envID}}/customDomains/{domID} endpoint.
deviceID The UUID of a device resource. Device IDs are associated with the /environments/{environmentId}/users/{userId}/devices/{deviceID} endpoint to associate devices with users for use in multi-factor sign-on actions.
envID The UUID of an environment resource. This ID identifies your current working domain within your organization. Nearly all Management and Authentication API endpoints require an environment ID.
flowID The UUID of an authentication flow resource. This ID is associated with the /{environmentId}/flows/{flowId} endpoint to identify the current authentication flow.
grantID The UUID of authorization grant resource. Grant IDs are associated with the /environments/{environmentId}/resources/{resourceId}/grants/{grantID} endpoint to identify authorization grant types. Grant IDs are also used with the /environments/{environmentId}/applications/{appId}/grants/{grantID} endpoint to associate resource grants with applications.
idpAttrID The UUID of an identity provider attribute resource. Identity provider IDs are used with the /environments/{environmentId}/identityProviders/{providerId}/attributes/{idpAttrId} endpoint.
idpID The UUID of an identity provider resource. Identity provider IDs are used with the /environments/{environmentId}/identityProviders/{providerId} endpoint.
imgID The UUID of an image resource. Image IDs are associated with the /environments/{environmentId}/images{imgID} endpoint to associated custom image files with the specified environment resource, which can be used for custom branding of the PingOne admin UI.
keyID The UUID of an encryption key resource. Key IDs are associated with the /environments/{environmentId}/keys/{keyID} endpoint to identify uploaded customer-provided signing/encryption keys.
licenseID The UUID of license resource. License IDs are associated with the /environments/{environmentId}/licenses/licenseID} endpoint to identify PingOne licenses.
pairingKeyID The UUID of a pairing key resource. Pairing key IDs are used with the /environments/{envId}/users/{userId}/pairingKeys endpoint to associate device pairing keys with users.
passwordPolicyID The UUID of a password policy resource. Password policy IDs are used with the /environments/{environmentId}/passwordPolicies/{passwordPolicyID} endpoint to associate password policies with the specified environment.
policyID The UUID of a sign-on policy resource. Sign-on policy IDs are used with the /environments/{environmentId}/signOnPolicies/{policyID} endpoint to associate sign-on policies with the specified environment.
popID The UUID of a population resource. Population IDs are used with the /environments/{environmentId}/populations/{popID} endpoint to manage the populations to which users can be assigned.
pushCredID The UUID of a push credential resource. Push credentials IDs are used with the /environments/{environmentId}/applications/{applicationId}/pushCredentials/{pushCredID} endpoint to send push notifications to a native application.
resourceID The UUID of a protected endpoint resource. Resource IDs identify the protected endpoints that applications request access to using OAuth 2 or SAML authorization protocols. These IDs are associated with the /environments/{environmentId}/resources/{resourceID} endpoint.
resourceAttrID The UUID of a resource attribute resource. Resource attribute IDs are associated with the /environments/{environmentId}/resources/{resourceId}/attributes/{resourceAttrID} endpoint.
roleAssignmentID The UUID of a role assignment resource. These IDs are used with the environments/{environmentId}/{actorType}/{actorId}/roleAssignments/{roleAssignmentID} endpoint to identify the roles assigned to a specified actor.
roleID The UUID of a role resource. Role IDs are used with the /roles/{roleID} endpoint to identify platform roles defined in PingOne. Note that roles and role IDs are not associated with a specific environment.
samlAttrID The UUID of an application attribute. Application attribute IDs (SAML or OIDC) are associated with the /environments/{environmentId}/applications/{applicationId}/attributes/{samlAttrID} endpoint to identify application attribute mapping resources.
schemaID The UUID of a schema resource. Schema IDs are associated with the /environments/{environmentId}/schemas/{schemaID} endpoint to identify custom user schema resources.
scopeID The UUID of a scope resource. Scope IDs are used with the /environments/{environmentId}/resources/{resourceId}/scopes/{scopeID} endpoint to define the scopes associated with a resource access grant.
SOPAssignmentID The UUID of a sign-on policy assignment resource. These IDs are used with the /environments/{environmentId}/applications/{applicationId}/signOnPolicyAssignments/{SOPAssignmentID} endpoint to assign sign-on policies to the specified application.
templateName The name of a notifications template task resource. These names are used with the /environments/{environmentId}/templates endpoint to identify a specific notifications template, which is used as the container for delivering notifications content to users. Options are: offline_pairing, verification_code_template, recovery_code_template, and offline_authentication.
userID The UUID of a user resource. User IDs are used with the /environments/{environmentId}/users/{userID} endpoint to identify specific user resources and manage user attributes.

Authentication and Authorization

The following section provides additional information about PingOne platform authorization and authentication workflows. It also includes detailed information about access tokens and ID tokens and how user scopes and platform roles enable access to PingOne resources. Topics include:

Access tokens and ID tokens

Access tokens are credential strings that represent authorization to access a protected resource. Client applications obtain access tokens by making OAuth 2 or OpenID Connect requests to an authorization server; resource servers require clients to authenticate using access tokens.

Access tokens are obtained from the token endpoint (when using the client credentials grant type) or from the authorization endpoint (when using the implicit grant type). Access tokens are typically granted on behalf of a specific authenticated user. (Tokens granted directly to applications are called application tokens.)

Clients present access tokens when making requests to a resource server (for example, the PingOne API endpoints) using bearer token authentication as described by RFC 6750. Here is a sample request using an access token:

curl -X GET "https://api.pingone.com/v1/environments" \
-H "Content-type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3QifQ.eyJzY29wZSI6IiIsImNsaWVudF9pZCI6ImlkZW50aXR5LWRpcmVjdG9yeS1zeW50aGV0aWMtdGVzdGluZyIsImlzcyI6ImF1dGgtc3RhZ2luZy5waW5nb25lLmNvbSIsImF1ZCI6ImFwaS1zdGFnaW5nLnBpbmdvbmUuY29tIiwiYWNjIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwiZW52aXJvbm1lbnRfaWQiOiIiLCJvcmciOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiLCJvcmdhbml6YXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiLCJlbnYiOiIiLCJleHAiOjE1MzAxMTc1Nzl9.OTGQethw-flgnf0oslpQOmW9YdExf6ZpsqpmRtBTeD5gpKGFmaSeHguFMVpR94GSjb27OEPzCY8qpU_OkoaQGH9FiysdgvFFVNVzHOb80e0MgP47ean1Rtk3lHmIWHg1ihp3Kt7vq9fO0OwekmfshejyaLYLX2g4seWFZKbs7ICIaSufYuGTsLLQFixiK7b0tM-lcjZUmLglPlzdGEYQgg13ZWho02rFVjwRrfOVkQRCLuhkk2Pz2eeblQgWBlzMi_zbHnRhqRnrHyX2PwoPZ9qHh3aqz6yNgGinUwSrE3J1slnx8uPeP88obYcX4QXTXOCf7su2rinbexOsNu4Puw"

Grant types

OAuth 2 and OpenID Connect define the authorization grant types by which a client application obtains an authorization grant in the form of an access token. PingOne supports the following grant types:

Authorization code

This grant type is used by web applications. The authorization request generates an authorization code that is exchanged for an access token. For more information, see Authorization request with a code grant.

Implicit

This grant type is intended for use by native applications or client-side web applications with no server-side component. The implicit grant type is for applications that cannot guarantee the confidentiality of the client secret.

In this flow, the client makes a request to the server’s authorization endpoint. If the request contains the id_token response type and the openid scope, then it is considered an authentication (OpenID Connect) request, and an ID token is issued. For more information, see Native and single-page applications.

Client credentials

This grant type is made directly to the token endpoint and is used to request an access token for either:

  • Resources owned by the client rather than any specific end user.
  • Resources belonging to multiple end users.

The client uses HTTP basic authentication with its client ID and client secret to authenticate itself to the token endpoint and must specify a Content-Type of application/x-www-form-urlencoded. For more information, see Obtain an access token.

Refresh token

This grant type is used by applications to exchange the refresh token for a new access token. It gives applications the ability to acquire a valid access token without additional interaction. For more information, see Obtain an access token.

Response types

The authorization request must specify a response_type attribute, which determines whether an access token, an authorization code, or an ID token is returned by the authorization server. The following is the list of the OAuth 2.0 response types supported by the PingOne authorization server:

  • code

    Returns an authorization code. If the grant type is authorization_code, the response_type attribute must have the code value. The authorization code returned by the request is exchanged for an access token to complete the authorization flow.

  • token

    Returns an access token. If the grant type is implicit or client_credentials, the response_type attribute can specify the token value to return an access token.

  • id_token

    Returns an ID token. If the grant type is implicit, the response_type attribute can specify the id_token value to return a JWT containing a set of claims that represent the authentication state of an end user.

  • id_token (OpenID Connect ID token)

    If the request contains the id_token response type and the openid scope, then it is considered an authentication (OpenID Connect) request, and an ID token is issued. The ID token includes the ID of the user; this request can also include the profile scope to add additional user claims to the ID token.

Token claims

All tokens in PingOne are JSON Web Tokens (JWTs) signed using the RS256 signing algorithm. The following section lists the supported claims for each token type.

Access token claims

For access tokens, the JWT header must contain the ID of the signing key as the kid claim.

Claim Description
sub A string that specifies the identifier for the authenticated user. This claim is not present for client_credentials tokens.
client_id A string that specifies the application that requested this token.
aud A string that lists the names of resources that this token is intended for. The resource of an application’s resource access grant is included if one or more scopes from the grant is requested and granted.
scope A string that specifies the space-separated list of scope names associated with this token in the format described in Section 3.3 of OAuth 2.0 RFC6749.
iss A string that specifies the per-environment issue URI: For example, https://auth.pingone.com/<environmentId>/as.
iat An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token was originally issued, as defined in JWT RFC7519.
exp An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token will expire, as defined in JWT RFC7519.
env A string that specifies the environment ID of the authenticated user or application. This claim is not present when the resource's audience property does not include the PingOne platform API resource.
org A string that specifies the organization ID of the authenticated user or application. This claim is not present when resource's audience property does not include the PingOne platform API resource.
ID Token claims

ID tokens are signed with the same key as the access token. The JWT header must contain the ID of the signing key as the kid claim.

Claim Description
sub A string that specifies the identifier for the authenticated user.
aud A string that lists the names of resources that this token is intended for. The resource of an application’s resource access grant is included if one or more scopes from the grant is requested and granted.
iss A string that specifies the per-environment issuer URI: https://auth.pingone.com/<environmentId>/as or https://<customDomain>/as.
iat An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token was originally issued, as defined in JWT RFC7519.
exp An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token will expire, as defined in JWT RFC7519.
auth_time A string that specifies the time when the user authentication occurred. Its value is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the current date and time.
nonce A string that specifies the value used to associate a client session with an id_token, and to mitigate replay attacks. The value is passed through unmodified from the authentication request to the ID token.
at_hash A case-sensitive string that specifies the access token hash value, which is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the access token value. For more information, see OpenID Connect Core 1.0.
c_hash A case-sensitive string that specifies the code hash value, which is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the code value. For more information, see OpenID Connect Core 1.0.
acr A string that specifies the name of the sign-on policy that was completed when the original authentication was performed. This claim is present only if an ID token was minted.
amr A string array that specifies the methods associated with the authenticators used when the original authentication was performed. This claim is present only if an ID token was minted.
Refresh tokens

Refresh tokens are JWTs signed with the same key as the access token. They are not intended to be read by the client. For more information about refresh token usage, see Obtain an access token.

Access token customization

PingOne lets you customize the content of access tokens by adding custom resource attributes and their values to the token. You can use the access token customization APIs to convey additional information about the user to applications. For more information, see Resource attributes.

ID token customization

You can also customize the content of OIDC ID tokens by adding custom user claims to the token. For more information, see Attribute mappings.

Token analysis

The PingOne platform supports endpoints to returns the active state of an OAuth 2.0 token and all of the claims in the token. The request takes a token parameter, which is the token string. For more information, see Token introspection.

PingOne basic login authentication flow

PingOne provides an out-of-box workflow to authenticate users. In addition, requests from OIDC/OAuth 2 and SAML applications initiate the flow and can redirect the browser to a custom authentication UI. The following diagram shows the authentication flow.

API Model

PingOne authentication flow endpoints

The following walk-through shows the actions required to authenticate a user. This scenario illustrates the following authentication operations:

  • Initiate an authorization request

  • Redirect to the authentication UI

  • Retrieve the flow and present appropriate forms to end users (and submit data) for all required steps.

  • Redirect to the resume URL when the flow is complete.

The steps that follow illustrate general flow actions. This exploration is not written as a step-by-step process that can be completed successfully.

Step 1: Initiate an authorization request

The following sample shows the GET /{environmentId}/as/authorize operation for an authorization_code request. The following sample shows as authorize request for an OIDC/OAuth 2 application.

curl -X GET \
  'https://auth.pingone.com/{environmentID}/as/authorize?response_type=code&client_id={appID}&redirect_uri=https://example.com&scope=p1:read:self:user&acr_values=Multi_Factor'

The response returns a 302 message with a flowID embedded in the Location header, which specifies that a call should be made to another resource to continue the authentication flow. The Location header looks like this:

Location: http://example.com?environmentId=9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7&flowId=acfa3223-aa05-49d5-bab2-b03dc019bb5f

Step 2: Retrieve the flow resource

The flowId returned in Step 1 specifies the flow to run to continue the authentication request. The following sample shows the GET /{environmentId}/flows/{flowId} operation that calls the flow identified by the flowId.

curl -X GET \
  'https://auth.pingone.com/{environmentID}/flows/{flowId}'

The response data looks like this. The status property in the response specifies the next action in the authentication flow. In this flow, the USERNAME_PASSWORD_REQUIRED action is the next required step:

{
    "_links": {
        "self": {
            "href": "https://auth.pingone.com/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/flows/5318a876-a8de-4d68-be79-b64043ff6490"
        },
        "usernamePassword.check": {
            "href": "https://auth.pingone.com/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/flows/5318a876-a8de-4d68-be79-b64043ff6490"
        },
        "password.forgot": {
            "href": "https://auth.pingone.com/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/flows/5318a876-a8de-4d68-be79-b64043ff6490"
        }
    },
    "id": "5318a876-a8de-4d68-be79-b64043ff6490",
    "resumeUrl": "https://auth.pingone.com/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/as/resume?flowId=5318a876-a8de-4d68-be79-b64043ff6490",
    "status": "USERNAME_PASSWORD_REQUIRED",
    "createdAt": "2019-06-18T18:47:44.750Z",
    "expiresAt": "2019-06-18T19:09:07.629Z",
    "_embedded": {
        "application": {
          "name" : "PingOne Admin Console",
          "icon" : {
             "id" : "<uuid>", 
             "href" : "[https://assets.pingone.com/ux/ui-library/4.18.0/images/logo-pingidentity.png] " 
          }
        }
    }
}

For more information about flow status values, see Flows.

Step 3: Submit data for the required action

The required action specified in Step 2 calls the action service to present the appropriate input form to end users, and after input is provided, to submit the data. This operation is performed repeatedly for each action required in the authentication flow, depending on the actions configured in the sign-on policy configuration. It continues until the flow status is COMPLETED or FAILED.

For example, the following sample shows the POST /{environmentId}/flows/{flowId} operation that calls the login with username and password action. This operation uses the application/vnd.pingidentity.usernamePassword.check+json custom media type as the content type in the request header when there is no user associated with the current flow.

curl -X POST "https://auth.pingone.com/{environmentId}/flows/{flowId}" \
-H 'Content-type: application/vnd.pingidentity.usernamePassword.check+json' \
-d '{
  "username": "jameslymanstone",
  "password": "ChangeM3!"
}'

Step 4: Redirect to the resume endpoint

After completing the actions specified by the sign-on policy, the authentication UI redirects the browser to the URL specified in the resumeUrl property in the flow resource.

The following sample shows the resumeUrl value constructed by the flow to return the flow back to the authorization service, specifying the flowID in the request URL.

"resumeUrl": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/as/resume?flowId=663067c8-3973-4578-adf2-f42514fe3dc1"

PingOne authentication flow states

An application's sign-on policy determines the flow states and the corresponding actions required to complete an authentication workflow. When the authentication workflow begins, the flow gets the list of sign-on policies assigned to the application and evaluates the policy conditions that must be met to complete sign on. The sign-on policy evaluation logic is shown in the diagram below:

Policy logic

For more information about sign-on policies, see Sign-on policies, Sign-on policy actions, and Sign-on policy assignments.

Common authentication actions

The PingOne flow API supports single-factor and multi-factor actions to complete an authentication workflow. For a single-factor login flow, there are four branches that allow the user to submit a username and password (or create a new account). PingOne also supports an identity first discovery action that identifies the user and determines the user's applicable identity provider and authentication methods. For a multi-factor authentication action, there are two branches in which either a one-time password (OTP) or a push confirmation is used as the second factor in the authentication workflow.

PingOne supports a progressive profiling action that prompts users to provide additional data at sign on. This action type does not authenticate users. It is used only to obtain additional profile data.

Login action

Login action authentication flows start with a call to the /{environmentId}/as/authorize endpoint. The response to an authorize request returns a Location HTTP header that specifies the URL for the sign-on screen and the flow ID for the authentication workflow. For a new session, the user’s browser is redirected to the sign-on screen that prompts for a PingOne username and password (or, based on the sign-on policy configuration, provides access to an external identity provider's sign-on URL).

For an existing session, the user's browser is redirected to a sign-on screen that prompts for a password only. The following diagram shows the flow options for the USERNAME_PASSWORD_REQUIRED and PASSWORD_REQUIRED flow states:

Flow overview

The login flow consists of the following four branches, which can be chosen to submit the username and password, recover a forgotten password, or create account credentials to complete the sign-on flow:

  • Sign on with username/password

    This flow verifies the username and password submitted by the user through the sign-on screen.

  • Forgot password

    If enabled, the recover password flow initiates actions to recover the account and set a new password.

  • Register user

    If enabled, the register user flow initiates actions to create an account for a user. The flow calls the user.register action to create the new user.

  • Sign on with identity provider

    If enabled, the social sign-on flow initiates actions to authenticate the user through an external identity provider.

Sign on with username and password

The username/password branch of the login flow uses the usernamePassword.check action to verify the user's password. If the user's password status is OK, the flow transitions to the next action required by the sign-on policy. If the user's password has expired, the flow transitions to the PASSWORD_EXPIRED flow state. The response from the usernamePassword.check action includes a HAL link to initiate the password.reset action to update the password. If the user is using a temporary password, the flow transitions to the MUST_CHANGE_PASSWORD flow state. The user can initiate the password.reset action to change the temporary password.

Check password

Forgot password

The recover password branch of the login flow uses the user.lookup action to verify the user. After user look-up, the flow transitions to the RECOVERY_CODE_REQUIRED flow state. The flow uses the password.recover action to issue a recovery code to the user. After the recovery code is issued and the user submits the correct code, the flow transitions to the MUST_CHANGE_PASSWORD flow state and uses the password.reset action to update the user's password.

Recover password

Register user

The register user branch of the login flow initiates the user.register action to create a new user account and set a password. The sign-on screen prompts the user to submit a username, an email address, and a password. If this action executes successfully, the flow transitions to the next action required by the sign-on policy.

Register user

Sign on with identity provider

The external identity provider (social sign-on) branch of the login flow initiates actions to authenticate the user through an external identity provider. It also links the external identity provider to the PingOne user account.

The flow diagram shows a flow path to update a user who already has an existing link to an external identity provider account, bypassing the ACCOUNT_LINKING_REQUIRED flow state. It also shows a flow path if the external identity provider account is not linked to an existing PingOne user. In this case, the flow transitions to the ACCOUNT_LINKING_REQUIRED flow state and calls the user.register action to find a matching user and initiate account linking to the external provider.

External IdP

From the ACCOUNT_LINKING_REQUIRED flow state, a user can either register as a new user or link to an existing PingOne user. In cases where the user does not exist in PingOne, the external identity provider login flow calls the user.register action to register the external identity account user as a new PingOne user. Consequently, when the social sign-on branch is implemented as a sign-on option, the sign-on policy should also include the register user sign-on branch with the registration.​enabled policy action attribute set to true.

If registration is enabled and the user exists in PingOne but no external account link is defined, PingOne tries to find a matching user (usually by email address). If PingOne does not find a matching user, then registration is required. If PingOne finds one or more matching users (more than one user in the system with a matching email address), then the flow prompts for a username and password to verify the user's identity and complete the account link.

If the registration login flow branch is disabled in the sign-on policy, then the user who tries to log in with external identity provider credentials can only link to an already existing user in PingOne.

Identifier first action

The identity provider discovery login flow initiates actions to identify the user and determine the applicable authentication methods for this user. It is designed to be used as an alternative to the standard login flow. It differs from the username/password login flow in that it first prompts the user for a username, and then it uses the identity provider discovery rules defined in the sign-on policy to route the user to the correct external identity provider for authentication.

A condition in the sign-on policy specifies the external identity providers that are evaluated to verify whether one of them is the authoritative source of identity. If one is found, the user is directed to authenticate using the external identity provider’s authentication flow. The flow transitions to the EXTERNAL_AUTHENTICATION_REQUIRED flow state and redirects the browser to the external identity provider's login URL.

IdP Discovery

Identifier first with login_hint

If the authorize request uses the login_hint property to identify the user, then the identity provider discovery login flow no longer prompts the user for a username in the sign-on flow. It uses the identity provider discovery rules defined in the sign-on policy to route the user directly to the correct external identity provider for authentication. The flow transitions to the EXTERNAL_AUTHENTICATION_REQUIRED flow state and redirects the browser to the external identity provider's login URL.

IdP Discovery

Identity provider account confirmation

Identity provider account confirmation occurs when the confirmIdentityProviderAttributes property in the login sign-on action is set to true. If the flow does not find a linked user with PingOne authorization authority linked to the external account, the flow transitions to the ACCOUNT_CONFIRMATION_REQUIRED flow state and redirects the browser to a form to confirm or update values for attributes mapped from the identity provider. After confirmation or update, the flow calls the user.confirm action to search for users with PingOne authentication authority based on mapped unique attributes. If matches are found, the flow transitions to the ACCOUNT_LINKING_REQUIRED flow state and redirects the browser to a form to select the matching user account. The flow updates the user account and completes.

IdP Confirm

Multi-factor (MFA) action

The MFA (multi-factor authentication) flow adds an MFA action to the authentication flow. When an MFA flow is initiated, the flow evaluates information about the requesting device and initiates appropriate MFA actions:

  1. If the MFA flow begins on a paired MOBILE device, it transitions directly to the device authorization flow (with or without extra verification specified in the sign-on policy).

  2. If the device authorization flow was not initiated, the flow checks the device to determine if it is a paired FIDO2 biometric device (by looking for an existing session token ST cookie). If the user has a session token cookie for this user on the browser (or if a FIDO2 biometrics device is selected during the device selection flow), the flow transitions to the FIDO2 biometrics flow. If no session token cookie exists, the flow will complete with the default device or with device selection, but not through bypass.

  3. If the FIDO2 biometrics flow is not started, the flow transitions to the device selection flow or to another flow using the default device.

  4. If the selected (or default) device is a MOBILE device with PUSH enabled, the flow transitions to the native PUSH flow.

  5. If the selected (or default) device is of type MOBILE, SMS, VOICE, EMAIL, TOTP, or SECURITY_KEY, the flow transitions to the offline flow (for MOBILE, SMS, VOICE, EMAIL, TOTP types) or the security key flow.

MFA Device flow overview

These MFA flow paths are described in the following sections.

Device authorization flow

If the user is authenticating from a paired MOBILE device and device authorization with extra verification is enabled (in the sign-on policy), the MFA flow transitions to PUSH_CONFIRMATION_REQUIRED. If extra verification is not enabled, the flow completes immediately. If the user does not have a default device, the flow transitions to the DEVICE_SELECTION_REQUIRED flow state and calls the device.select action to specify the device used for the MFA action. For more information about extra verification, see the "MULTI_FACTOR_AUTHENTICATION action data model" table in the Sign-On Policy Actions topic.

MFA Device authorization flow

FIDO2 device flow

If the user is authenticating from a registered platform device and has a session token (ST) cookie on a compatible browser, the FIDO2 biometric flow uses this device, bypassing the default device. The flow transitions to the ASSERTION_REQUIRED flow state and calls the assertion.check action to complete the flow. If there is no session token cookie on the browser, or the FIDO2 device type is SECURITY_KEY, the default device is selected automatically. The flow transitions to the ASSERTION_REQUIRED flow state and calls the assertion.check action to complete the flow. For more information about FIDO2 platform devices, see MFA Devices.

MFA FIDO2 device flow

Native PUSH device flow

If the default device is a MOBILE application with PUSH enabled, a PUSH notification is sent to the application, and the flow transitions to the PUSH_CONFIRMATION_REQUIRED flow state. The flow transitions to one of the following states:

  • COMPLETED if the user approves the authentication action on the native device.

  • FAILED if the user denies the authentication action on the native device.

  • PUSH_CONFIRMATION_TIMED_OUT if the user does not respond to the authentication action on the native device.

If pushless is enabled, the flow transitions to the OTP_REQUIRED flow state and calls the otp.check action to send a one-time passcode (OTP) to the user's specified device. After the OTP is issued and the user submits the correct OTP, the flow completes.

Native PUSH device flow

Offline device and security key flows

If the default device is an email, SMS, voice, authenticator device (TOTP) or a MOBILE device in PUSHLESS mode, the flow transitions to the OTP_REQUIRED flow state and calls the otp.check action to send a one-time passcode (OTP) to the user's specified device. After the OTP is issued and the user submits the correct OTP, the flow completes.

If the default device (or selcted device) is SECURITY_KEY, the flow transitions to the ASSERTION_REQUIRED flow state and calls the assertion.check action to send a FIDO2 assertion retrieved by the WebAuthn browser API for the specified device. After the client submits the correct assertion, the flow completes. For more information about FIDO2 security key devices, see MFA Devices.

MFA offline device flow

Device selection flow

If the user does not have a default device, and the conditions to trigger the device authorization or FIDO2 platform flows are not met, the flow transitions to the DEVICE_SELECTION_REQUIRED flow state. The client calls the device.select action to specify an MFA device to use for performing the MFA action. After device selection, the flow transitions to either the offline flow, the FIDO2 biometrics flow, or the native flow with PUSH enabled, depending on the selected device. For more information, see MFA Devices.

If pushless is enabled, and the flow is in the PUSH_CONFIRMATION_TIMED_OUT state, the flow can also transition to the OTP_REQUIRED flow state and calls the otp.check action to send a one-time passcode (OTP) to the user's specified device. After the OTP is issued and the user submits the correct OTP, the flow completes.

MFA FIDO2 device flow

Progressive profiling action

The progressive profiling login flow prompts users to provide additional data at sign on. The attribute data provided is added to the user's profile. For example, this flow can be configured to follow the user.register action to add more user data to the newly created account. The sign-on screen prompts the user to submit data for the specified user attributes. If this action executes successfully, the flow transitions to the next action required by the sign-on policy.

Progressive profiling

Authentication workflow walkthrough

An authentication workflow starts with an application's sign-on policy. The sign-on policy determines the steps and corresponding actions required to authenticate a user's account. When the authentication workflow begins, the flow gets the sign-on policy (or policies) assigned to the application.

Application sign-on policies

The PingOne platform includes the following two pre-configured sign-on policies:

  • Single_Factor

    A single-factor sign-on policy that prompts users to enter a username and password to authenticate the account.

  • Multi_Factor

    A two-step authentication process that prompts users to take the following actions to authenticate the account:

    • Enter a username and password.
    • Enter a one-time password (OTP) on a registered phone number or email, or approve the authentication on a registered native device.

If an application does not have an assigned sign-on policy, it uses the default sign-on policy for the environment. If the application has one or more assigned sign-on policies, the flow service evaluates the sign-on policies and their conditions based on designated priority (or the order in which the assigned policies are listed in the acr_values attribute of the authorization request). If all actions for an assigned policy complete successfully, the authorization workflow completes successfully.

For more information about sign-on policies, see Sign-on policies and Sign-on policy actions.

For information about assigning a sign-on policy to an application, see Sign-on policy assignments.

Sign-on request

PingOne authentication workflows are initiated with a call to the /{environmentId}/as/authorize endpoint. The application's type property determines the parameters required in the authorize request. For more information about application types and the supported parameters for an authorize request, see Authorization requests for application types.

The response to an /{environmentId}/as/authorize request returns a Location HTTP header that specifies the URL for the sign-on screen and the flow ID for this specific authentication workflow. The user's browser is redirected to the sign-on screen, which looks like this for a new session.

Login screen user and password

For an existing session, the user's browser is redirected to a sign-on screen that prompts for a password:

Login screen password only

Get the flow

As the user's browser is redirected to the sign-on screen, the authorize service calls the GET /{environmentId}/flows/{flowID} operation and uses the {flowId} value from the /{environmentId}/as/authorize response to get the flow and the current flow state. The status property in the GET /{environmentId}/flows/{flowID} response specifies the initial flow state, which determines the possible next actions in the authentication workflow.

Both the Single_Factor and Multi_Factor pre-defined sign-on policies require a username and password. The response data looks like this:

{
    "_links": {
        "self": {
            "href": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/flows/663067c8-3973-4578-adf2-f42514fe3dc1"
        },
        "usernamePassword.check": {
            "href": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/flows/663067c8-3973-4578-adf2-f42514fe3dc1"
        },
        "password.forgot": {
            "href": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/flows/663067c8-3973-4578-adf2-f42514fe3dc1"
        }
    },
    "id": "663067c8-3973-4578-adf2-f42514fe3dc1",
    "resumeUrl" : "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/as/resume?flowId=ff50b02c-48dd-4fbf-9c6d-82e8cc9e70c6",
    "status" : "USERNAME_PASSWORD_REQUIRED",
    "createdAt" : "2019-06-04T21:52:34.866Z",
    "expiresAt" : "2019-06-04T22:07:35.724Z"
  }
}


In this example, the status attribute shows a flow state of USERNAME_PASSWORD_REQUIRED, specifying that username and password values are required to complete this sign-on action. The response also includes the following HAL links to present options for the next operation in the flow:

  • usernamePassword.check

    An action to sign on with a username and password.

  • password.forgot

    A sign-on action to recover a user’s forgotten password.

Complete the sign-on action

To respond to the USERNAME_PASSWORD_REQUIRED flow state, the user initiates the usernamePassword.check action, which includes these steps:

  1. The user enters a username and password in the fields provided on the sign-on screen.

  2. The user clicks Sign on to initiate the usernamePassword.check authentication action.

  3. The flow service calls the POST /{environmentId}/flows/{flowId} endpoint operation and uses the application/vnd.pingidentity.usernamePassword.check+json custom media type in the Content-type HTTP request header to identify the action. For more information about this request, see Login with username and password.

Complete the Single_Factor sign-on flow

For a Single_Factor sign-on policy, if the user's account and password are valid, the flow returns a status of COMPLETED, indicating that the conditions of the Single_Factor sign on policy have been met.

The response data looks like this:

{
    "_links": {
        "self": {
            "href": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/flows/663067c8-3973-4578-adf2-f42514fe3dc1"
        }
    },
    "id": "663067c8-3973-4578-adf2-f42514fe3dc1",
    "session": {
        "id": "ec249037-9f42-40d5-bdda-eb9b7ddeac18"
    },
    "resumeUrl": "https://auth.pingone.com/4fda72e8-0490-4e2a-96ba-2b0a4cf25ddd/as/resume?flowId=663067c8-3973-4578-adf2-f42514fe3dc1",
    "status": "COMPLETED",
    "createdAt": "2019-07-09T19:56:59.817Z",
    "expiresAt": "2019-07-09T20:22:08.229Z",
    "_embedded": {
        "user": {
            "id": "710d6278-ccce-4a91-bdb9-ac7a4a0e60d5",
            "username": "lindajones@example.com",
            "name": {
                "given": "Linda",
                "family": "Jones"
            }
        }
    }
}

Continue the flow for Multi_Factor authentication

For a Multi_Factor sign-on policy, after the username/password action finishes, the flow continues by returning one of the following MFA status values:

  • DEVICE_SELECTION_REQUIRED

    This flow state prompts the user to select a device to receive the OTP. This status occurs when the user has more than one registered device.

    Device select screen

  • OTP_REQUIRED

    This flow state prompts the user to complete a multi-factor authentication action that involves receiving a one-time password (OTP) on a specified device and submitting the OTP. This status occurs when the user has only one EMAIL, SMS or VOICE registered device used to receive the OTP (or after selecting a device).

    OTP screen

  • PUSH_CONFIRMATION_REQUIRED

    This flow state prompts the user to approve or deny a push confirmation sent to the user’s registered native device. This status occurs when the user has only one registered MOBILE device type registered to receive push notifications (or after selecting a native device).

    Confirm screen

  • PUSH_CONFIRMATION_TIMED_OUT

    This flow state occurs when the user does not respond to the push authentication confirmation request. It prompts the user to retry push authentication (with the same device) or choose a different registered device.

    Timeout screen

Complete the MFA action

The MFA authentication flow requires specific actions depending on the flow state.

DEVICE_SELECTION_REQUIRED

To respond to the DEVICE_SELECTION_REQUIRED flow state, the user initiates the device.select action, which includes these steps:

  1. The sign-on screen presents the list of registered devices.

  2. The user clicks a registered device to specify the device to use for the MFA action.

  3. The flow service calls the POST /{environmentId}/flows/{flowId} endpoint operation and uses the application/vnd.pingidentity.device.select+json custom media type in the Content-type HTTP request header to identify the action. For more information about this request, see Select an MFA device.

After a device is selected, the flow transitions to the OTP_REQUIRED flow state and initiates the otp.check action, or it transitions to the PUSH_CONFIRMATION_REQUIRED flow state to prompt the user to accept or deny the confirmation request.

OTP_REQUIRED

To respond to the OTP_REQUIRED flow state, the user initiates the otp.check action, which includes these steps:

  1. The user receives the OTP on the specified device.

  2. The user enters the OTP in the field provided on the sign-on screen.

  3. The user clicks Submit to initiate the otp.check authentication action.

  4. The flow service calls the POST /{environmentId}/flows/{flowId} endpoint operation and uses the application/vnd.pingidentity.otp.check+json custom media type in the Content-type HTTP request header to identify the action. For more information about this request, see Validate the OTP.

After the OTP is issued and the user submits the correct OTP, the flow completes.

PUSH_CONFIRMATION_REQUIRED

To respond to the PUSH_CONFIRMATION_REQUIRED flow state, the user completes these actions:

  1. The user receives the push authentication request on the specified native device.

  2. The user chooses ACCEPT or DENY in response to the confirmation prompt.

  3. Validation for a push authentication request is managed by the PingOne Native SDK on the native device. For more information, see Native SDK APIs.

PUSH_CONFIRMATION_TIMED_OUT

To respond to the PUSH_CONFIRMATION_TIMED_OUT flow state, the user completes these actions:

  1. The user is prompted to either retry push authentication on the currently selected device, or select a different registered native device.

  2. For a retry action, the user receives the push authentication request on the currently selected native device and chooses APPROVE or DENY in response to the confirmation prompt.

  3. Validation for a push authentication request is managed by the PingOne Native SDK on the native device.

For a Multi_Factor sign-on policy, if the user submits the correct OTP or selects APPROVE in the push confirmation prompt, the flow returns a status of COMPLETED, indicating that the conditions of the Single_Factor sign on policy have been met.

For more information about MFA flow states, see Multi-factor authentication flow states.

Authorization and authentication by application type

PingOne supports several application types. When you make a POST /environments/{environmentId}/applications request to define a new application, you must specify the type property that best describes the application. PingOne supports the following application types:

  • Web application

    A browser-based application with a server-side component, such as ASP, CGI, JSP/Java, Node.js, or Ruby on Rails applications.

  • Native application

    An application that is installed and run directly on the local operating system, like Java, Objective-C, Swift, or React applications. Native applications are typically intended for native devices.

  • Single page application

    A browser-based application that runs on the front-end with no server-side component, such as Sencha Touch, AngularJS, and React applications. A single page application runs on the client side after it loads, so it cannot keep a client secret.

  • Non-interactive

    A web application that does not require user interaction through the web browser, like a command line interface, a service, or a daemon.

  • Worker

    An administrator application that can interact with platform APIs. Access to platform APIs is determined by the user's or application's role assignments.

Authorization flow steps

An authorization grant gives applications the capability to authenticate users and access secure resources. The following steps describe the application authorization flow:

  1. The application initiates the authorization flow through a GET or POST request to the authorize endpoint.

  2. The authorization service generates the access token for the implicit grant.

  3. For authorization_code and client_credentials grants, the application calls the /{environmentId}/as/token endpoint to acquire the access token.

For more information about authorization, see OpenID Connect/OAuth 2.

Authorization requests for application types

The following examples describe common authorization requests for the designated application type.

Web applications

For web applications, the typical grant type to request access to protected resources is authorization_code. The /{environmentId}/as/authorize endpoint supports GET and POST methods and returns the authorization code needed to acquire an access token. After an authorization code is returned successfully, the code is used to get the access token.

The following sample shows the GET /{environmentId}/as/authorize operation.

https://auth.pingone.com/{environmentID}/as/authorize?response_type=code&client_id={appID}&redirect_uri=https%3A%2F%2Fexample.com&scope=openid%20profile%20email&acr_values=Single_Factor&prompt=login

The request URL contains the following parameter values:

  • response type

    Specifies the response type for the authorization request. If the grant type is authorization_code, the response_type parameter must have a value of code. This parameter is required.

  • client_id

    Specifies the application's UUID, returned from a GET /environments/{environmentId}/applications/{applicationId} request. This parameter is required.

  • redirect_uri

    Provides a URL that specifies the return entry point of the application. This parameter is required.

    Note: To ensure proper redirect on some iOS and OSX browsers, the redirect_uri value must include a trailing slash. For example, a registered URI of https://www.pingidentity.com/ redirects properly to https://www.pingidentity.com/#access_token=eyJsdf, but a registered URI of https://www.pingidentity.com redirects incorrectly to https://www.pingidentity.com/en.html, and the client application would not receive the access token.

  • scope

    Specifies permissions that determine the resources that the application can access. This parameter is not required, but it is needed to specify accessible resources.

  • acr_values

    An optional parameter that designates whether the authentication request includes specified sign-on policies. Sign-on policy names should be listed in order of preference, and they must be assigned to the application. For more information, see Sign-on policies.

  • prompt

    An optional parameter that specifies whether the user is prompted to login for re-authentication. The prompt parameter can be used as a way to check for existing authentication, verifying that the user is still present for the current session.

The authorization request returns a URL to initiate login flow. This authentication flow presents appropriate login forms to an end user and submits data provided by the user for all required sign-on steps. After all login actions in the flow are completed, the GET /{environmentId}/as/resume endpoint continues processing the authorization request.

https://auth.pingone.com/{environmentID}/as/resume?flowId={flowID}

After restarting the authorization flow, the authorization code is submitted through a request to the POST /{environmentId}/as/token endpoint to create the access token.

curl --request POST \
  --url 'https://auth.pingone.com/{envID}/as/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'grant_type=authorization_code&code={authCode}&redirect_uri=https%3A%2F%2Fexample.com'

The grant_type, code, and redirect_uri parameter values are required in the request body.

Native and single-page applications

For native applications and single-page applications, the default grant type to request access to protected resources is implicit.

For the implicit flow, the application is issued an access token without requiring an authorization code exchange. When the request is made to the /{environmentId}/as/authorize endpoint for an implicit grant type, the value of the response_type parameter is set to token or id_token.

If the request contains the id_token response type and the openid scope, then it is considered an authentication (OpenID Connect) request, and an ID token is issued. The ID token includes the ID of the user; this request can also include the profile, email, address, and phone OIDC scopes to add additional user claims to the ID token.

The following sample shows the GET /{environmentId}/as/authorize operation to return an id_token.

https://auth.pingone.com/{environmentID}/as/authorize?client_id={applicationID}&redirect_uri=https:%3A%2F%2Fexample.com&response_type=id_token&scope=openid%20profile%20email&acr_values=Single_Factor&max_age=86400

The request can specify the token or id_token response types individually, or both. The following sample shows the GET /{environmentId}/as/authorize operation to return a token and an id_token:

curl --request GET \
  --url 'https://auth.pingone.com/{environmentID}/as/authorize?client_id={applicationID}&redirect_uri=https://example.com&response_type=token id_token&nonce=12345&scope=openid profile p1:read:user&acr_values=Single_Factor&max_age=86400'

In this request, the p1:read:user scope is included in the access token but not in the ID token.

The request URL contains the following parameter values:

  • response type

    Specifies the response type for the authorization request. The implicit grant type requires a response_type parameter value of token or id_token (or both). This parameter is required.

  • client_id

    Specifies the application's UUID, returned from a GET /environments/{environmentId}/applications/{applicationId} request. This parameter is required.

  • redirect_uri

    Provides a URL that specifies the return entry point of the application. This parameter is required.

    Note: To ensure proper redirect on some iOS and OSX browsers, the redirect_uri value must include a trailing slash. For example, a registered URI of https://www.pingidentity.com/ redirects properly to https://www.pingidentity.com/#access_token=eyJsdf, but a registered URI of https://www.pingidentity.com redirects incorrectly to https://www.pingidentity.com/en.html, and the client application would not receive the access token.

  • nonce

    A string that is used to associate a client session with a token to mitigate replay attacks. The value is passed through unmodified from the authentication request to the token. This is a required property for authorization requests that return a token. It is not required for requests that return only an id_token.

  • scope

    Specifies permissions that determine the resources that the application can access. This parameter is not required, but it is needed to specify accessible resources.

  • acr_values

    An optional parameter that designates whether the authentication request includes specified sign-on policies. Sign-on policy names should be listed in order of preference, and they must be assigned to the application. For more information, see Sign-on policies.

  • max_age

    An optional parameter that specifies the maximum amount of time allowed since the user last authenticated. If the max_age value is exceeded, the user must re-authenticate.

After all login action steps in the flow are completed successfully, the GET /{environmentId}/as/resume endpoint is called to continue processing the authorization request.

https://auth.pingone.com/{environmentID}/as/resume?flowId={flowID}

The authorization service generates the token or id_token for the application after restarting the authorization flow; it does not require a step to call the /{environmentId}/as/token endpoint.

Non-interactive applications

Non-interactive applications support the client_credentials, authorization_code, implicit, and refresh_token grant types to obtain an access token. For information about authentication flows for applications using the authorization_code and implicit grant types.

The following sample shows the POST request to the /{environmentId}/as/token endpoint to acquire the access token. Note that the application must have its tokenEndpointAuthMethod attribute value set to client_secret_post.

curl --request POST \
  --url 'https://auth.pingone.com/{environmentID}/as/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'grant_type=client_credentials&client_id={applicationID}&client_secret={secret}'

The request URL contains the following parameter values:

  • grant_type

    Specifies the grant type for the authorization request, which for non-interactive applications must be a client_credentials grant. This parameter is required.

  • client_id

    Specifies the application's UUID, returned from a GET /environments/{environmentId}/applications/{applicationId} request. This parameter is required.

  • client_secret

    Specifies the application's client secret, returned from a GET /environments/{environmentId}/applications/{applicationId}/secret request. This parameter is required.

For client_credentials requests in which the application's tokenEndpointAuthMethod attribute value is set to client_secret_basic, the client_id and client_secret attributes cannot be part of the request body. In these cases, the client_id and client_secret are passed in as a Base64 encoded authorization header in the request:

curl --request POST \
 --url 'https://auth.pingone.com/{environmentID}/as/token' \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --user 'client_id:client_secret' \
 --data 'grant_type=client_credentials'

The --user 'client_id:client_secret' option tells curl to use a BASIC authentication header with the specified credentials in the request, which is similar to this:

Authorization: Basic <base64 encoded "client_id:client_secret">

Worker applications

Worker applications are administrator applications that interact with platform APIs. This application type supports only the OPENID_CONNECT protocol. When creating a new worker application, the application inherits the same role assignments as the user or application that created the application. When getting a token using the client_credentials grant type, the application's role assignments are used.

Worker applications that use a user-based grant type such as implicit or authorization_code let you assign only OIDC scopes to the application. When getting a token using a user-based grant type, the user's role assignments are used.

The following sample shows the /{environmentID}/as/token request with a client_credentials grant to return an access token with no platform scopes.

curl --request POST \
 --url 'https://auth.pingone.com/{environmentID}/as/token' \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data 'grant_type=client_credentials&client_id={applicationID}&client_secret={secret}'

The response returns the access_token, the token_type, and the expires_in property values. It does not list any scopes.

{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3QifQ.eyJzY29wZSI6IiIsImNsaWVudF9pZCI6ImlkZW50aXR5LW...",
  "token_type": "Bearer",
  "expires_in" : 3600
}

Access services through scopes and roles

User applications rely on self-management scopes to grant users access to a subset of PingOne resources. For more information about scopes, see Resource scopes. Conversely, administrator applications use role assignments to determine the actions a user or client can perform. For more information about roles, see Roles.

PingOne self-management scopes

Self-management scopes are applicable to users only. They are granted on authorization_code and implicit authorization flows. PingOne self-management scopes cannot be granted on a client_credentials flow.

The self-management scopes specified in an authorization request identify the resources that end users can access to perform self-management actions. These scopes use the following naming format to represent a self-management permission:

p1:<permission-action>:<permission-classifier>

For example, the self-management scope to read user information is p1:read:user.

The PingOne platform includes the following self-management scopes:

Scope Description
p1:read:user Users can retrieve their own user identity and all attributes. If the user authenticates with an authoritative identity provider (user.identityProvider.id is not null), their password state will not be returned with a self-service GET READ One User request.
p1:update:user Users can modify the attributes of their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:update:userMfaEnabled Users can enable and disable multi-factor authentication for their own user identity.
p1:create:device Users can create multi-factor authentication devices for their own user identity.
p1:read:device Users can retrieve multi-factor authentication devices for their own user identity.
p1:update:device Users can update multi-factor authentication devices for their own user identity.
p1:delete:device Users can delete multi-factor authentication devices for their own user identity.
p1:read:userPassword Users can read the password state for their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:reset:userPassword Users can reset the password for their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:validate:userPassword Users can validate the password for their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:read:userLinkedAccounts Users can read linked accounts for their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:delete:userLinkedAccounts Users can delete linked accounts for their own user identity. This scope is not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).
p1:create:pairingKey Users can create a pairing key for their own user identity.
p1:delete:pairingKey Users can delete a pairing key for their own user identity.
p1:read:pairingKey Users can read a pairing key for their own user identity.
p1:read:sessions Users can read sessions for their own user identity.
p1:delete:sessions Users can delete sessions for their own user identity.
User scopes enable self-service actions

User scopes provide privileges to specific actions, giving end users the ability to interact with their own profile data. An example of a commonly used user scope is p1:reset:userPassword. This scope, when included in an authorization request, generates access tokens that give users permission to run the self-service password reset action.

The following sample shows an authorization_code request that includes the reset password scope.

curl --request GET \
  --url 'https://auth.pingone.com/{environmentID}/as/authorize?response_type=code&client_id={appID}&redirect_uri=https://example.com&scope=p1:reset:userPassword'

For more information about authorization requests, see OpenID Connect/OAuth 2.

Access control self scopes

Some PingOne platform self-management scopes allow organizations to specify which user profile attributes are accessible to end users. An administrator might want to prevent end users with access to their profiles from seeing or modifying particular attributes that should remain private, such as custom attributes for entitlements, internal foreign keys, account status information, or any profile data that should not be exposed to an individual user. With access control scopes, organizations can store additional private data in the user profile without risk that the end user can see the data.

The following scopes allow access control:

Scope Description
p1:read:user and p1:read:user:{suffix} Users can read any of the user schema attributes defined in the scope's schemaAttributes property for their own user identity. The p1:read:user scope can be modified using PUT to change the list of user schema attributes. The p1:read:user:{suffix} scope is created using POST and must specify at least one user schema attribute in the schemaAttributes property.
p1:update:user and p1:update:user:{suffix} Users can modify any of the user schema attributes defined in the scope's schemaAttributes property for their own user identity. The p1:update:user scope can be modified using PUT to change the list of user schema attributes. The p1:update:user:{suffix} scope is created using POST and must specify at least one user schema attribute in the schemaAttributes property. These scopes are not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).

For example, an access control scope based off of p1:update:user (such as p1:update:user:name that specifies only the ['name.family', 'name.given'] user attribute in the scope's schemaAttributes property) allows self updates of the first and last name attributes only. For more information about self-scope properties, see Resource scopes.

When the actor is self, the following behaviors apply to the p1:read:user and p1:read:user:{suffix} access control scopes for a GET /environments/{environmentId}/users/{userId} request:

  • Attributes that are not included in any provided read scope are excluded from output, except for the id attribute, which is always included in the response if any other user schema attributes are returned.

  • An attribute that is included in a read scope and present in the user record is included in the response body.

  • An attribute that is not included in a read scope and present in the user record is excluded from the response body.

If no attributes are included in the provided read scopes (if self has no access), then an HTTP Status 403 error is returned.

Likewise, the following behaviors apply to the p1:update:user and p1:update:user:{suffix} access control scopes for a PUT /environments/{environmentId}/users/{userId} request:

  • Attributes that are not included in any provided updates scope are not accessible to end users for update.

  • Immutable attributes such as id even if included, are not updated. Attempts to update immutable user attributes are ignored.

  • An attribute that is included in an update scope and present in the user record is accessible to update, unless it is immutable.

  • An attribute that is not included in an update scope and present in the user record is not accessible to update.

  • Multi-value attribute updates replace the entire attribute. It is not possible to merge data into an existing set of values.

  • The multiValued property of an attribute can only be changed from false or null to true, never from true to false.

These scopes are not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).

If the user does not have update access to an attribute, a 403 Forbidden error is returned if an update is attempted for that attribute.

Restricted access scopes
License capabilities and access scopes

License capabilities control access to some PingOne self-service scopes. Your PingOne license can disable access to specific scopes (and their associated permissions) based on the capabilities enabled by the license package. For example, if your PingOne license supports only MFA capabilities, then other self-service capabilities such as canUsePasswordManagement, canUseIdentityProviders, and canUsersUpdateSelf are set to false in the license. With these capabilities set to false, access to the scopes controlled by these capabilities are restricted.

The following capabilities control access to these associated scopes:

Capability Associated scopes
canUsePasswordManagement p1:reset:userPassword, p1:read:userPassword
canUseIdentityProviders p1:read:userLinkedAccounts, p1:delete:userLinkedAccounts
canUsersUpdateSelf p1:update:user

If the controlling capability is set to false, authorization requests that specify restricted scopes will not grant a token that includes the restricted scopes. However, if the authorization request also specifies a non-restricted platform scope, such as p1:read:user, the request returns a token that includes only the p1:read:user scope.

Authoritative identity providers and access scopes

The following self-service scopes are not granted if the user authenticates with an authoritative identityProvider (user.identityProvider.id is not null).

  • p1:update:user
  • p1:update:user:{suffix}
  • p1:read:userPassword
  • p1:reset:userPassword
  • p1:validate:userPassword
  • p1:read:userLinkedAccounts
  • p1:delete:userLinkedAccounts

OpenID Connect (OIDC) scopes

Standard OpenID Connect scopes control which user claims are included in an id_token or in a userinfo response. Unlike other resources, scopes from this resource can be included in an access token along with scopes from another resource.

PingOne supports the following OIDC scopes:

Scope Description
profile This scope value requests access to the end-user's default profile claims, which are: name, family_name, given_name, middle_name, preferred_username, picture, zoneinfo, locale, and updated_at.
email This scope value requests access to the email claim.
address This scope value request access to the address claim.
phone This scope value requests access to the phone_number claim.
OIDC scopes for user information

The following sample shows an implicit authorization request with an id_token response type. The scope parameter specifies the required openid scope. It also specifies the optional profile scope to provide access to the end-user's default profile claims.

curl -X GET \
  'https://auth.pingone.com/{environmentId}/as/authorize?client_id={clientId}&redirect_uri=https://example.com&response_type=id_token&scope=openid profile'

For more information about retrieving scopes for a specified resource, see Get scopes for a resource.

Custom scopes

Resources are the protected endpoints that applications request access to using OAuth 2 authorization services. The PingOne platform includes two predefined resources, PingOne API, which is a defined resource that represents the PingOne APIs, and openid, which represents OpenID Connect scopes. These resources have self scopes that grant an actor permission to perform CRUD operations on the actor's data (such as p1:create:device, p1:read:device, p1:update:device, and p1:delete:device).

In addition, the platform lets you configure additional resources and their associated self scopes. For example, a custom resource such as https://api.acme-photo.com might have upload:photos, read:photos, edit:photos, and delete:photos scopes that give users permission to manage their photo libraries.

PingOne supports the following two types of resource scopes.

Custom resource scopes

Custom resource scopes are associated with protected endpoints on a non-PingOne resource server. Custom resources can be associated with an application either exclusively, or in addition to the platform's predefined resources. When an application is associated with both the PingOne platform resource and a custom resource, an authorization request cannot include scopes from both PingOne and the custom resource.

If you do specify scopes from two different resources in the authorize request, the request returns the following error:

The request could not be completed. One or more validation errors were in the request.: May not request scopes for multiple resources (Correlation ID: 8E7B23B8-6761-4532-8AFC-4B723D52FF5D).

If more than one resource is associated with the application, actors need to make separate authorization requests to get a token for the desired resource scopes.

For more information about defining scopes for custom resources, see Create scope.

Custom PingOne API scopes

Custom PingOne API scopes control access to specific user schema attributes. As described above, a PingOne platform custom scope is based on an existing platform scope and uses the schemaAttributes property in the scope's definition to list the specific user attributes that the end user has permission to read or update. For example, a scope that grants permission to update only the user's email address would list only the email attribute in the schemaAttributes property. This PingOne custom scope is named by adding a descriptive suffix to the base PingOne scope name: p1:update:user:email-only.

For more information about defining custom PingOne API scopes, see Create PingOne access control scope.

Administrator permissions and role assignments

Unlike user self-service applications, administrator applications use role assignments to determine the actions a user or client can perform. For external API client applications, the access tokens do not use scopes to control access to resources. Instead, the actor's role assignments determine resource access.

Worker application permissions

Administrator applications that interact with non-self Platform APIs are classified as a WORKER application type. This application type supports only the OPENID_CONNECT protocol. A worker application that uses the client_credentials grant type inherits the same role assignments as the user or application that created the application. These role assignments can be cross-environment, which allows access to APIs for other environments.

Role assignments determine access to APIs (see Application role assignments and User role assignments. Users and clients cannot create or use clients that have more privileges than the worker application itself. For example, an actor with only the Identity Data Admin role cannot create a worker application that has Environment Admin privileges. Likewise, access to an application's client secret is restricted based on the accessing user's or application's role assignments. If an actor has only the Identity Data Admin role, it is not able to see the client secret. Similar roles can have different privileges, or restrictions, based on the role's scope. For example, an actor with an Environment Admin role over a single environment cannot access the client secret of an application with Environment Admin privileges over the entire organization.

PingOne roles include a set of permissions that allow access to PingOne resources. For example, the Identity Data Admin role grants access to PingOne resources for these user management actions:

  • Read, create, update, and delete user resources
  • Read, create, update, and delete device management resources
  • Assign identity resources
  • Bulk user import
  • Read, create, update and delete population resources
  • Update user password resources
  • Read user password state resources
  • Read password policy resources
  • Read audit reporting activities resources
  • Read schema resources

The actor (user or client) assigning roles to the application must have the permissions that they are trying to assign. In other words, the requesting user or client must have the same (or broader) role assignments as the target application's role assignments. This prevents a lesser privileged user (such as a Client Application Developer) from creating a more privileged client_credentials application (such as an Environment Admin).

When retrieving access tokens for WORKER applications, the authorization service checks to make sure the user or client has at least one role assignment. If not, the token request is rejected. If at least one role assignment exists, the authorization service creates a token with no scopes except for the requested OIDC scopes. When accessing platform APIs with this token, it retrieves the actor's entitlements, which ensures that clients and users can access only the resources that their role assignments allow.

Worker applications and environments

When a worker application with Environment Admin privileges creates a new environment, that application is given Identity Data Admin and Client Application developer role assignments for the new environment. Only the worker application can perform Identity Data Admin operations in that environment (see the list of Identity Data Admin actions above). However, the worker application can give the same role assignment to another user or worker application.

Control access to applications through roles and groups

The applications data model includes optional accessControl properties that, when set, specify the conditions that must be met by an authenticating actor to access the application. The application properties that control application access are:

  • accessControl.role.type

    This property specifies that an administrator role is required to access the application. When set, the only option for this property is ADMIN_USERS_ONLY, which means that the actor must be assigned at least one or more of the following administrator roles: Organization Admin, Environment Admin, Identity Data Admin, or Client Application Developer. For more information about roles, see Roles. If this property is not set, access to the application is not restricted by administrator roles.

  • accessControl.group.type

    This property specifies that the actor must be associated with a particular group (or groups) to access the application. When set, this property can be set to ANY_GROUP, which means that the actor must be a member of at least one group specified in the accessControl.group.groups property. This property can also be set to ALL_GROUPS, which means that the actor must belong to all groups specified in the accessControl.group.groups property. If this property is not set, access to the application is not restricted by groups.

  • accessControl.group.groups

    This property specifies a list of one or more groups that control access to the application. If there is more than one group, then the actor must belong to at least one group (if ANY_GROUP is the value of accessControl.group.type) or all groups (if ALL_GROUPS is the value of accessControl.group.type). If this property is not set, access to the application is not restricted by groups.

Application access control for OpenID Connect applications

When accessControl properties are set for an application, the authenticating actor must meet the requirements specified in the application's accessControl properties to get a token.

To implement role-based application access control:

  1. Set the accessControl.role.type property value to ADMIN_USERS_ONLY.

  2. Ensure that the authenticating actor has at least one assigned administrator role.

If the actor has an assigned administrator role, a token is issued that allows access to the application.

To implement group-based application access control:

  1. Set the accessControl.group.type and accessControl.group.groups properties. (If you set one of the application's access control group properties, you must set the other.)

  2. Set the property value for the accessControl.group.type. The options are ANY_GROUP and ALL_GROUPS.

  3. Set the accessControl.group.groups property value to list the group IDs to which an actor must belong. For information about obtaining group IDs, see Groups.

If the actor belongs to at least one group (for the ANY_GROUP type), or all groups (for the ALL_GROUPS type), a token is issued that allows access to the application.

Application access control for SAML applications

When accessControl properties are set for a SAML application, the authenticating actor must meet the requirements specified in the application's accessControl properties to get an assertion. The steps to define the accessControl properties for role-based and group-based conditions are the same as for OIDC applications. If the authenticating actor meets the the application's access control conditions, an assertion is created. If the conditions are not met, a sign-on attempt returns an authorization failed error.

Sample Applications

You can use these sample applications available on Github to quickly start your custom PingOne project. All sample application project files on GitHub include a README.md file with detailed developer instructions on prerequisites, building and running the sample code, and any other information required to use the sample application successfully in your environment.

Javascript Java (Spring Boot) Python ASP.NET React
javascript springboot python asp react
  • OIDC Authentication
  • Required PingOne tools
  • Customer User Registration
  • Import Tools
  • Resource Owner and Authorization
  • Custom User Registration
  • SignIn
  • SignOut
  • Registration
  • Password Recovery
  • Custom User Sign-On (React)
JavaScript OIDC authentication sample (Required) PingOne Spring Boot tools

Java Spring Boot custom user registration sample

Java Spring Boot resource owner and authorization sample
Python custom user registration sample ASP.NET core sample React custom user sign-on experience

Additionally, the User Import Tool provides a quick and easy way to import users into your application instance from a CSV file.

PingOne Services

PingOne MFA

PingOne MFA is a cloud-based service that provides multi-factor authentication (MFA) for the customer use case, that protects an organization's network, applications, and data resources.

See Getting Started with PingOne MFA in the PingOne MFA Administration Guide, which demonstrates a basic flow of practical steps to getting started with PingOne MFA, accompanied with explanations.

The flow depicts typical interaction between admin and developer roles. There are some PingOne MFA tasks which can only be implemented using the admin UI, whereas for other tasks, there is also the option to apply some of these steps using the developer API. At each step that the API option is possible, it is noted together with a link to the relevant section in the developer API documentation.

PingOne Risk

PingOne Risk is a cloud-based service that provides a single access point for event-based risk evaluations. The Risk service can be used with Ping Identity's SaaS products such as PingOne and PingOne MFA as well as with on-premise software products such as PingFederate.

See Getting Started with PingOne Risk in the PingOne Risk Administration Guide, which demonstrates a basic flow of practical steps to getting started with PingOne Risk, accompanied with explanations.

The flow depicts typical interaction between admin and developer roles. There are some PingOne Risk tasks which can only be implemented using the admin UI, whereas for other tasks, there is also the option to apply some of these steps using the developer API. At each step that the API option is possible, it is noted together with a link to the relevant section in the developer API documentation.

PingOne Verify

PingOne Verify enables secure user verification based on a government-issued document and live face capture (a selfie). The user ID information is captured on a user's iOS or Android device using the customer-created Verify app, and sent to the PingOne ID Verification service. The PingOne ID Verification service interacts with a service provider or providers that verify the submitted user ID information. When a user's ID information is successfully verified, the PingOne ID Verification service approves the user authentication and sends the ID verification status to the customer Verify app on a user's device.

Only the ID verification status is retained by PingOne. Any personally identifiable information (PII data) passed to PingOne is deleted by the ID Verification service.

To set up and configure PingOne Verify, you'll use:

  • The PingFederate admin console to configure the PingOne Verify Integration Kit.
  • The PingOne Verify Native SDKs.
  • The PingOne admin console or the PingOne Verify REST APIs.

See PingOne Verify transactions flow and Getting started with PingOne Verify in the PingOne Verify Administration Guide.

Reference

The following section provides reference information about the PingOne platform. Topics include:

Conventions

PingOne API requests

Public endpoints

The public endpoint for calling PingOne API services for environments in the North America region is api.pingone.com, the public endpoint for environments in the Canada region is api.pingone.ca, the public endpoint for environments in the European Union region is api.pingone.eu, and the public endpoint for environments in the Asia-Pacific region is api.pingone.asia.

Authorization

To make a call to the PingOne API, you'll need an OAuth 2.0 access token for API authentication. The access token (a JSON Web Token) is accepted per RFC 6750 most commonly through the Authorization HTTP request header. In the code samples in this document, the access token is expressed in the request header as Authorization: Bearer jwtToken. For more information about using access tokens, see Getting started.

HTTP methods

The PingOne API supports the following HTTP methods. Note that a resource may not support all listed methods below. When a method is not supported, the platform returns a 405 METHOD NOT ALLOWED error in the response.

  • POST

    Creates a new resource in the collection. If a specific resource is identified, it performs an operation on that resource.

  • PUT

    Updates a resource in the collection. If a specific resource is identified, it updates all attribute values of the resource.

  • PATCH

    Updates the attributes on an object or a partial update for the specified attributes.

  • GET

    Lists or queries a collection of resources. If a specific resource is identified, it returns the attribute values for the specific resource.

  • DELETE

    Deletes or unlinks a resource from the collection.

A resource supports updating either by replacing the resource (PUT) or partially updating the resource (PATCH).

Replacing a resource

A PUT request is a replace operation. Requests submitted using PUT will replace attribute values specified in the request and clear any attribute values that aren't specified.

A null value is represented in a resource by omitting the property, although you can specify null to explicitly clear the value.

Partial updates to a resource

A PATCH operation performs partial updates of a resource. The body of a PATCH operation is similar to that of a PUT operation. However, omitting an attribute in a PATCH operation results in the attribute being ignored.

You can use a value of null to explicitly clear the value.

Supported data exchange formats

The PingOne API supports JSON as the data exchange format with UTF-8 character encoding required for request body content. For PUT, POST, and PATCH operations, the Content-type request header identifies the format of the request body. A request header value of application/json specifies the data exchange format as JSON, which, by default, sets the character encoding to UTF-8. Here is a sample:

curl -vX PUT "https://api.pingone.com/v1/environments/{id}/populations/{id}" \
-H "Content-type: application/json" \
-H "Authorization: Bearer jwtToken" \
-d "{
  "name" : "Finance",
  "description" : "Finance and accounting group"
}"

UUIDs for resource identification

Resources in PingOne are identified by their associated UUID (universally unique identifier). API requests use UUIDs in the request URL to specify the resources involved in the operation. For clarity, the code samples in this API Reference use descriptive variables such as {environmentId}, {userId}, {applicationId}, and {deviceId} to represent the UUIDs assigned to PingOne resources.

For example, the following sample request URL specifies a unique device associated with a unique user in a unique environment. The resource ID variables represent specific UUIDs for PingOne resources.

curl -X "GET" "https://api.pingone.com/v1/environments/{environmentId}/users/{userId}/devices/{deviceId}"

The actual request URL with UUIDs looks like this:

curl -X "GET" "https://api.pingone.com/v1/environments/88c23def-39c9-4646-8d41-aa91a14a1006/users/8ce55f02-2077-4493-9a6d-0385df1f0772/devices/4ca9eb79-be29-4a1f-9a23-b29d58606e18"

There are a few exceptions to this convention. Notifications template names in PingOne are identified by the template name {templateName} rather than by a UUID. For example, the following request URL returns information about a specific template:

curl -X "GET" "https://api.pingone.com/v1/environments/000c2764-3489-4d34-a707-b23dd488049c/templates/{templateName}

The {templateName} variable is replaced by one of the pre-defined notifications template names in PingOne. The actual request URL that uses a defined notifications template called strong_authentication looks like this:

curl -X "GET" "https://api.pingone.com/v1/environments/000c2764-3489-4d34-a707-b23dd488049c/templates/strong_authentication

Placeholder syntax

Some requests use placeholder syntax to reference platform resource entities as variables. When placeholder syntax is required, the PingOne resource used as a variable is expressed in placeholder syntax format as ${attribute}. For example, when mapping a SAML name attribute to the PingOne username attribute, the value of the PingOne attribute in the POST request body is expressed as ${user.username}. In most cases where placeholder syntax is required, the placeholder references attributes in the PingOne user schema. The variable is written as a path to the value: ${user.​path.​to.​value}. For example, to reference the name.family user attribute, the variable is written as ${user.​name.​family}.

Placeholder syntax is also used to express sign-on policy condition variables. For example, a condition variable to specify the last completed time the password authenticator was used for sign on is expressed as ${session.​lastSignOn.​withAuthenticator.​pwd.​at}.

Placeholders in sign-on policy conditions often specify a value or range of values to meet the sign-on condition. For example, the sign-on policy associated with the following condition prevents sign-on from devices that contain the remote IP address value specified by the variable ${flow.request.http.remoteIp} in the specified IP address ranges.

"condition": {
   "not": {
        "ipRange": [
            "10.1.1.1/8",
            "10.0.0.0/8"
        ],
        "contains": "${flow.request.http.remoteIp}"
    }
}

Placeholders are also used to specify external identity provider attributes. For example, to specify a Facebook attribute that is mapped to a PingOne attribute, the Facebook attribute is expressed as ${providerAttributes.<Facebook attribute name>}. For example, the following expression maps the PingOne username attribute to the Facebook email attribute.

{
    "name": "username",
    "value": "${providerAttributes.email}"
    "update": "EMPTY_ONLY",
}

The following table shows the PingOne resources that use Placeholder syntax in POST requests.

PingOn resource Placeholder example
Sign-on policy actions ${session.​lastSignOn.​at}
${session.​lastSignOn.​withAuthenticator.​pwd.​at}
${session.​lastSignOn.​withAuthenticator.​mfa.​at}
${flow.​request.​http.​remoteIp}
${user.​*}
Identity providers ${providerAttributes.<IdP attribute name>}
Notifications templates ${user.username}
${otp}
Resource attributes ${user.email}
SAML attribute mapping ${user.id}
Link expansion

You can optimize the information returned by a request through link expansion. Link expansion is helpful when you need the query to return detailed information from an additional resource in the response data. You can identify a resource to expand using the expand query string parameter in the request.

Here is a sample that requests data for a specific user and expands the passwordPolicy attribute to show the password policy's attribute data.

curl -X GET "https://api.pingone.com/v1/environments/{environmentId}/users/{userId}/password?expand=passwordPolicy" \
-H "Authorization: Bearer jwtToken"  

When using the expand parameter in the request, the returned JSON includes an embedded passwordPolicy resource to show the details of the password policy associated with this user:

{
    "_links": {
        "self": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613/password"
        },
        "environment": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
        },
        "user": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613"
        },
        "passwordPolicy": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/passwordPolicies/9ad15e9e-3ac6-43f7-86d3-01018f6ef0ad"
        },
        "password.check": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613/password"
        },
        "password.reset": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613/password"
        },
        "password.set": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613/password"
        },
        "password.recover": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/b94f4977-0d52-4c9d-a5da-e7d42a82f613/password"
        }
    },
    "environment": {
        "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    },
    "user": {
        "id": "b94f4977-0d52-4c9d-a5da-e7d42a82f613"
    },
    "passwordPolicy": {
        "id": "9ad15e9e-3ac6-43f7-86d3-01018f6ef0ad"
    },
    "status": "NO_PASSWORD",
    "lastChangedAt": "2019-05-21T18:01:07.413Z",
    "_embedded": {
        "passwordPolicy": {
            "_links": {
                "self": {
                    "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/passwordPolicies/9ad15e9e-3ac6-43f7-86d3-01018f6ef0ad"
                },
                "environment": {
                    "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
                }
            },
            "id": "9ad15e9e-3ac6-43f7-86d3-01018f6ef0ad",
            "environment": {
                "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
            },
            "name": "Standard",
            "description": "A standard policy that incorporates industry best practices",
            "excludesProfileData": true,
            "notSimilarToCurrent": true,
            "excludesCommonlyUsed": true,
            "maxAgeDays": 182,
            "minAgeDays": 1,
            "maxRepeatedCharacters": 2,
            "minUniqueCharacters": 5,
            "history": {
                "count": 6,
                "retentionDays": 365
            },
            "lockout": {
                "failureCount": 5,
                "durationSeconds": 900
            },
            "length": {
                "min": 8,
                "max": 255
            },
            "minCharacters": {
                "1234567890": 1,
                "abcdefghijklmnopqrstuvwxyz": 1,
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ": 1,
                "~!@#$%^&*()-_=+[]{}|;:,.<>/?": 1
            },
            "default": true
        }
    }
}

Cross-origin resource sharing

PingOne supports cross-origin resource sharing (CORS), which gives applications running at different domains permission to access resources on PingOne servers. For example, an application at https://myapp.com that uses PingOne to authenticate users needs to request permission to access resources at https://auth.pingone.com before authentication operations are executed. In this case, a request is made to the resource owner (auth.pingone.com) from the requestor (myapp.com) using CORS headers to ask for access privileges. The response from auth.pingone.com returns the CORS Access-Control-Allow-Origin header with a value that confirms the requestor's access rights.

PingOne servers are configured to trust all origins. Consequently, when defining an application's connection to PingOne, you do not need to add your application's domain to a list of trusted origins. Cross-origin requests that use HTTP methods to modify the resource, such as PUT, PATCH, POST, and DELETE, trigger a preflight request to ensure that the initial request can be sent. The browser initiates a preflight HTTP OPTIONS request to verify that the HTTP method used in the actual request is allowed. In these cases, the response from auth.pingone.com to the preflight request returns a response with the CORS Access-Control-Allow-Methods header to specify the allowed methods.

Forced type conversion of floating point numbers in requests

PingOne truncates a float value submitted in the JSON request body to a matching int value for services other than flow orchestration. For example, in the following request body JSON, the minAgeDays value can be submitted with a value of 1.5.

{
  "name": "Standard",
  "description": "A standard policy that incorporates industry best practices",
  "excludesProfileData": true,
  "notSimilarToCurrent": true,
  "excludesCommonlyUsed": true,
  "maxAgeDays": 182,
  "minAgeDays": 1.5,
  "maxRepeatedCharacters": 2,
  "minUniqueCharacters": 5,
  "history": {
    "count": 6,
    "retentionDays": 365
  },
  "lockout": {
    "failureCount": 5,
    "durationSeconds": 900
  },
  "length": {
    "min": 8,
    "max": 255
  },
  "minCharacters": {
    "~!@#$%^&*()-_=+[]{}|;:,.<>/?": 1,
    "0123456789": 1,
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ": 1,
    "abcdefghijklmnopqrstuvwxyz": 1
  },
  "default": true
}

The request will execute. However, the response shows that the minAgeDays value is converted automatically to an int value:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/passwordPolicies/ad53ea0b-28b3-413f-a762-46eaf929ab78"
    },
    "environment": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    }
  },
  "id": "ad53ea0b-28b3-413f-a762-46eaf929ab78",
  "environment": {
    "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
  },
  "name": "Standard",
  "description": "A standard policy that incorporates industry best practices",
  "excludesProfileData": true,
  "notSimilarToCurrent": true,
  "excludesCommonlyUsed": true,
  "maxAgeDays": 182,
  "minAgeDays": 1,
  "maxRepeatedCharacters": 2,
  "minUniqueCharacters": 5,
  "history": {
    "count": 6,
    "retentionDays": 365
  },
  "lockout": {
    "failureCount": 5,
    "durationSeconds": 900
  },
  "length": {
    "min": 8,
    "max": 255
  },
  "minCharacters": {
    "~!@#$%^&*()-_=+[]{}|;:,.<>/?": 1,
    "0123456789": 1,
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ": 1,
    "abcdefghijklmnopqrstuvwxyz": 1
  },
  "default": true
}

Note that the value of the floating point number is not rounded. It is trimmed by removing the decimal portion of the value.

For flow orchestration services such as sign-on policy actions, float values submitted in the JSON request body generate an INVALID_VALUE error. For example, the following request body with a priority attribute value of 1.5 generates an error:

{
    "priority": 1.5,
    "type": "MULTI_FACTOR_AUTHENTICATION",
    "recovery": {
    	"enabled": false
    },
    "sms": {
        "enabled": true
    },
    "voice": {
        "enabled": true
    },
    "email": {
        "enabled": true
    },
    "applications": [
        {
            "id": "5e81bba1-1234-457c-926a-aae0e9876543",
            "autoEnrollment":{"enabled":true}
        }
    ]
}

The response error looks like this:

{
  "id": "15051F81-2500-4BBB-BE4A-0AF31DD50205",
  "code": "INVALID_REQUEST",
  "message": "The request could not be completed. The request was malformed or invalid.",
  "details": [
    {
      "code": "INVALID_VALUE",
      "target": "priority",
      "message": "Invalid value for attribute."
    }
  ]
}

PingOne API responses

HTTP response headers

The PingOne API includes information about the result of the operation in the HTTP headers. This enables you to determine the appropriate action to take without having to parse the response body.

The following HTTP Headers are returned by every operation:

  • Access-Control-Allow-Headers

    Used in response to a cross-origin resource sharing (CORS) preflight request to indicate the HTTP headers that can be used when making a request.

  • Access-Control-Allow-Max-Age

    Specifies how long the results of a CORS preflight request can be cached.

  • Access-Control-Allow-Methods

    Specifies the method or methods allowed when accessing the resource in response to a CORS preflight request.

  • Cache-Control

    Specifies directives for caching mechanisms in both requests and responses.

  • Content-Type

    Specifies the data exchange format for the response data.

  • Correlation-Id

    A custom header.

  • Date

    Shows the date the response was sent.

  • Expires

    Shows the date and time when the response expires.

  • Pragma

    Used for backwards compatibility with HTTP/1.0 caches in which the Cache-Control HTTP/1.1 header is not yet present.

  • Strict-Transport-Security

    Allows a web site to tell browsers that the site should only be accessed using HTTPS, instead of HTTP.

  • Transfer-Encoding

    Specifies the form of encoding used to safely transfer the entity to the user.

  • Vary

    Determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server. It is used by the server to indicate which headers it used when selecting a representation of a resource in a content negotiation algorithm.

  • Via

    Used for tracking message forwards, avoiding request loops, and identifying the protocol capabilities of senders along the request/response chain.

  • X-Content-Type-Options

    A marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed.

  • X-Frame-Options

    This denies rendering in a frame where there is a frame mismatch.

  • X-XSS-Protection

    A feature of Internet Explorer, Chrome, and Safari that stops pages from loading when the browsers detect reflected cross-site scripting (XSS) attacks.

HTTP response codes

The PingOne API returns the status of an operation as a registered HTTP response code. The HTTP response codes can be summarized as:

  • 200-299

    Confirms a successful call.

  • 300-399

    Indicates that the call or subsequent calls should be made to another resource.

  • 400-499

    Shows that an exception occurred, generally due to client code, insufficient permissions, or incorrect parameters.

  • 500-599

    Shows that an error occurred, generally due to an issue with the service (for example, a service outage).

Operations can also return additional information about a failed operation in the HTTP response body.

Synchronous responses

Responses for synchronous operations have the following behavior:

  • GET operations

    A request that returns a body also returns the code 200 OK with the resource in the body of the response.

  • POST operations

    A request that creates a new resource returns 201 CREATED with a Location header containing the location of the created resource.

  • PUT or PATCH operations

    A request that updates a resource returns 200 OK and the full resource in the body.

  • DELETE operations

    A request that deletes a resource returns 204 NO CONTENT.

Asynchronous responses

The PingOne API can create a long-running or asynchronous operation that can be monitored by a client. An asynchronous operation will have the following behavior:

  • POST operations

    Responses include 202 ACCEPTED with a Location header containing the location of the newly created operation. The client can poll the provided location to check the status of the operation. The operation may also return a suggested number of seconds for the client to recheck the status using the Retry-After HTTP header.

  • Canceling long-running operations

    Some resources may allow the client to cancel an operation by performing a DELETE request on the created resource.

  • Clean up

    The PingOne API will clean up operation history according to the application requirements (such as, keep the last n results, or purge results after the client has verified its success).

Response data structure

HAL (Hypertext Application Language) is a formatting convention that provides hyperlinks to related resources returned by an API request. For example, a GET /environments/{environmentId}/users/{usersId} request returns data for a specific user resource. The _links object in the JSON response data shows the hyperlinks to related resources associated with this user. You can use the roleAssignments link to get role assignments associated with this user, or the password.reset link to perform password management actions on this user resource.

{
    "_links": {
        "self": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab"
        },
        "environment": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
        },
        "population": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/populations/60971d3b-cc5a-4601-9c44-2be541f91bf1"
        },
        "devices": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/devices"
        },
        "roleAssignments": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/roleAssignments"
        },
        "password": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/password"
        },
        "password.reset": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/password"
        },
        "password.set": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/password"
        },
        "password.check": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/password"
        },
        "password.recover": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/password"
        },
        "linkedAccounts": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab/linkedAccounts"
        },
        "account.sendVerificationCode": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/users/8376797d-641c-4e7b-8bc1-2fdf71916cab"
        }
    },
    "_embedded": {
        "password": {
            "status": "PASSWORD_EXPIRED"
        },
        "population": {
            "_links": {
                "self": {
                    "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/populations/60971d3b-cc5a-4601-9c44-2be541f91bf1"
                },
                "environment": {
                    "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
                }
            },
            "id": "60971d3b-cc5a-4601-9c44-2be541f91bf1"
        }
    },
    "id": "8376797d-641c-4e7b-8bc1-2fdf71916cab",
    "environment": {
        "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    },
    "createdAt": "2020-02-18T20:50:14.092Z",
    "email": "tomjones@example.com",
    "enabled": true,
    "lifecycle": {
        "status": "ACCOUNT_OK"
    },
    "mfaEnabled": false,
    "name": {
        "given": "Tom",
        "family": "Jones"
    },
    "population": {
        "id": "60971d3b-cc5a-4601-9c44-2be541f91bf1"
    },
    "updatedAt": "2020-02-18T20:50:14.092Z",
    "username": "tomjones"
}

In addition, the _embedded resources returned by the request can be used as a navigation option to explore related resources. For example, population is returned as an _embedded resource in the response, and you can use the embedded resource's self HAL link to initiate a GET /environments/{environmentId}/populations/{populationId} request to return data about the population associated with this user.

Relationships, links, and references

Relationships between resources or operations can be described as follows:

  • Relationships (one-to-one)

    Where a resource is directly related to another resource (such as employee to manager, user to population, logo to brand), the relationship is generally represented by an attribute as a first-class citizen of the resource. For example:

    • _links object : Contains an href to the actual resource.

    • Payload : Contains the reference as an attribute with the ID. The name of the _links attribute and the attribute in the payload must be the same).

    • Expandable : Yes.

  • Relationships (one-to-many or many-to-one)

    Where a resource or resources may be related to a collection or to many resources. For example, a user to group membership:

    • _links object : Contains an href to the actual resource or collection.

    • Payload : May contain the reference as an attribute with the ID. The name of the _links attribute and the attribute in the payload must be the same).

    • Expandable : No.

  • Informal relationships and links

    Provides navigation and self-discovery of the API and its related resources (such as next page of search results, next authentication service to invoke, or with which environment the resource is associated). For example:

    • _links object : Contains an href to the actual resource, collection, or URL.

    • Payload : Cannot contain the reference as an attribute.

    • Expandable : No.

These relationships and references are represented as follows:

  • Links are represented using JSON HAL conventions (such as in a _links object).

  • Links are represented as absolute URLs.

  • Links can be expanded using the expand parameter. The links can also be referenced using the "property-as-resource" pattern.

  • References as attributes have an id value and can also have additional attributes (such as displayName).

Errors

Errors generated by the PingOne API allow you to resolve specific errors programmatically. An error response consists of a high-level error code that must be handled by the client and optional details containing specific information on how to resolve the fault. The PingOne API errors return a response payload formatted as follows:

Attribute Required Description
id Yes A unique identifier that is stored in log files and always included in an error response. This value can be used to track the error received by the client, with server-side activity included for troubleshooting purposes.
code Yes A general fault code which the client must handle to provide all exception handling routines and to localize messages for users. This code is common across all PingOne services and is human readable (such as a defined constant rather than a number).
message Yes A short description of the error. This message is intended to assist with debugging and is returned in English only.
target No The item that caused the error (such as a form field ID or an attribute inside a JSON object).
details No Additional details about the error. Optional information to help resolve the error and to display to users.
innererror No Additional details to help the client developer resolve the fault (primarily for UI validation reasons). The following attributes can be used in the innererror object:
  • rangeMinimumValue. Errors that failed due to range violation. This attribute represents the minimum value of the range.
  • rangeMaximumValue. The maximum range or value of an attribute.
  • allowedPattern. A regex pattern describing an acceptable input pattern.
  • allowedValues. A list describing acceptable values.
  • maximumValue. The maximum value allowed for the request.

A top-level error message looks like this:


HTTP/1.1 400 BAD REQUEST
{
  "id" : "6c796712-0f16-4062-815a-e0a92f4a2143",
  "code" : "INVALID_DATA",
  "message" : "The request could not be completed. One or more validation errors were in the request.”
}


A detail-level error message provides more information about the error. Specific codes at the detail level can be introduced by each service to reflect the actions in that service. A detail-level error message looks like this:

HTTP/1.1 400 BAD REQUEST
{
  "id" : "6c796712-0f16-4062-815a-e0a92f4a2143",
  "code" : "INVALID_DATA",
  "message" : "The request could not be completed. One or more validation errors were in the request.",
  "details" : [
  {
    "code" : "REQUIRED_VALUE",
    "target" : "username",
    "message" : "Username is required and cannot be empty."
  },
  {
    "code" : "INVALID_VALUE",
    "target" : "employeeType",
    "message" : "Invalid value for employee type."
    "innerError" : {
      "allowedValues" : [ "EMPLOYEE", "CONTRACTOR" ]
    }
  }
}

Caching

The PingOne API generally implements HTTP caching of operation responses. When HTTP caching is implemented, the following HTTP response headers are included:

  • ETag

    An arbitrary string for the version of a representation. This includes the media type in the hash value. For example: ETag: "686897696a7c876b7e".

  • Date

    The date and time the response was returned. For example: Date: Sun, 06 Nov 1994 08:49:37 GMT.

  • Cache-Control

    The maximum number of seconds a response can be cached. If caching is not supported for the response, the value is no-cache. For example: Cache-Control: 360 or Cache-Control: no-cache.

  • Expires

    If Cache-Control is supplied, this header contains the timestamp for when the response expires. If caching is not supported for the response, this header is not present. For example: Expires: Sun, 06 Nov 1994 08:49:37 GMT.

  • Pragma

    When the Cache-Control value is no-cache, this header is also set to no-cache. If caching is not supported for the response, this header is not present. For example: Pragma: no-cache.

  • Last-Modified

    The timestamp for when the resource itself was last modified. For example: Last-Modified: Sun, 06 Nov 1994 08:49:37 GMT.

  • Varies

    This header is included for user-specific headers (such as Authorization) in multi-tenant scenarios.

Paging, ordering, and filtering collections

Pagination

PingOne supports cursor-based pagination to return large collections in consumable pages. When an operation supports pagination, the following conventions are used:

  • Page limits

    Page limits are requested using the limit query string. If the limit parameter value is omitted, the operation returns the lesser of the service-defined maximum page size or the number of items in the collection.

  • Self, next, and previous links

    The response body includes a self link in the _links object. If there are more pages available, the response includes a next link in the _links object. If there are previous pages of results available, the response includes a prev link in the _links object.

  • Multiple pages

    If there is more than one page, the response returns a URL-safe cursor in the cursor query string parameter for the next or prev links.

  • Response metadata

    The response can include the following metadata about the results in the body of the payload:

    • count (optional).

      Describes the number of items in the collection or result set (such as the total item count). If a response does not return a count attribute, this usually means there are many in the result set.

    • size (optional).

      Describes the size of the page of results (such as the limit or service-defined maximum page size).

Here is a sample request that limits the collection returned to a maximum of 2.

GET /environments/{id}/populations?limit=2 HTTP/1.1

Here is the response body.

{
 "_links" : {
  "self" : { "href" : "https://api.pingone.com/v1/environments/{id}}/populations?limit=2" },
  "next" : { "href" : "https://api.pingone.com/v1/environments/{id}}/populations?cursor=xygdhs&limit=2" }
 },
 "count" : 50,
 "size" : 2,
 "_embedded" : {
  "populations" [
   {
    "name" : "Accounting",
    "id" : "12345-aaa-12345"
   },
   {
    "name" : "Engineering",
    "id" : "12345-aaa-12346"
   }
  ]
 }
}

Ordering collections

The PingOne API supports ordering collection results. The following conventions are used:

  • order query string

    The order query string parameter specifies the attribute used to order the results. To return a collection in descending order, prefix the attribute with a minus sign ("-"). Here is a sample of ordering on the startDate attribute in descending order:

    https://api.pingone.com/v1/environments/{environmentID}/activeIdentityCounts?filter=startDate ge "2019-05-01T19:00:00Z" and samplingPeriod eq "10"&limit=10ℴ=-startDate
    
  • Multiple column ordering

    An operation can support ordering multiple columns in the order parameter by separating the columns with a comma. If an operation supports multiple columns, it treats the comma as a "THEN BY" directive. For example, order=dateTime,name indicates that the collection is sorted by dateTime then by name.

Filtering collections

Requests that return a large number of items can be filtered using the filter query string parameter. The PingOne platform supports the SCIM protocol filtering operators listed in the following table. However, a particular operation may not support all SCIM filtering operators. If a filtering operator is not supported, the operation returns 400 REQUEST_FAILED code in the response. The details section of the message returns an INVALID_FILTER code as the cause of the error.

Operator Description Behavior
eq equal The attribute and operator values are identical.
ne not equal The attribute and operator values must not be identical for a match.
co contains The entire operator value must be a substring of the attribute value for a match.
sw starts with The entire operator value must be a substring of the attribute value, starting at the beginning of the attribute value. This criterion is satisfied if the two strings are identical.
ew ends with The entire operator value must be a substring of the attribute value, matching at the end of the attribute value. This criterion is satisfied if the two strings are identical.
pr present (has value) If the attribute has a non-empty or non-null value, or if it contains a non-empty node for complex attributes, there is a match.
gt greater than If the attribute value is greater than the operator value, there is a match. The actual comparison is dependent on the attribute type. For string attribute types, this is a lexicographical comparison, and for DateTime types, it is a chronological comparison. For integer attributes, it is a comparison by numeric value.
ge greater than or equal to If the attribute value is greater than or equal to the operator value, there is a match. The actual comparison is dependent on the attribute type. For string attribute types, this is a lexicographical comparison, and for DateTime types, it is a chronological comparison. For integer attributes, it is a comparison by numeric value.
lt less than If the attribute value is less than the operator value, there is a match. The actual comparison is dependent on the attribute type. For string attribute types, this is a lexicographical comparison, and for DateTime types, it is a chronological comparison. For integer attributes, it is a comparison by numeric value.
le less than or equal to If the attribute value is less than or equal to the operator value, there is a match. The actual comparison is dependent on the attribute type. For string attribute types, this is a lexicographical comparison, and for DateTime types, it is a chronological comparison. For integer attributes, it is a comparison by numeric value.

For example, here is a sample SCIM filtering expression that returns users with a last name of "Smith" and a phone number that starts with the "512" area code:

https://api.pingone.com/v1/environments/{envID}/users?filter=name.family eq "Smith" and mobilePhone sw "512"

Here is the same filter with URL-encoding to account for spaces (%20) and quotation marks (%22):

https://api.pingone.com/v1/environments/{envID}/users?filter=name.family%20eq%20%22Smith%22%20and%20mobilePhone%20sw%20%22512%22

For more information about the SCIM Protocol Specification, see "Section 3.4.2.2. Filtering," in the SCIM Protocol Specification.

Generating a CSR for custom domains

If you use a custom domain, you need to create the custom domain resource in PingOne and import the SSL certificate used by the custom domain resource. In brief, the steps in PingOne to implement a custom domain are:

  1. Create the custom domain resource (for example, auth.acme.com).

  2. Create a CNAME record in the acme.com DNS for auth.acme.com that points to the canonical name when the custom domain was created.

  3. If you do not have an SSL certificate, outside of PingOne, generate a certificate for auth.acme.com (a certificated request that is signed by a certificate authority), which results in a private key, certificate chain, and certificate.

  4. Import the SSL certificate (chain, cert, private key).

Generate an SSL certificate

If you do not have an SSL certificate, which is referenced in step 3, follow these steps to create the trusted SSL certificate for the custom domain:

  1. Open (or install) openssl on your computer.

  2. Enter the following openssl command:

    openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr

  3. Enter the following certificate signing request (CSR) information at the prompt:

    • Common Name (CN)
    • Organization
    • Organization Unit (OU)
    • City (or Locality)
    • State (or Province)
    • Country
  4. Submit your CSR to a Certificate Authority (CA) for validation.

After validation, the CA returns the trusted SSL certificate, which you can import to complete and enable the custom domain. For information about custom domains, see Custom Domains.

Create a login_hint_token JWT

A login_hint_token is a JWT that provides a way for the client to identify and authenticate the end-user without needing to encode the entire authentication request in a signed JWT. The following information describes the OIDC parameters and the steps for generating and signing the token.

Prerequisites
  1. Install a JWT token generator such as jwtgen globally using npm install -g jwtgen. This action requires npm.

  2. Retrieve the environment id property value associated with your worker application and user.

  3. Retrieve the clientId and clientSecret property values for the worker application.

  4. Retrieve the user ID id or username property value for whom this token will be associated.

Generate a signed token

The command to generate the login_hint_token JWT takes the following parameters:

Parameter Description
-a Specifies the JWT signing algorithm. Options are HS256.
-s Specifies the signing key, which is the application's clientSecret property value.
-e Specifies the expiration date, expressed as the number of seconds from the time of creation. The typical value is 3600 seconds.
--claims Specifies the claims required by the token:
  • iss: A string that specifies the application ID of the issuer creating the token
  • sub: A string that specifies the identifier for the authenticated user (for example, the id or username property value).
  • iat: An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token was originally issued.
  • exp: An integer that specifies the timestamp, measured in the number of seconds since January 1, 1970, UTC, indicating when this token will expire.
  • aud: A string that specifies the intended audience for this token.
  1. Run the jwtgen command.
jwtgen -a "HS256" -s "YOUR_CLIENT_SECRET" -e 3600 --claims '{
"iss":"YOUR_CLIENT_ID",
"sub":"YOUR_USER_ID_OR_USERNAME",
"iat":1300819380,
"exp":1300819391,
"aud":"https://auth.pingone.com/YOUR_ENVIRONMENT_ID/as"
}'
  1. Record the token returned successfully by the command to use as the value of the login_hint_token property in the authorize request.

Create a request property JWT

A request property JWT enables OIDC/OAuth2 request parameters to be passed as a single, self-contained parameter. Using a JWT enables integrity protection of parameters that are required for risk-based authentication or privacy and consent use cases.

This sample shows the information required in a transaction approval JWT:

"jwtHeader": {
  "alg": "HS256",
  "typ": "JWT"
},
"jwtBody":
{
  "aud": "https://auth.pingone.com/{{envId}}/as",
  "iss": "{{appId}}",
  "pi.template": {
    "name": "transaction",
    "variant": "{{variantName}}",
    "variables": {
      "sum": "1,000,000",
      "currency": "USD",
      "recipient": "Charlie Parker"
    }
  },
  "pi.clientContext": {
    "alert.color": "red"
  }
}

The following information describes the OIDC parameters and the steps for generating and signing the token.

Prerequisites
  1. Install a JWT token generator such as jwtgen globally using npm install -g jwtgen. This action requires npm.

  2. Retrieve the environment id property value associated with your worker application and user.

  3. Retrieve the clientId and clientSecret property values for the worker application.

  4. Retrieve the name of the transaction notification template that you want to use.

Generate a signed token

The command to generate the request JWT takes the following parameters:

Parameter Description
-a Specifies the JWT signing algorithm. Options are HS256.
-s Specifies the signing key, which is the application's clientSecret property value.
--claims Specifies the claims required by the token:
  • iss: A string that specifies the application ID of the issuer creating the token
  • aud: A string that specifies the intended audience for this token.
  • pi.template: A string that specifies the template name and the variables required by the template.
  • pi.clientContext: A string that specifies the key-value pairs that define the client context.
  • pi.remoteIp: A string that specifies the user's IP address. This is an optional property used with authentication policies that include IP-based conditions.

The following command creates a JWT for the request property specified in the authorization request:

  1. Run the jwtgen command.
jwtgen -a "HS256" -s "<applicationSecret>" --claims '{
    "aud":"https://auth.pingone.com/{{envId}}/as",
    "iss":"{{appId}}",
    "pi.template":{"name":"transaction","variables":{"sum":"1,000,000","currency":"USD","recipient":"Charlie Parker"}},
    "pi.clientContext":{"alert.color":"red"}}' 
  1. Record the token returned successfully by the command to use as the value of the request property in the authorize request.

Migrate existing external agreement consents to PingOne

This topic provides guidance on how to load existing user agreement consents into PingOne. It assumes that your users and agreements are already loaded into PingOne. For information about creating and managing PingOne agreements, see Agreement Management. For information about creating and managing users, see Users.

In this topic, the following terms are used to describe the PingOne and external entities:

  • External user: A user record outside of PingOne.

  • External agreement: An agreement that exists outside of PingOne to which external users have provided consent.

  • External agreement consent: A user agreement consent record outside of PingOne.

  • PingOne user: The user in PingOne. You should have a way to correlate each external user to the corresponding PingOne user.

  • PingOne agreement: An agreement in PingOne. Each of your external agreements should have a corresponding PingOne agreement.

  • PingOne agreement consent: A user agreement consent record in PingOne.

Migrate external agreement consents

Follow these steps to load one existing external user agreement consent into PingOne:

Step 1: Get information from the external existing consent record

Extract the following information from your existing agreement consent record. You will need this information to complete Step 2:

  • userId

    The existing external consent should be associated with an external user. Correlate that external user to a PingOne user. The userId is that PingOne user's id.

  • agreementId

    The existing external agreement consent should be associated with an external agreement. Correlate that external agreement to a PingOne agreement. The agreementId is that PingOne agreement's id.

  • languageId

    The existing consent should be associated with a language. Correlate that to a PingOne agreement language. This is the PingOne agreement language languageId property value needed in the API request you will run in Step 2.

  • revisionId

    The most recent effective revision ID associated with the PingOne agreement language. This is the PingOne agreement revision revisionId property value needed in the API request you will run in Step 2.

  • consentedAt

    This can be either the external agreement consent time or the current time. If you want to make sure your users do not have to consent again, you might need to modify the PingOne agreement's reconsent period property.

Step 2: Create the user's PingOne agreement consent

To create the user's corresponding PingOne agreement consent, you can make requests to the following PingOne endpoint: POST /environments/{environmentId}/users/{userId}/agreementConsents/{agreementId}. You will need the information for the external agreement consent you collected in Step 1.

The POST /environments/{environmentId}/users/{userId}/agreementConsents/{agreementId} request uses a Content-Type header with a value of application/vnd.pingidentity.consent.accept+json to initiate the consent accept action.

The request body for this request requires the following properties:

{
	language: { id: "{languageId}" },
	revision: { id: "{revisionId}" },
	consentedAt: "{date}"
}

The languageId property value is the ID of the language resource associated with the agreement revision. The revisionId is the PingOne current active agreement revision ID.

For more information about the POST /environments/{environmentId}/users/{userId}/agreementConsents/{agreementConsentId} request, see Accept Agreement.

To load multiple existing external user agreement consents into PingOne, you can perform this operation over your existing external agreement consents and load each one at a time. Please ensure you account for API rate limits.